Skip to content

New timer method, tick fractions & StartReplay native#931

Merged
kidfearless merged 12 commits intoshavitush:very_good_yesfrom
hermansimensen:master
Jul 9, 2020
Merged

New timer method, tick fractions & StartReplay native#931
kidfearless merged 12 commits intoshavitush:very_good_yesfrom
hermansimensen:master

Conversation

@hermansimensen
Copy link
Contributor

Two new cvars:

  • shavit_core_useoffsets (0/1)
  • shavit_core_debugoffsets (1/0)

Tick calculation is now done in IGameMovement::ProcessMovement
Added tick fractioning system from Momentum Mod.
Added StartReplay native to allow support for per-player replays.

Tested and working on both csgo and css.

kidfearless and others added 9 commits June 17, 2020 20:04
This should hopefully prevent Invalid memory access from plugins compiled on older version of the timer. If an enum struct is changed then plugins compiled on older version of the timer will be forced to be recompiled to match the version they are using.
Misc. name changes for natives. And a somehow possible exception fixed when getting a record.
* Add optional cvar for player center of mass/player hitbox for touching zones
fix spelling mistake
add missing optional native
tabify spaces
Added the tick fraction system from Momentum Mod. Timer is now run within ProcessMovement
@hermansimensen hermansimensen changed the base branch from master to very_good_yes July 7, 2020 23:37
@kidfearless
Copy link
Collaborator

Not going to merge this yet since I haven't fully gone through it.

I'm not 100% sure if ProcessMovement will be the right way to go since it still seems vulnerable to time altering. Players with a frame rate low enough will move at the same real-time velocity as other players, but due to process movement not being called enough the actual advantage of that might not be as useful as I might think. I'm worried that if a player can willfully boost their time by reducing their frame rate that a cheater would be able to do the same without the disadvantages that would come with dropping frames.

One possible scenario where this would occur is on maps with a greater than 64/tickrate second drop allowing the player to toggle an fps bind and gain a .1 second difference in an identical route. While players are currently able to reduce times through cheats in the current system, one is abuse through means not normally accessible to the player, while the other can be changed via various methods.

@kidfearless
Copy link
Collaborator

Another thing is the way that time is incremented should be changed to match this system. While probably not significant, instead of incrementing the time by the time it took the server to process the last frame or the servers tick interval. It should be incremented by the players'/styles' timescale, then at the end multiplied by the tick interval of the server. This will greatly reduce the players' time from drifting too far from their actual time as their run continues. Assuming that they are running at a normal timescale.

The code below shows how bad the current system of incrementing is on the timer. variables are only incremented and assigned via Call_StartFunction to ensure that the compiler can't make any runtime optimizations for us. For a ten minute run at 100 tick the timer will add an extra .274 seconds to the players run. As a note, this is less of an issue on csgo servers that run on 2 to the power of n for the most part. It is also the most likely reason why rumour's time dropped significantly from the baseline.

public void OnPluginStart()
{
	float intervalTime = 0.0;
	float tickedTime = 0.0;
	for (int i = 0; i < 100 * 60 * 10; i++)
	{
		Call_StartFunction(INVALID_HANDLE, GetFunctionByName(GetMyHandle(), "GetTickIntervalEx"));
		float tickInterval;
		Call_Finish(tickInterval);
		Call_StartFunction(INVALID_HANDLE, GetFunctionByName(GetMyHandle(), "GetOne"));
		float one;
		Call_Finish(one)
		intervalTime += tickInterval;
		tickedTime += one;
	}
	Call_StartFunction(INVALID_HANDLE, GetFunctionByName(GetMyHandle(), "GetTickIntervalEx"));
	float tickInterval;
	Call_Finish(tickInterval);
	tickedTime *= tickInterval;

	PrintToConsoleAll("%.9f, %.9f", intervalTime, tickedTime);
}

public float GetTickIntervalEx()
{
	float interval = 1.0/100.0;
	return interval;
}

public float GetOne()
{
	float one = 1.0;
	return one;
}

600.274414062, 600.000000000
600.274414062, 600.000000000
600.274414062, 600.000000000
600.274414062, 600.000000000

@kidfearless
Copy link
Collaborator

After looking into the exploit more, it seems it was caused by some bad code of mine. I was unable to alter my times with the pull request by changing my framerate to the upper and lower bounds of the engine.

The timing issue on 100 tick servers will be addressed at a later date. Thanks @hermansimensen for making this pull request.

@kidfearless kidfearless merged commit dec640f into shavitush:very_good_yes Jul 9, 2020
@DaLLuZZ DaLLuZZ mentioned this pull request Jul 29, 2021
33 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants