3 #include "util_cstrike.h"
5 bool g_pTerminateRoundDetoured = false;
6 bool g_pCSWeaponDropDetoured = false;
7 bool g_pIgnoreTerminateDetour = false;
8 bool g_pIgnoreCSWeaponDropDetour = false;
9 bool g_PriceDetoured = false;
10 bool g_HandleBuyDetoured = false;
13 IForward *g_pHandleBuyForward = NULL;
14 IForward *g_pPriceForward = NULL;
15 IForward *g_pTerminateRoundForward = NULL;
16 IForward *g_pCSWeaponDropForward = NULL;
17 CDetour *DHandleBuy = NULL;
18 CDetour *DWeaponPrice = NULL;
19 CDetour *DTerminateRound = NULL;
20 CDetour *DCSWeaponDrop = NULL;
22 int weaponNameOffset = -1;
24 #if SOURCE_ENGINE == SE_CSGO
25 DETOUR_DECL_MEMBER2(DetourHandleBuy, int, const char *, weapon, bool, bRebuy)
27 DETOUR_DECL_MEMBER1(DetourHandleBuy, int, const char *, weapon)
30 int client = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(this));
34 cell_t result = Pl_Continue;
36 g_pHandleBuyForward->PushCell(client);
37 g_pHandleBuyForward->PushString(weapon);
38 g_pHandleBuyForward->Execute(&result);
40 if (result != Pl_Continue)
46 #if SOURCE_ENGINE == SE_CSGO
47 int defaultprice = -1;
48 if (g_iPriceOffset != -1 && g_PriceDetoured)
50 defaultprice = CallPriceForwardCSGO(client, weapon);
53 int val = DETOUR_MEMBER_CALL(DetourHandleBuy)(weapon, bRebuy);
55 int val = DETOUR_MEMBER_CALL(DetourHandleBuy)(weapon);
59 #if SOURCE_ENGINE == SE_CSGO
60 if (defaultprice != -1)
61 SetWeaponPrice(weapon, defaultprice);
68 #if SOURCE_ENGINE != SE_CSGO
69 DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
71 int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)();
76 const char *weapon_name = reinterpret_cast<char *>(this+weaponNameOffset);
78 return CallPriceForward(lastclient, weapon_name, price);
82 DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
84 if (g_pIgnoreTerminateDetour)
86 g_pIgnoreTerminateDetour = false;
87 DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
90 float orgdelay = delay;
91 int orgreason = reason;
93 cell_t result = Pl_Continue;
95 g_pTerminateRoundForward->PushFloatByRef(&delay);
96 g_pTerminateRoundForward->PushCellByRef(&reason);
97 g_pTerminateRoundForward->Execute(&result);
99 if (result >= Pl_Handled)
102 if (result == Pl_Changed)
103 return DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
105 return DETOUR_MEMBER_CALL(DetourTerminateRound)(orgdelay, orgreason);
108 DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, something, bool, toss)
110 if (g_pIgnoreCSWeaponDropDetour)
112 g_pIgnoreCSWeaponDropDetour = false;
113 DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, something, toss);
117 int client = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(this));
118 int weaponIndex = gamehelpers->EntityToBCompatRef(weapon);
120 cell_t result = Pl_Continue;
121 g_pCSWeaponDropForward->PushCell(client);
122 g_pCSWeaponDropForward->PushCell(weaponIndex);
123 g_pCSWeaponDropForward->Execute(&result);
126 if (result == Pl_Continue)
127 DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, something, toss);
132 bool CreateWeaponPriceDetour()
134 if (weaponNameOffset == -1)
136 if (!g_pGameConf->GetOffset("WeaponName", &weaponNameOffset))
138 smutils->LogError(myself, "Could not find WeaponName offset - Disabled OnGetWeaponPrice forward");
143 #if SOURCE_ENGINE == SE_CSGO
144 if (g_iPriceOffset == -1)
146 if (!g_pGameConf->GetOffset("WeaponPrice", &g_iPriceOffset))
149 g_pSM->LogError(myself, "Failed to get WeaponPrice offset - Disabled OnGetWeaponPrice forward");
153 if (!CreateHandleBuyDetour())
155 g_pSM->LogError(myself, "HandleCommand_Buy_Internal failed to detour, disabled OnGetWeaponPrice forward.");
160 g_PriceDetoured = true;
165 DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetWeaponPrice");
167 if (DWeaponPrice != NULL)
169 if (!CreateHandleBuyDetour())
171 g_pSM->LogError(myself, "GetWeaponPrice detour could not be initialized - HandleCommand_Buy_Internal failed to detour, disabled OnGetWeaponPrice forward.");
174 DWeaponPrice->EnableDetour();
175 g_PriceDetoured = true;
179 g_pSM->LogError(myself, "GetWeaponPrice detour could not be initialized - Disabled OnGetWeaponPrice forward.");
185 bool CreateTerminateRoundDetour()
187 DTerminateRound = DETOUR_CREATE_MEMBER(DetourTerminateRound, "TerminateRound");
189 if (DTerminateRound != NULL)
191 DTerminateRound->EnableDetour();
192 g_pTerminateRoundDetoured = true;
195 g_pSM->LogError(myself, "TerminateRound detour could not be initialized - Disabled OnTerminateRound forward");
199 bool CreateHandleBuyDetour()
201 if (g_HandleBuyDetoured)
204 DHandleBuy = DETOUR_CREATE_MEMBER(DetourHandleBuy, "HandleCommand_Buy_Internal");
206 if (DHandleBuy != NULL)
208 DHandleBuy->EnableDetour();
209 g_HandleBuyDetoured = true;
212 g_pSM->LogError(myself, "HandleCommand_Buy_Internal detour could not be initialized - Disabled OnBuyCommand forward");
216 bool CreateCSWeaponDropDetour()
218 DCSWeaponDrop = DETOUR_CREATE_MEMBER(DetourCSWeaponDrop, "CSWeaponDrop");
220 if (DCSWeaponDrop != NULL)
222 DCSWeaponDrop->EnableDetour();
223 g_pCSWeaponDropDetoured = true;
227 g_pSM->LogError(myself, "CSWeaponDrop detour could not be initialized - Disabled OnCSWeaponDrop forward");
231 void RemoveWeaponPriceDetour()
233 #if SOURCE_ENGINE != SE_CSGO
234 if (DWeaponPrice != NULL)
236 DWeaponPrice->Destroy();
239 g_PriceDetoured = false;
243 void RemoveHandleBuyDetour()
248 if (DHandleBuy != NULL)
250 DHandleBuy->Destroy();
253 g_HandleBuyDetoured = false;
256 void RemoveTerminateRoundDetour()
258 if (DTerminateRound != NULL)
260 DTerminateRound->Destroy();
261 DTerminateRound = NULL;
263 g_pTerminateRoundDetoured = false;
266 void RemoveCSWeaponDropDetour()
268 if (DCSWeaponDrop != NULL)
270 DCSWeaponDrop->Destroy();
271 DCSWeaponDrop = NULL;
273 g_pCSWeaponDropDetoured = false;
276 #if SOURCE_ENGINE == SE_CSGO
277 bool SetWeaponPrice(int weaponID, int price)
279 void *info = GetWeaponInfo(weaponID);
284 *(int *)((intptr_t)info+g_iPriceOffset) = price;
288 bool SetWeaponPrice(const char *weapon, int price)
290 const char *weaponalias = GetTranslatedWeaponAlias(weapon);
291 int weaponID = AliasToWeaponID(weaponalias);
296 void *info = GetWeaponInfo(weaponID);
301 *(int *)((intptr_t)info+g_iPriceOffset) = price;
306 int CallPriceForwardCSGO(int client, const char *weapon, int price)
308 int changedprice = price;
309 cell_t result = Pl_Continue;
311 g_pPriceForward->PushCell(client);
312 g_pPriceForward->PushString(weapon);
313 g_pPriceForward->PushCellByRef(&changedprice);
314 g_pPriceForward->Execute(&result);
316 if (result == Pl_Continue)
322 int CallPriceForwardCSGO(int client, const char *weapon)
324 const char *weaponalias = GetTranslatedWeaponAlias(weapon);
325 int weaponID = AliasToWeaponID(weaponalias);
330 void *info = GetWeaponInfo(weaponID);
335 const char *weapon_name = (const char *)((intptr_t)info + weaponNameOffset);
336 int price = *(int *)((intptr_t)info + g_iPriceOffset);
337 int changedprice = price;
338 cell_t result = Pl_Continue;
340 g_pPriceForward->PushCell(client);
341 g_pPriceForward->PushString(weapon_name);
342 g_pPriceForward->PushCellByRef(&changedprice);
343 g_pPriceForward->Execute(&result);
345 if (result == Pl_Continue)
347 if (SetWeaponPrice(weaponID, changedprice))
354 int CallPriceForward(int client, const char *weapon_name, int price)
356 int changedprice = price;
358 cell_t result = Pl_Continue;
360 g_pPriceForward->PushCell(client);
361 g_pPriceForward->PushString(weapon_name);
362 g_pPriceForward->PushCellByRef(&changedprice);
363 g_pPriceForward->Execute(&result);
365 if (result == Pl_Continue)