1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
/*
Invalidating invalid jumps, such as ones with a modified velocity.
*/
static Handle processMovementHookPost;
void OnPluginStart_JumpValidating()
{
Handle gamedataConf = LoadGameConfigFile("gokz-core.games");
if (gamedataConf == null)
{
SetFailState("Failed to load gokz-core gamedata");
}
// CreateInterface
// Thanks SlidyBat and ici
StartPrepSDKCall(SDKCall_Static);
if (!PrepSDKCall_SetFromConf(gamedataConf, SDKConf_Signature, "CreateInterface"))
{
SetFailState("Failed to get CreateInterface");
}
PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer);
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL);
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
Handle CreateInterface = EndPrepSDKCall();
if (CreateInterface == null)
{
SetFailState("Unable to prepare SDKCall for CreateInterface");
}
char interfaceName[64];
// ProcessMovement
if (!GameConfGetKeyValue(gamedataConf, "IGameMovement", interfaceName, sizeof(interfaceName)))
{
SetFailState("Failed to get IGameMovement interface name");
}
Address IGameMovement = SDKCall(CreateInterface, interfaceName, 0);
if (!IGameMovement)
{
SetFailState("Failed to get IGameMovement pointer");
}
int offset = GameConfGetOffset(gamedataConf, "ProcessMovement");
if (offset == -1)
{
SetFailState("Failed to get ProcessMovement offset");
}
processMovementHookPost = DHookCreate(offset, HookType_Raw, ReturnType_Void, ThisPointer_Ignore, DHook_ProcessMovementPost);
DHookAddParam(processMovementHookPost, HookParamType_CBaseEntity);
DHookAddParam(processMovementHookPost, HookParamType_ObjectPtr);
DHookRaw(processMovementHookPost, false, IGameMovement);
}
static MRESReturn DHook_ProcessMovementPost(Handle hParams)
{
int client = DHookGetParam(hParams, 1);
if (!IsValidClient(client) || IsFakeClient(client))
{
return MRES_Ignored;
}
float pVelocity[3], velocity[3];
Movement_GetProcessingVelocity(client, pVelocity);
Movement_GetVelocity(client, velocity);
gB_SpeedJustModifiedExternally[client] = false;
for (int i = 0; i < 3; i++)
{
if (FloatAbs(pVelocity[i] - velocity[i]) > EPSILON)
{
// The current velocity doesn't match the velocity of the end of movement processing,
// so it must have been modified by something like a trigger.
InvalidateJumpstat(client);
gB_SpeedJustModifiedExternally[client] = true;
break;
}
}
return MRES_Ignored;
}
|