summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/gokz-jumpstats/jump_validating.sp
diff options
context:
space:
mode:
Diffstat (limited to 'sourcemod/scripting/gokz-jumpstats/jump_validating.sp')
-rw-r--r--sourcemod/scripting/gokz-jumpstats/jump_validating.sp82
1 files changed, 82 insertions, 0 deletions
diff --git a/sourcemod/scripting/gokz-jumpstats/jump_validating.sp b/sourcemod/scripting/gokz-jumpstats/jump_validating.sp
new file mode 100644
index 0000000..c6835c7
--- /dev/null
+++ b/sourcemod/scripting/gokz-jumpstats/jump_validating.sp
@@ -0,0 +1,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;
+} \ No newline at end of file