2011-06-26 10:25:42 +02:00
# include "extension.h"
# include "forwards.h"
2012-05-27 00:31:23 +02:00
# include "util_cstrike.h"
2011-06-26 10:25:42 +02:00
bool g_pTerminateRoundDetoured = false ;
bool g_pCSWeaponDropDetoured = false ;
bool g_pIgnoreTerminateDetour = false ;
bool g_pIgnoreCSWeaponDropDetour = false ;
bool g_PriceDetoured = false ;
bool g_HandleBuyDetoured = false ;
2017-08-21 16:28:59 +02:00
# if SOURCE_ENGINE != SE_CSGO
2011-06-26 10:25:42 +02:00
int lastclient = - 1 ;
2017-08-21 16:28:59 +02:00
# endif
2011-06-26 10:25:42 +02:00
IForward * g_pHandleBuyForward = NULL ;
IForward * g_pPriceForward = NULL ;
IForward * g_pTerminateRoundForward = NULL ;
IForward * g_pCSWeaponDropForward = NULL ;
CDetour * DHandleBuy = NULL ;
CDetour * DWeaponPrice = NULL ;
CDetour * DTerminateRound = NULL ;
CDetour * DCSWeaponDrop = NULL ;
int weaponNameOffset = - 1 ;
2013-01-23 20:46:12 +01:00
# if SOURCE_ENGINE == SE_CSGO
2020-12-18 13:10:10 +01:00
DETOUR_DECL_MEMBER4 ( DetourHandleBuy , int , int , iLoadoutSlot , void * , pWpnDataRef , bool , bRebuy , bool , bDrop )
2017-08-21 16:28:59 +02:00
{
2017-08-28 16:17:12 +02:00
CBaseEntity * pEntity = reinterpret_cast < CBaseEntity * > ( this ) ;
int client = gamehelpers - > EntityToBCompatRef ( pEntity ) ;
2017-08-21 16:28:59 +02:00
2017-08-28 16:17:12 +02:00
CEconItemView * pView = GetEconItemView ( pEntity , iLoadoutSlot ) ;
2017-08-21 16:28:59 +02:00
if ( ! pView )
{
2020-12-18 13:10:10 +01:00
return DETOUR_MEMBER_CALL ( DetourHandleBuy ) ( iLoadoutSlot , pWpnDataRef , bRebuy , bDrop ) ;
2017-08-21 16:28:59 +02:00
}
2017-08-28 16:17:12 +02:00
CCSWeaponData * pWpnData = GetCCSWeaponData ( pView ) ;
2017-08-21 16:28:59 +02:00
if ( ! pWpnData )
{
2020-12-18 13:10:10 +01:00
return DETOUR_MEMBER_CALL ( DetourHandleBuy ) ( iLoadoutSlot , pWpnDataRef , bRebuy , bDrop ) ;
2017-08-21 16:28:59 +02:00
}
const char * szClassname = * ( const char * * ) ( ( intptr_t ) pWpnData + weaponNameOffset ) ;
char weaponName [ 128 ] ;
if ( strstr ( szClassname , " knife " ) )
{
2017-08-21 16:35:58 +02:00
Q_strncpy ( weaponName , " knife " , sizeof ( weaponName ) ) ;
2017-08-21 16:28:59 +02:00
}
else
{
2017-09-04 01:31:23 +02:00
Q_strncpy ( weaponName , GetWeaponNameFromClassname ( szClassname ) , sizeof ( weaponName ) ) ;
2017-08-21 16:28:59 +02:00
}
cell_t result = Pl_Continue ;
g_pHandleBuyForward - > PushCell ( client ) ;
g_pHandleBuyForward - > PushString ( weaponName ) ;
g_pHandleBuyForward - > Execute ( & result ) ;
if ( result ! = Pl_Continue )
{
return 0 ;
}
int originalPrice = 0 ;
if ( g_iPriceOffset ! = - 1 )
{
originalPrice = * ( int * ) ( ( intptr_t ) pWpnData + g_iPriceOffset ) ;
int changedPrice = CallPriceForward ( client , weaponName , originalPrice ) ;
if ( originalPrice ! = changedPrice )
* ( int * ) ( ( intptr_t ) pWpnData + g_iPriceOffset ) = changedPrice ;
}
2020-12-18 13:10:10 +01:00
int ret = DETOUR_MEMBER_CALL ( DetourHandleBuy ) ( iLoadoutSlot , pWpnDataRef , bRebuy , bDrop ) ;
2017-08-21 16:28:59 +02:00
if ( g_iPriceOffset ! = - 1 )
* ( int * ) ( ( intptr_t ) pWpnData + g_iPriceOffset ) = originalPrice ;
return ret ;
}
2013-01-23 20:46:12 +01:00
# else
2011-06-26 10:25:42 +02:00
DETOUR_DECL_MEMBER1 ( DetourHandleBuy , int , const char * , weapon )
{
2011-06-29 02:16:05 +02:00
int client = gamehelpers - > EntityToBCompatRef ( reinterpret_cast < CBaseEntity * > ( this ) ) ;
2011-06-26 10:25:42 +02:00
lastclient = client ;
cell_t result = Pl_Continue ;
g_pHandleBuyForward - > PushCell ( client ) ;
g_pHandleBuyForward - > PushString ( weapon ) ;
g_pHandleBuyForward - > Execute ( & result ) ;
if ( result ! = Pl_Continue )
{
lastclient = - 1 ;
return 0 ;
}
2012-05-27 00:31:23 +02:00
2011-06-26 10:25:42 +02:00
int val = DETOUR_MEMBER_CALL ( DetourHandleBuy ) ( weapon ) ;
2017-08-21 16:28:59 +02:00
2011-06-26 10:25:42 +02:00
lastclient = - 1 ;
return val ;
}
2017-08-21 16:28:59 +02:00
# endif
2011-06-26 10:25:42 +02:00
2012-05-27 00:31:23 +02:00
# if SOURCE_ENGINE != SE_CSGO
2011-06-26 10:25:42 +02:00
DETOUR_DECL_MEMBER0 ( DetourWeaponPrice , int )
2013-08-15 20:40:30 +02:00
{
2015-01-31 18:44:18 +01:00
int price = DETOUR_MEMBER_CALL ( DetourWeaponPrice ) ( ) ;
if ( lastclient = = - 1 )
2013-08-15 20:40:30 +02:00
return price ;
const char * weapon_name = reinterpret_cast < char * > ( this + weaponNameOffset ) ;
return CallPriceForward ( lastclient , weapon_name , price ) ;
}
2017-08-21 16:28:59 +02:00
# endif
2011-06-26 10:25:42 +02:00
2018-10-05 13:22:29 +02:00
# if SOURCE_ENGINE == SE_CSS
2011-06-26 10:25:42 +02:00
DETOUR_DECL_MEMBER2 ( DetourTerminateRound , void , float , delay , int , reason )
{
if ( g_pIgnoreTerminateDetour )
{
g_pIgnoreTerminateDetour = false ;
DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( delay , reason ) ;
return ;
}
2018-10-05 13:22:29 +02:00
# elif SOURCE_ENGINE == SE_CSGO && !defined(WIN32)
2018-10-04 04:50:31 +02:00
DETOUR_DECL_MEMBER4 ( DetourTerminateRound , void , float , delay , int , reason , int , unknown , int , unknown2 )
{
if ( g_pIgnoreTerminateDetour )
{
g_pIgnoreTerminateDetour = false ;
DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( delay , reason , unknown , unknown2 ) ;
return ;
}
2014-02-09 02:04:12 +01:00
# else
//Windows CSGO
2016-02-18 17:15:39 +01:00
//char __userpurge TerminateRound(int a1@<ecx>, float a2@<xmm1>, int *a3)
2014-02-09 02:04:12 +01:00
// a1 - this
2016-02-18 17:15:39 +01:00
// a2 - delay
// a3 - reason
2018-10-04 04:50:31 +02:00
// a4 - unknown
// a5 - unknown
DETOUR_DECL_MEMBER3 ( DetourTerminateRound , void , int , reason , int , unknown , int , unknown2 )
2014-02-09 02:04:12 +01:00
{
float delay ;
if ( g_pIgnoreTerminateDetour )
{
g_pIgnoreTerminateDetour = false ;
2018-10-04 04:50:31 +02:00
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( reason , unknown , unknown2 ) ;
2014-02-09 02:04:12 +01:00
}
//Save the delay
__asm
{
movss delay , xmm1
}
# endif
2011-06-26 10:25:42 +02:00
float orgdelay = delay ;
int orgreason = reason ;
cell_t result = Pl_Continue ;
2015-09-17 01:21:58 +02:00
# if SOURCE_ENGINE == SE_CSGO
2015-09-17 01:03:40 +02:00
reason - - ;
2015-09-17 01:21:58 +02:00
# endif
2015-09-17 01:03:40 +02:00
2011-06-26 10:25:42 +02:00
g_pTerminateRoundForward - > PushFloatByRef ( & delay ) ;
g_pTerminateRoundForward - > PushCellByRef ( & reason ) ;
g_pTerminateRoundForward - > Execute ( & result ) ;
if ( result > = Pl_Handled )
return ;
2015-09-17 01:21:58 +02:00
# if SOURCE_ENGINE == SE_CSGO
2015-09-17 01:03:40 +02:00
reason + + ;
2015-09-17 01:21:58 +02:00
# endif
2015-09-17 01:03:40 +02:00
2018-10-05 13:22:29 +02:00
# if SOURCE_ENGINE == SE_CSS
2011-06-26 10:25:42 +02:00
if ( result = = Pl_Changed )
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( delay , reason ) ;
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( orgdelay , orgreason ) ;
2018-10-05 13:22:29 +02:00
# elif SOURCE_ENGINE == SE_CSGO && !defined(WIN32)
2018-10-04 04:50:31 +02:00
if ( result = = Pl_Changed )
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( delay , reason , unknown , unknown2 ) ;
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( orgdelay , orgreason , unknown , unknown2 ) ;
2014-02-09 02:04:12 +01:00
# else
if ( result = = Pl_Changed )
{
__asm
{
movss xmm1 , delay
}
2018-10-04 04:50:31 +02:00
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( reason , unknown , unknown2 ) ;
2014-02-09 02:04:12 +01:00
}
__asm
{
movss xmm1 , orgdelay
}
2018-10-04 04:50:31 +02:00
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( orgreason , unknown , unknown2 ) ;
2014-02-09 02:04:12 +01:00
# endif
2011-06-26 10:25:42 +02:00
}
2012-05-27 00:31:23 +02:00
2021-10-22 17:20:54 +02:00
# if SOURCE_ENGINE == SE_CSGO
DETOUR_DECL_MEMBER3 ( DetourCSWeaponDrop , void , CBaseEntity * , weapon , bool , bThrowForward , bool , bDonated )
# else
2021-10-23 05:42:45 +02:00
DETOUR_DECL_MEMBER3 ( DetourCSWeaponDrop , void , CBaseEntity * , weapon , bool , bDropShield , bool , bThrowForward )
2021-10-22 17:20:54 +02:00
# endif
2011-06-26 10:25:42 +02:00
{
if ( g_pIgnoreCSWeaponDropDetour )
{
g_pIgnoreCSWeaponDropDetour = false ;
2021-10-22 17:20:54 +02:00
# if SOURCE_ENGINE == SE_CSGO
DETOUR_MEMBER_CALL ( DetourCSWeaponDrop ) ( weapon , bThrowForward , bDonated ) ;
# else
2021-10-23 05:42:45 +02:00
DETOUR_MEMBER_CALL ( DetourCSWeaponDrop ) ( weapon , bDropShield , bThrowForward ) ;
2021-10-22 17:20:54 +02:00
# endif
2011-06-26 10:25:42 +02:00
return ;
}
2011-06-29 02:16:05 +02:00
int client = gamehelpers - > EntityToBCompatRef ( reinterpret_cast < CBaseEntity * > ( this ) ) ;
int weaponIndex = gamehelpers - > EntityToBCompatRef ( weapon ) ;
2011-06-26 10:25:42 +02:00
cell_t result = Pl_Continue ;
g_pCSWeaponDropForward - > PushCell ( client ) ;
g_pCSWeaponDropForward - > PushCell ( weaponIndex ) ;
2021-10-22 17:20:54 +02:00
# if SOURCE_ENGINE == SE_CSGO
g_pCSWeaponDropForward - > PushCell ( bDonated ) ;
# else
g_pCSWeaponDropForward - > PushCell ( false ) ;
# endif
2011-06-26 10:25:42 +02:00
g_pCSWeaponDropForward - > Execute ( & result ) ;
2015-03-28 00:54:42 +01:00
if ( result = = Pl_Continue )
2014-07-02 16:08:56 +02:00
{
2021-10-22 17:20:54 +02:00
# if SOURCE_ENGINE == SE_CSGO
DETOUR_MEMBER_CALL ( DetourCSWeaponDrop ) ( weapon , bThrowForward , bDonated ) ;
# else
2021-10-23 05:42:45 +02:00
DETOUR_MEMBER_CALL ( DetourCSWeaponDrop ) ( weapon , bDropShield , bThrowForward ) ;
2021-10-22 17:20:54 +02:00
# endif
2014-07-02 16:08:56 +02:00
}
2011-06-26 10:25:42 +02:00
return ;
}
2012-05-27 00:31:23 +02:00
2011-06-26 10:25:42 +02:00
bool CreateWeaponPriceDetour ( )
{
2017-08-21 16:28:59 +02:00
# if SOURCE_ENGINE != SE_CSGO
2011-06-26 10:25:42 +02:00
if ( weaponNameOffset = = - 1 )
{
if ( ! g_pGameConf - > GetOffset ( " WeaponName " , & weaponNameOffset ) )
{
smutils - > LogError ( myself , " Could not find WeaponName offset - Disabled OnGetWeaponPrice forward " ) ;
return false ;
}
}
2012-05-27 00:31:23 +02:00
2011-06-26 10:25:42 +02:00
DWeaponPrice = DETOUR_CREATE_MEMBER ( DetourWeaponPrice , " GetWeaponPrice " ) ;
if ( DWeaponPrice ! = NULL )
{
if ( ! CreateHandleBuyDetour ( ) )
{
g_pSM - > LogError ( myself , " GetWeaponPrice detour could not be initialized - HandleCommand_Buy_Internal failed to detour, disabled OnGetWeaponPrice forward. " ) ;
return false ;
}
DWeaponPrice - > EnableDetour ( ) ;
g_PriceDetoured = true ;
return true ;
}
2017-08-21 16:28:59 +02:00
# else
if ( g_iPriceOffset = = - 1 )
{
if ( ! g_pGameConf - > GetOffset ( " WeaponPrice " , & g_iPriceOffset ) )
{
smutils - > LogError ( myself , " Could not find WeaponPrice offset - Disabled OnGetWeaponPrice forward " ) ;
return false ;
}
}
2011-06-26 10:25:42 +02:00
2017-08-21 16:28:59 +02:00
if ( ! CreateHandleBuyDetour ( ) )
{
g_pSM - > LogError ( myself , " GetWeaponPrice detour could not be initialized - HandleCommand_Buy_Internal failed to detour, disabled OnGetWeaponPrice forward. " ) ;
return false ;
}
else
{
g_PriceDetoured = true ;
return true ;
}
# endif
2011-06-26 10:25:42 +02:00
g_pSM - > LogError ( myself , " GetWeaponPrice detour could not be initialized - Disabled OnGetWeaponPrice forward. " ) ;
return false ;
}
bool CreateTerminateRoundDetour ( )
{
DTerminateRound = DETOUR_CREATE_MEMBER ( DetourTerminateRound , " TerminateRound " ) ;
if ( DTerminateRound ! = NULL )
{
DTerminateRound - > EnableDetour ( ) ;
g_pTerminateRoundDetoured = true ;
return true ;
}
g_pSM - > LogError ( myself , " TerminateRound detour could not be initialized - Disabled OnTerminateRound forward " ) ;
return false ;
}
bool CreateHandleBuyDetour ( )
{
if ( g_HandleBuyDetoured )
return true ;
2017-08-21 16:28:59 +02:00
# if SOURCE_ENGINE == SE_CSGO
if ( weaponNameOffset = = - 1 )
{
if ( ! g_pGameConf - > GetOffset ( " WeaponName " , & weaponNameOffset ) )
{
smutils - > LogError ( myself , " Could not find WeaponName offset - Disabled OnBuyCommand forward " ) ;
return false ;
}
}
# endif
2011-06-26 10:25:42 +02:00
DHandleBuy = DETOUR_CREATE_MEMBER ( DetourHandleBuy , " HandleCommand_Buy_Internal " ) ;
if ( DHandleBuy ! = NULL )
{
DHandleBuy - > EnableDetour ( ) ;
g_HandleBuyDetoured = true ;
return true ;
}
g_pSM - > LogError ( myself , " HandleCommand_Buy_Internal detour could not be initialized - Disabled OnBuyCommand forward " ) ;
return false ;
}
bool CreateCSWeaponDropDetour ( )
{
2017-06-12 14:38:11 +02:00
DCSWeaponDrop = DETOUR_CREATE_MEMBER ( DetourCSWeaponDrop , WEAPONDROP_GAMEDATA_NAME ) ;
2011-06-26 10:25:42 +02:00
if ( DCSWeaponDrop ! = NULL )
{
DCSWeaponDrop - > EnableDetour ( ) ;
g_pCSWeaponDropDetoured = true ;
return true ;
}
g_pSM - > LogError ( myself , " CSWeaponDrop detour could not be initialized - Disabled OnCSWeaponDrop forward " ) ;
return false ;
}
void RemoveWeaponPriceDetour ( )
{
if ( DWeaponPrice ! = NULL )
{
DWeaponPrice - > Destroy ( ) ;
DWeaponPrice = NULL ;
}
g_PriceDetoured = false ;
}
void RemoveHandleBuyDetour ( )
{
if ( g_PriceDetoured )
return ;
if ( DHandleBuy ! = NULL )
{
DHandleBuy - > Destroy ( ) ;
DHandleBuy = NULL ;
}
g_HandleBuyDetoured = false ;
}
void RemoveTerminateRoundDetour ( )
{
if ( DTerminateRound ! = NULL )
{
DTerminateRound - > Destroy ( ) ;
DTerminateRound = NULL ;
}
g_pTerminateRoundDetoured = false ;
}
void RemoveCSWeaponDropDetour ( )
{
if ( DCSWeaponDrop ! = NULL )
{
DCSWeaponDrop - > Destroy ( ) ;
DCSWeaponDrop = NULL ;
}
g_pCSWeaponDropDetoured = false ;
}
2017-08-21 16:28:59 +02:00
2011-06-29 02:32:55 +02:00
int CallPriceForward ( int client , const char * weapon_name , int price )
{
int changedprice = price ;
cell_t result = Pl_Continue ;
g_pPriceForward - > PushCell ( client ) ;
g_pPriceForward - > PushString ( weapon_name ) ;
g_pPriceForward - > PushCellByRef ( & changedprice ) ;
g_pPriceForward - > Execute ( & result ) ;
if ( result = = Pl_Continue )
return price ;
return changedprice ;
}