extensions/cstrike/forwards.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Fri Aug 03 16:10:28 2012 -0400 (2012-08-03)
changeset 3594 0a382baff180
parent 3519 a116c415c73e
child 3754 11c89c729fac
permissions -rw-r--r--
Updated SQLite for SQLite extension to version 3.7.13 (bug 5235).
rgr_02@3313
     1
#include "extension.h"
rgr_02@3313
     2
#include "forwards.h"
rgr_02@3519
     3
#include "util_cstrike.h"
rgr_02@3313
     4
rgr_02@3313
     5
bool g_pTerminateRoundDetoured = false;
rgr_02@3313
     6
bool g_pCSWeaponDropDetoured = false;
rgr_02@3313
     7
bool g_pIgnoreTerminateDetour = false;
rgr_02@3313
     8
bool g_pIgnoreCSWeaponDropDetour = false;
rgr_02@3313
     9
bool g_PriceDetoured = false;
rgr_02@3313
    10
bool g_HandleBuyDetoured = false;
rgr_02@3313
    11
int lastclient = -1;
rgr_02@3313
    12
rgr_02@3313
    13
IForward *g_pHandleBuyForward = NULL;
rgr_02@3313
    14
IForward *g_pPriceForward = NULL;
rgr_02@3313
    15
IForward *g_pTerminateRoundForward = NULL;
rgr_02@3313
    16
IForward *g_pCSWeaponDropForward = NULL;
rgr_02@3313
    17
CDetour *DHandleBuy = NULL;
rgr_02@3313
    18
CDetour *DWeaponPrice = NULL;
rgr_02@3313
    19
CDetour *DTerminateRound = NULL;
rgr_02@3313
    20
CDetour *DCSWeaponDrop = NULL;
rgr_02@3313
    21
rgr_02@3313
    22
int weaponNameOffset = -1;
rgr_02@3313
    23
rgr_02@3313
    24
DETOUR_DECL_MEMBER1(DetourHandleBuy, int, const char *, weapon)
rgr_02@3313
    25
{
rgr_02@3322
    26
	int client = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(this));
rgr_02@3313
    27
rgr_02@3313
    28
	lastclient = client;
rgr_02@3313
    29
rgr_02@3313
    30
	cell_t result = Pl_Continue;
rgr_02@3313
    31
rgr_02@3313
    32
	g_pHandleBuyForward->PushCell(client);
rgr_02@3313
    33
	g_pHandleBuyForward->PushString(weapon);
rgr_02@3313
    34
	g_pHandleBuyForward->Execute(&result);
rgr_02@3313
    35
rgr_02@3313
    36
	if (result != Pl_Continue)
rgr_02@3313
    37
	{
rgr_02@3313
    38
		lastclient = -1;
rgr_02@3313
    39
		return 0;
rgr_02@3313
    40
	}
rgr_02@3519
    41
rgr_02@3519
    42
#if SOURCE_ENGINE == SE_CSGO
rgr_02@3519
    43
	int defaultprice = -1;
rgr_02@3519
    44
	if (g_iPriceOffset != -1 && g_PriceDetoured)
rgr_02@3519
    45
	{
rgr_02@3519
    46
		defaultprice = CallPriceForwardCSGO(client, weapon);
rgr_02@3519
    47
	}
rgr_02@3519
    48
#endif
rgr_02@3519
    49
rgr_02@3313
    50
	int val = DETOUR_MEMBER_CALL(DetourHandleBuy)(weapon);
rgr_02@3519
    51
rgr_02@3519
    52
#if SOURCE_ENGINE == SE_CSGO
rgr_02@3519
    53
	if (defaultprice != -1)
rgr_02@3519
    54
		SetWeaponPrice(weapon, defaultprice);
rgr_02@3519
    55
#endif
rgr_02@3519
    56
rgr_02@3313
    57
	lastclient = -1;
rgr_02@3313
    58
	return val;
rgr_02@3313
    59
}
rgr_02@3313
    60
rgr_02@3519
    61
#if SOURCE_ENGINE != SE_CSGO
rgr_02@3313
    62
DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
rgr_02@3313
    63
{
rgr_02@3313
    64
	int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)();
rgr_02@3313
    65
rgr_02@3313
    66
	if (lastclient == -1)
rgr_02@3313
    67
		return price;
rgr_02@3313
    68
rgr_02@3313
    69
	const char *weapon_name = reinterpret_cast<char *>(this+weaponNameOffset);
rgr_02@3313
    70
rgr_02@3324
    71
	return CallPriceForward(lastclient, weapon_name, price);
rgr_02@3313
    72
}
rgr_02@3519
    73
#endif
rgr_02@3313
    74
rgr_02@3313
    75
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
rgr_02@3313
    76
{
rgr_02@3313
    77
	if (g_pIgnoreTerminateDetour)
rgr_02@3313
    78
	{
rgr_02@3313
    79
		g_pIgnoreTerminateDetour = false;
rgr_02@3313
    80
		DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
rgr_02@3313
    81
		return;
rgr_02@3313
    82
	}
rgr_02@3313
    83
	float orgdelay = delay;
rgr_02@3313
    84
	int orgreason = reason;
rgr_02@3313
    85
rgr_02@3313
    86
	cell_t result = Pl_Continue;
rgr_02@3313
    87
rgr_02@3313
    88
	g_pTerminateRoundForward->PushFloatByRef(&delay);
rgr_02@3313
    89
	g_pTerminateRoundForward->PushCellByRef(&reason);
rgr_02@3313
    90
	g_pTerminateRoundForward->Execute(&result);
rgr_02@3313
    91
rgr_02@3313
    92
	if (result >= Pl_Handled)
rgr_02@3313
    93
		return;
rgr_02@3313
    94
rgr_02@3313
    95
	if (result == Pl_Changed)
rgr_02@3313
    96
		return DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
rgr_02@3313
    97
rgr_02@3313
    98
	return DETOUR_MEMBER_CALL(DetourTerminateRound)(orgdelay, orgreason);
rgr_02@3313
    99
}
rgr_02@3519
   100
rgr_02@3313
   101
DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, something, bool, toss)
rgr_02@3313
   102
{
rgr_02@3313
   103
	if (g_pIgnoreCSWeaponDropDetour)
rgr_02@3313
   104
	{
rgr_02@3313
   105
		g_pIgnoreCSWeaponDropDetour = false;
rgr_02@3313
   106
		DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, something, toss);
rgr_02@3313
   107
		return;
rgr_02@3313
   108
	}
rgr_02@3313
   109
rgr_02@3322
   110
	int client = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(this));
rgr_02@3322
   111
	int weaponIndex = gamehelpers->EntityToBCompatRef(weapon);
rgr_02@3313
   112
rgr_02@3313
   113
	cell_t result = Pl_Continue;
rgr_02@3313
   114
	g_pCSWeaponDropForward->PushCell(client);
rgr_02@3313
   115
	g_pCSWeaponDropForward->PushCell(weaponIndex);
rgr_02@3313
   116
	g_pCSWeaponDropForward->Execute(&result);
rgr_02@3313
   117
rgr_02@3313
   118
rgr_02@3313
   119
	if (result == Pl_Continue)
rgr_02@3313
   120
		DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, something, toss);
rgr_02@3313
   121
rgr_02@3313
   122
	return;
rgr_02@3313
   123
}
rgr_02@3519
   124
rgr_02@3313
   125
bool CreateWeaponPriceDetour()
rgr_02@3313
   126
{
rgr_02@3313
   127
	if (weaponNameOffset == -1)
rgr_02@3313
   128
	{
rgr_02@3313
   129
		if (!g_pGameConf->GetOffset("WeaponName", &weaponNameOffset))
rgr_02@3313
   130
		{
rgr_02@3313
   131
			smutils->LogError(myself, "Could not find WeaponName offset - Disabled OnGetWeaponPrice forward");
rgr_02@3313
   132
			return false;
rgr_02@3313
   133
		}
rgr_02@3313
   134
	}
rgr_02@3519
   135
rgr_02@3519
   136
#if SOURCE_ENGINE == SE_CSGO
rgr_02@3519
   137
	if (g_iPriceOffset == -1)
rgr_02@3519
   138
	{
rgr_02@3519
   139
		if (!g_pGameConf->GetOffset("WeaponPrice", &g_iPriceOffset))
rgr_02@3519
   140
		{
rgr_02@3519
   141
			g_iPriceOffset = -1;
rgr_02@3519
   142
			g_pSM->LogError(myself, "Failed to get WeaponPrice offset - Disabled OnGetWeaponPrice forward");
rgr_02@3519
   143
			return false;
rgr_02@3519
   144
		}
rgr_02@3519
   145
	}
rgr_02@3519
   146
	if (!CreateHandleBuyDetour())
rgr_02@3519
   147
	{
rgr_02@3519
   148
		g_pSM->LogError(myself, "HandleCommand_Buy_Internal failed to detour, disabled OnGetWeaponPrice forward.");
rgr_02@3519
   149
		return false;
rgr_02@3519
   150
	}
rgr_02@3519
   151
	else
rgr_02@3519
   152
	{
rgr_02@3519
   153
		g_PriceDetoured = true;
rgr_02@3519
   154
		return true;
rgr_02@3519
   155
	}
rgr_02@3519
   156
#else
rgr_02@3519
   157
rgr_02@3313
   158
	DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetWeaponPrice");
rgr_02@3313
   159
rgr_02@3313
   160
	if (DWeaponPrice != NULL)
rgr_02@3313
   161
	{
rgr_02@3313
   162
		if (!CreateHandleBuyDetour())
rgr_02@3313
   163
		{
rgr_02@3313
   164
			g_pSM->LogError(myself, "GetWeaponPrice detour could not be initialized - HandleCommand_Buy_Internal failed to detour, disabled OnGetWeaponPrice forward.");
rgr_02@3313
   165
			return false;
rgr_02@3313
   166
		}
rgr_02@3313
   167
		DWeaponPrice->EnableDetour();
rgr_02@3313
   168
		g_PriceDetoured = true;
rgr_02@3313
   169
		return true;
rgr_02@3313
   170
	}
rgr_02@3313
   171
rgr_02@3313
   172
	g_pSM->LogError(myself, "GetWeaponPrice detour could not be initialized - Disabled OnGetWeaponPrice forward.");
rgr_02@3313
   173
rgr_02@3313
   174
	return false;
rgr_02@3519
   175
#endif
rgr_02@3313
   176
}
rgr_02@3313
   177
rgr_02@3313
   178
bool CreateTerminateRoundDetour()
rgr_02@3313
   179
{
rgr_02@3313
   180
	DTerminateRound = DETOUR_CREATE_MEMBER(DetourTerminateRound, "TerminateRound");
rgr_02@3313
   181
rgr_02@3313
   182
	if (DTerminateRound != NULL)
rgr_02@3313
   183
	{
rgr_02@3313
   184
		DTerminateRound->EnableDetour();
rgr_02@3313
   185
		g_pTerminateRoundDetoured = true;
rgr_02@3313
   186
		return true;
rgr_02@3313
   187
	}
rgr_02@3313
   188
	g_pSM->LogError(myself, "TerminateRound detour could not be initialized - Disabled OnTerminateRound forward");
rgr_02@3313
   189
	return false;
rgr_02@3313
   190
}
rgr_02@3313
   191
rgr_02@3313
   192
bool CreateHandleBuyDetour()
rgr_02@3313
   193
{
rgr_02@3313
   194
	if (g_HandleBuyDetoured)
rgr_02@3313
   195
		return true;
rgr_02@3313
   196
rgr_02@3313
   197
	DHandleBuy = DETOUR_CREATE_MEMBER(DetourHandleBuy, "HandleCommand_Buy_Internal");
rgr_02@3313
   198
rgr_02@3313
   199
	if (DHandleBuy != NULL)
rgr_02@3313
   200
	{
rgr_02@3313
   201
		DHandleBuy->EnableDetour();
rgr_02@3313
   202
		g_HandleBuyDetoured = true;
rgr_02@3313
   203
		return true;
rgr_02@3313
   204
	}
rgr_02@3313
   205
	g_pSM->LogError(myself, "HandleCommand_Buy_Internal detour could not be initialized - Disabled OnBuyCommand forward");
rgr_02@3313
   206
	return false;
rgr_02@3313
   207
}
rgr_02@3313
   208
rgr_02@3313
   209
bool CreateCSWeaponDropDetour()
rgr_02@3313
   210
{
rgr_02@3313
   211
	DCSWeaponDrop = DETOUR_CREATE_MEMBER(DetourCSWeaponDrop, "CSWeaponDrop");
rgr_02@3313
   212
rgr_02@3313
   213
	if (DCSWeaponDrop != NULL)
rgr_02@3313
   214
	{
rgr_02@3313
   215
		DCSWeaponDrop->EnableDetour();
rgr_02@3313
   216
		g_pCSWeaponDropDetoured = true;
rgr_02@3313
   217
		return true;
rgr_02@3313
   218
	}
rgr_02@3313
   219
rgr_02@3313
   220
	g_pSM->LogError(myself, "CSWeaponDrop detour could not be initialized - Disabled OnCSWeaponDrop forward");
rgr_02@3313
   221
	return false;
rgr_02@3313
   222
}
rgr_02@3313
   223
rgr_02@3313
   224
void RemoveWeaponPriceDetour()	
rgr_02@3313
   225
{
rgr_02@3519
   226
#if SOURCE_ENGINE != SE_CSGO
rgr_02@3313
   227
	if (DWeaponPrice != NULL)
rgr_02@3313
   228
	{
rgr_02@3313
   229
		DWeaponPrice->Destroy();
rgr_02@3313
   230
		DWeaponPrice = NULL;
rgr_02@3313
   231
	}
rgr_02@3313
   232
	g_PriceDetoured = false;
rgr_02@3519
   233
#endif
rgr_02@3313
   234
}
rgr_02@3313
   235
rgr_02@3313
   236
void RemoveHandleBuyDetour()	
rgr_02@3313
   237
{
rgr_02@3313
   238
	if (g_PriceDetoured)
rgr_02@3313
   239
		return;
rgr_02@3313
   240
rgr_02@3313
   241
	if (DHandleBuy != NULL)
rgr_02@3313
   242
	{
rgr_02@3313
   243
		DHandleBuy->Destroy();
rgr_02@3313
   244
		DHandleBuy = NULL;
rgr_02@3313
   245
	}
rgr_02@3313
   246
	g_HandleBuyDetoured = false;
rgr_02@3313
   247
}
rgr_02@3313
   248
rgr_02@3313
   249
void RemoveTerminateRoundDetour()	
rgr_02@3313
   250
{
rgr_02@3313
   251
	if (DTerminateRound != NULL)
rgr_02@3313
   252
	{
rgr_02@3313
   253
		DTerminateRound->Destroy();
rgr_02@3313
   254
		DTerminateRound = NULL;
rgr_02@3313
   255
	}
rgr_02@3313
   256
	g_pTerminateRoundDetoured = false;
rgr_02@3313
   257
}
rgr_02@3313
   258
rgr_02@3313
   259
void RemoveCSWeaponDropDetour()	
rgr_02@3313
   260
{
rgr_02@3313
   261
	if (DCSWeaponDrop != NULL)
rgr_02@3313
   262
	{
rgr_02@3313
   263
		DCSWeaponDrop->Destroy();
rgr_02@3313
   264
		DCSWeaponDrop = NULL;
rgr_02@3313
   265
	}
rgr_02@3313
   266
	g_pCSWeaponDropDetoured = false;
rgr_02@3313
   267
}
rgr_02@3519
   268
rgr_02@3519
   269
#if SOURCE_ENGINE == SE_CSGO
rgr_02@3519
   270
bool SetWeaponPrice(int weaponID, int price)
rgr_02@3519
   271
{
rgr_02@3519
   272
	void *info = GetWeaponInfo(weaponID);
rgr_02@3519
   273
	if (!info)
rgr_02@3519
   274
	{
rgr_02@3519
   275
		return false;
rgr_02@3519
   276
	}
rgr_02@3519
   277
	*(int *)((intptr_t)info+g_iPriceOffset) = price;
rgr_02@3519
   278
	return true;
rgr_02@3519
   279
}
rgr_02@3519
   280
rgr_02@3519
   281
bool SetWeaponPrice(const char *weapon, int price)
rgr_02@3519
   282
{
rgr_02@3519
   283
	const char *weaponalias = GetTranslatedWeaponAlias(weapon);
rgr_02@3519
   284
	int weaponID = AliasToWeaponID(weaponalias);
rgr_02@3519
   285
	if (weaponID <= 0)
rgr_02@3519
   286
	{
rgr_02@3519
   287
		return false;
rgr_02@3519
   288
	}
rgr_02@3519
   289
	void *info = GetWeaponInfo(weaponID);
rgr_02@3519
   290
	if (!info)
rgr_02@3519
   291
	{
rgr_02@3519
   292
		return false;
rgr_02@3519
   293
	}
rgr_02@3519
   294
	*(int *)((intptr_t)info+g_iPriceOffset) = price;
rgr_02@3519
   295
	return true;
rgr_02@3519
   296
rgr_02@3519
   297
}
rgr_02@3519
   298
rgr_02@3519
   299
int CallPriceForwardCSGO(int client, const char *weapon, int price)
rgr_02@3519
   300
{
rgr_02@3519
   301
	int changedprice = price;
rgr_02@3519
   302
	cell_t result = Pl_Continue;
rgr_02@3519
   303
rgr_02@3519
   304
	g_pPriceForward->PushCell(client);
rgr_02@3519
   305
	g_pPriceForward->PushString(weapon);
rgr_02@3519
   306
	g_pPriceForward->PushCellByRef(&changedprice);
rgr_02@3519
   307
	g_pPriceForward->Execute(&result);
rgr_02@3519
   308
	
rgr_02@3519
   309
	if (result == Pl_Continue)
rgr_02@3519
   310
		return price;
rgr_02@3519
   311
rgr_02@3519
   312
	return changedprice;
rgr_02@3519
   313
}
rgr_02@3519
   314
rgr_02@3519
   315
int CallPriceForwardCSGO(int client, const char *weapon)
rgr_02@3519
   316
{
rgr_02@3519
   317
	const char *weaponalias = GetTranslatedWeaponAlias(weapon);
rgr_02@3519
   318
	int weaponID = AliasToWeaponID(weaponalias);
rgr_02@3519
   319
	if (weaponID <= 0)
rgr_02@3519
   320
	{
rgr_02@3519
   321
		return -1;
rgr_02@3519
   322
	}
rgr_02@3519
   323
	void *info = GetWeaponInfo(weaponID);
rgr_02@3519
   324
	if (!info)
rgr_02@3519
   325
	{
rgr_02@3519
   326
		return -1;
rgr_02@3519
   327
	}
rgr_02@3519
   328
	const char *weapon_name = (const char *)((intptr_t)info + weaponNameOffset);
rgr_02@3519
   329
	int price = *(int *)((intptr_t)info + g_iPriceOffset);
rgr_02@3519
   330
	int changedprice = price;
rgr_02@3519
   331
	cell_t result = Pl_Continue;
rgr_02@3519
   332
rgr_02@3519
   333
	g_pPriceForward->PushCell(client);
rgr_02@3519
   334
	g_pPriceForward->PushString(weapon_name);
rgr_02@3519
   335
	g_pPriceForward->PushCellByRef(&changedprice);
rgr_02@3519
   336
	g_pPriceForward->Execute(&result);
rgr_02@3519
   337
		
rgr_02@3519
   338
	if (result == Pl_Continue)
rgr_02@3519
   339
		return -1;
rgr_02@3519
   340
	if (SetWeaponPrice(weaponID, changedprice))
rgr_02@3519
   341
		return price;
rgr_02@3519
   342
	else
rgr_02@3519
   343
		return -1;
rgr_02@3519
   344
}
rgr_02@3519
   345
#else
rgr_02@3519
   346
rgr_02@3324
   347
int CallPriceForward(int client, const char *weapon_name, int price)
rgr_02@3324
   348
{
rgr_02@3324
   349
	int changedprice = price;
rgr_02@3324
   350
rgr_02@3324
   351
	cell_t result = Pl_Continue;
rgr_02@3324
   352
rgr_02@3324
   353
	g_pPriceForward->PushCell(client);
rgr_02@3324
   354
	g_pPriceForward->PushString(weapon_name);
rgr_02@3324
   355
	g_pPriceForward->PushCellByRef(&changedprice);
rgr_02@3324
   356
	g_pPriceForward->Execute(&result);
rgr_02@3324
   357
	
rgr_02@3324
   358
	if (result == Pl_Continue)
rgr_02@3324
   359
		return price;
rgr_02@3324
   360
rgr_02@3324
   361
	return changedprice;
rgr_02@3324
   362
}
rgr_02@3519
   363
#endif