diff options
Diffstat (limited to 'sourcemod/scripting/gokz-jumpstats/jump_validating.sp')
| -rw-r--r-- | sourcemod/scripting/gokz-jumpstats/jump_validating.sp | 82 |
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 |
