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 ;
int lastclient = - 1 ;
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 ;
2014-02-09 02:04:12 +01:00
//Windows CS:GO
// int __userpurge HandleCommand_Buy_Internal<eax>(int a1<ecx>, float a2<xmm0>, int a3, int a4, char a5)
// a1 - this
// a2 - CCSGameRules::GetWarmupPeriodEndTime(g_pGameRules)
// a3 - weapon
// a4 - unknown
// a5 - bRebuy
2013-01-23 20:46:12 +01:00
# if SOURCE_ENGINE == SE_CSGO
2013-08-14 23:08:02 +02:00
DETOUR_DECL_MEMBER3 ( DetourHandleBuy , int , const char * , weapon , int , iUnknown , bool , bRebuy )
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 )
2013-01-23 20:46:12 +01:00
# endif
2011-06-26 10:25:42 +02:00
{
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
# if SOURCE_ENGINE == SE_CSGO
2013-08-14 23:08:02 +02:00
int val = DETOUR_MEMBER_CALL ( DetourHandleBuy ) ( weapon , iUnknown , bRebuy ) ;
2013-01-23 20:46:12 +01:00
# else
2011-06-26 10:25:42 +02:00
int val = DETOUR_MEMBER_CALL ( DetourHandleBuy ) ( weapon ) ;
2013-01-23 20:46:12 +01:00
# endif
2011-06-26 10:25:42 +02:00
lastclient = - 1 ;
return val ;
}
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 )
2015-01-31 18:44:18 +01:00
# elif defined(WIN32)
DETOUR_DECL_MEMBER2 ( DetourWeaponPrice , int , CEconItemView * , pEconItem , int , iUnknown )
2013-08-15 20:40:30 +02:00
# else
2015-01-31 18:44:18 +01:00
DETOUR_DECL_MEMBER3 ( DetourWeaponPrice , int , CEconItemView * , pEconItem , int , iUnknown , float , fUnknown )
# endif
2013-08-15 20:40:30 +02:00
{
2015-01-31 18:44:18 +01:00
# if SOURCE_ENGINE != SE_CSGO
int price = DETOUR_MEMBER_CALL ( DetourWeaponPrice ) ( ) ;
# elif defined(WIN32)
int price = DETOUR_MEMBER_CALL ( DetourWeaponPrice ) ( pEconItem , iUnknown ) ;
# else
int price = DETOUR_MEMBER_CALL ( DetourWeaponPrice ) ( pEconItem , iUnknown , fUnknown ) ;
# endif
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 ) ;
}
2011-06-26 10:25:42 +02:00
2014-02-09 02:04:12 +01:00
# if SOURCE_ENGINE != SE_CSGO || !defined(WIN32)
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 ;
}
2014-02-09 02:04:12 +01:00
# else
//Windows CSGO
//char __userpurge TerminateRound<al>(unsigned int a1<ecx>, signed int a2<edi>, unsigned int a3<xmm1>, int a4)
// a1 - this
// a2 - unknown
// a3 - delay
// a4 - reason
DETOUR_DECL_MEMBER1 ( DetourTerminateRound , void , int , reason )
{
float delay ;
if ( g_pIgnoreTerminateDetour )
{
g_pIgnoreTerminateDetour = false ;
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( reason ) ;
}
//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:03:40 +02:00
# if SOURCE_ENGINE == SE_CSGO
reason - - ;
# endif
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:03:40 +02:00
# if SOURCE_ENGINE == SE_CSGO
reason + + ;
# endif
2014-02-09 02:04:12 +01:00
# if SOURCE_ENGINE != SE_CSGO || !defined(WIN32)
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 ) ;
2014-02-09 02:04:12 +01:00
# else
if ( result = = Pl_Changed )
{
__asm
{
movss xmm1 , delay
}
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( reason ) ;
}
__asm
{
movss xmm1 , orgdelay
}
return DETOUR_MEMBER_CALL ( DetourTerminateRound ) ( orgreason ) ;
# endif
2011-06-26 10:25:42 +02:00
}
2012-05-27 00:31:23 +02:00
2014-07-02 16:08:56 +02:00
# if SOURCE_ENGINE == SE_CSGO
DETOUR_DECL_MEMBER3 ( DetourCSWeaponDrop , void , CBaseEntity * , weapon , Vector , vec , bool , unknown )
# else
DETOUR_DECL_MEMBER3 ( DetourCSWeaponDrop , void , CBaseEntity * , weapon , bool , bDropShield , bool , bThrowForward )
# endif
2011-06-26 10:25:42 +02:00
{
if ( g_pIgnoreCSWeaponDropDetour )
{
g_pIgnoreCSWeaponDropDetour = false ;
2014-07-02 16:08:56 +02:00
# if SOURCE_ENGINE == SE_CSGO
DETOUR_MEMBER_CALL ( DetourCSWeaponDrop ) ( weapon , vec , unknown ) ;
# else
DETOUR_MEMBER_CALL ( DetourCSWeaponDrop ) ( weapon , bDropShield , bThrowForward ) ;
# 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 ) ;
g_pCSWeaponDropForward - > Execute ( & result ) ;
2015-03-28 00:54:42 +01:00
if ( result = = Pl_Continue )
2014-07-02 16:08:56 +02:00
{
# if SOURCE_ENGINE == SE_CSGO
DETOUR_MEMBER_CALL ( DetourCSWeaponDrop ) ( weapon , vec , unknown ) ;
# else
DETOUR_MEMBER_CALL ( DetourCSWeaponDrop ) ( weapon , bDropShield , bThrowForward ) ;
# endif
}
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 ( )
{
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
2015-01-31 18:44:18 +01:00
# if SOURCE_ENGINE == SE_CSGO && defined(WIN32)
void * pGetWeaponPriceAddress = GetWeaponPriceFunction ( ) ;
if ( ! pGetWeaponPriceAddress )
{
g_pSM - > LogError ( myself , " GetWeaponPrice detour could not be initialized - Disabled OnGetWeaponPrice forward. " ) ;
}
DWeaponPrice = DETOUR_CREATE_MEMBER ( DetourWeaponPrice , pGetWeaponPriceAddress ) ;
2012-05-27 00:31:23 +02:00
# else
2011-06-26 10:25:42 +02:00
DWeaponPrice = DETOUR_CREATE_MEMBER ( DetourWeaponPrice , " GetWeaponPrice " ) ;
2013-08-15 20:40:30 +02:00
# endif
2011-06-26 10:25:42 +02:00
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 ;
}
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 ;
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 ( )
{
DCSWeaponDrop = DETOUR_CREATE_MEMBER ( DetourCSWeaponDrop , " CSWeaponDrop " ) ;
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 ;
}
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 ;
}