Raised This Month: $32 Target: $400
 8% 

[PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Nickelony
Junior Member
Join Date: Aug 2017
Location: Poland
Old 01-06-2018 , 10:06   [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #1

Hello everyone!

A few months ago, I started working (with the help of zipcore) on a strafebooster plugin which simulates a higher or lower tickrate while strafing. I was just about to release it after a few weeks of testing on my public server, but the players found an exploit which in my opinion is unfixable since I would have to change the whole functionality of the plugin.

First, let me explain how the plugin works.

How it works:

The plugin gets the client's eye angles and calculates the difference between ticks:
Code:
float fTempAngle = angles[1];

float fAngles[3];
GetClientEyeAngles(client, fAngles);
float fAngleDiff = (fTempAngle - fAngles[1]);

if(fAngleDiff < 0.0)
{
	fAngleDiff = -fAngleDiff;
}

return fAngleDiff;
After that, the plugin checks if the players is strafing:
Code:
bool bPlayerStrafing = ((vel[0] != 0.0 || vel[1] != 0.0) && fAngleDiff != 0.0);
Then it gets the server tickrate to calculate the difference between other tickrates (to have a similar simulation for every possible tickrate):
Code:
float fTickrate = 1.0 / GetTickInterval();
float fTickDiff = 100.0 / fTickrate;
Then it calculates the perfect strafing angles for each tickrate (This is a close simulation of how the strafing worked in CS 1.6... I think.):
Code:
if(fAngleDiff > (fTickDiff * 10.0))
{
	fAngleDiff = ((fTickDiff * 10.0) * 2.0) - fAngleDiff;

	if(fAngleDiff == 0.0)
	{
		fAngleDiff = 0.0;
	}
}
And finally, it simulates the strafing tickrate using the perfect strafing angles and a multiplier (e.g. 1.024 for TR102.4):
Code:
float fMultiplier = gF_SimulatedTR / 100.0;

if(fMultiplier == (fTickrate / 100.0)) // If the simulated tickrate equals the server tickrate.
{
	return;
}

else // If you want to have a higher strafing tickrate.
{
	float fNewGain = fCurrentSpeed / (fCurrentSpeed + (fMultiplier * (fStrafingAngle * 0.1) * fTickDiff));

	// Explanation:
	// (0.64 * (15.625 * 0.1) * 1.5625) * [Tickrate 64.0] = 100.0
	// (1.024 * (9.765625 * 0.1) * 0.9765625) * [Tickrate 102.4] = 100.0
	// (1.28 * (7.8125 * 0.1) * 0.78125) * [Tickrate 128.0] = 100.0

	// If fStrafingAngle equals fTickDiff, then the player's strafing efficiency equals 100%

	fAbsVelocity[0] /= fNewGain;
	fAbsVelocity[1] /= fNewGain;
	TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, fAbsVelocity);
}
This method believably recreates FPS categories from CS 1.6 and other tickrates from CS:GO, but there's just 1 problem that ruins the whole concept of this plugin.

The problem:

While strafing with W / A / S / D only or HSW, you're gaining a lot of unfair speed because it's much more efficient than normal strafing. This is just inacceptable.

What I need:

I'm looking for help, because I don't know if my method is complete trash or if there's any way to improve it.
Also, if anyone has an idea how to fix the exploit I mentioned above, I would be greatful!

Source Code

Thanks for your attention!

Last edited by Nickelony; 01-06-2018 at 11:52.
Nickelony is offline
zipcore
Veteran Member
Join Date: Mar 2010
Location: m_flZipcore
Old 01-06-2018 , 10:32   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #2

Well I just gave you the tools etc. the main work was done by you. But I'm afraid to let you know I'm to busy atm to help you now. If nobody could find a solution next days come msg me on steam and I'll check your latest version.
__________________
zipcore is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 01-06-2018 , 11:19   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #3

You had me until the 100.0 / tickrate, can you explain where you got that from and what its meant to be? Would also be helpful if you could explain what GetStrafingAngle is meant to do. You say its meant to calculate "perfect strafing angles" but I don't really see how it does that.

Also:
PHP Code:
if(fAngleDiff == 0.0)
{
    
fAngleDiff 0.0;

wat

Last edited by hmmmmm; 01-06-2018 at 11:20.
hmmmmm is offline
Nickelony
Junior Member
Join Date: Aug 2017
Location: Poland
Old 01-06-2018 , 12:31   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #4

Quote:
Originally Posted by hmmmmm View Post
You had me until the 100.0 / tickrate, can you explain where you got that from and what its meant to be? Would also be helpful if you could explain what GetStrafingAngle is meant to do. You say its meant to calculate "perfect strafing angles" but I don't really see how it does that.

Also:
PHP Code:
if(fAngleDiff == 0.0)
{
    
fAngleDiff 0.0;

wat
Well, I was trying to understand how high FPS strafing works in CS 1.6, so I slowed down the game and I tried to strafe about 10 times per jump, so I could tell when the player is slowing down after strafing too much. (the result is about 7-8 perfect strafes)

I tried to do the same in CS:GO and the result was very similar.
On tickrate 128, you started to lose speed after the angle difference went above ~8.0
On tickrate 102.4, above ~10.0
On tickrate 64, above ~16.0
So I used the "tick difference" because it fits with my measurements (which might be total trash if I think about this now).
"Tick difference" also balances the multiplier, so it's the same for every other tickrate.

Anyway, there's definitely a better solution to do this, but I just can't think of anything different.
That's why I posted this plugin here, seeking help to make this a better plugin.

Also:
PHP Code:
if(fAngleDiff == 0.0)
{
    
fAngleDiff 0.0;

holy... I didn't see that, thx. xD

Last edited by Nickelony; 01-06-2018 at 12:53.
Nickelony is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 01-06-2018 , 13:15   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #5

I don't think this will work, the angle difference/speed gain ratio is dependent on your current speed. On higher velocity, turning a certain angle might make you lose speed, while on lower velocity it makes you go faster.

For simulating a lower tickrate you can try nulling the excess cmds (setting vel[1] to 0 should do the trick)
e.g. If on 128 tick and simulating 64 tick, null every second cmd sent by player. That way only half the ticks get used by player and on rest nothing should happen.
Not sure how effective it'll be but I've used this for a similar problem before and worked out well for me.

As for simulating higher tickrates, I'm not too sure. Theres probably some calculations you can do to simulate it. Possibly redoing AirAccelerate stuff with modified frametime?

Again, not too sure how well that would work, but these are the ideas that I have.

Last edited by hmmmmm; 01-06-2018 at 13:16.
hmmmmm is offline
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 01-07-2018 , 20:21   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #6

I had a better idea for this, basically what @hmmmmm suggested.

https://forums.alliedmods.net/showthread.php?t=303550

If anyone helps me figure out how to hook CGameMovement::ProcessMovement in both pre and post aspects, it shouldn't be too hard to do.
However I'm not great at CPP and I'm not good at reversing/hacking either, unfortunately there aren't many resources out to help with this :/

Or instead of pre and post hooks, hook pre, modify tick interval, call the detoured function and after calling it, restore the frame time.

-

Keep in mind that if something like this works out, it will probably feel terrible at high pings due to client prediction not matching the server's CGameMovement::ProcessMovement function, as the code is shared between the client and the server.
__________________
retired

Last edited by shavit; 01-07-2018 at 20:24.
shavit is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 01-08-2018 , 08:51   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #7

To hook it you can just use DHooks since its a virtual function and it lets you easily hook pre/post, no need for any cpp and MM/Extensions.

Heres a plugin I quickly made that (i think) does that:
PHP Code:
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <dhooks>

Handle g_hProcessMovementHookPre;
Handle g_hProcessMovementHookPost;

public 
void OnPluginStart()
{
    
Handle hGameData LoadGameConfigFile"frametime_changer.games" );
    if( 
hGameData == null )
    {
        
LogError"Failed to load processmove_hook.games.txt gamedata for CCSGameMovement::ProcessMovement hook." );
        return;
    }

    
Address pGameMovement GameConfGetAddresshGameData"g_pGameMovement" );
    if ( 
pGameMovement == Address_Null )
    {
        
LogError"Failed to find g_pGameMovement address" );
        return;
    }

    
int iOffset GameConfGetOffsethGameData"CCSGameMovement::ProcessMovement" );
    if( 
iOffset == -)
    {
        
LogError"Can't find CCSGameMovement::ProcessMovement offset in gamedata." );
        return;
    }
    
    
delete hGameData;
    
    
g_hProcessMovementHookPre DHookCreateiOffsetHookType_RawReturnType_VoidThisPointer_IgnoreDHooks_OnProcessMovementPre );
    if( 
g_hProcessMovementHookPre == null )
    {
        
LogError"Failed to create CCSGameMovement::ProcessMovement hook." );
        return;
    }

    
DHookAddParamg_hProcessMovementHookPreHookParamType_CBaseEntity );
    
DHookAddParamg_hProcessMovementHookPreHookParamType_ObjectPtr );
    
DHookRawg_hProcessMovementHookPrefalsepGameMovement );
    
    
g_hProcessMovementHookPost DHookCreateiOffsetHookType_RawReturnType_VoidThisPointer_IgnoreDHooks_OnProcessMovementPost );
    if( 
g_hProcessMovementHookPost == null )
    {
        
LogError"Failed to create CCSGameMovement::ProcessMovement hook." );
        return;
    }

    
DHookAddParamg_hProcessMovementHookPostHookParamType_CBaseEntity );
    
DHookAddParamg_hProcessMovementHookPostHookParamType_ObjectPtr );
    
DHookRawg_hProcessMovementHookPosttruepGameMovement );
}

public 
MRESReturn DHooks_OnProcessMovementPreHandle hParams )
{
    
int entity DHookGetParamhParams);
    if( 
entity <= MaxClients && IsClientInGameentity ) )
    {
        
PrintToServer"ProcessMovement hook started for %N"entity );
    }
    
    return 
MRES_Ignored;
}

public 
MRESReturn DHooks_OnProcessMovementPostHandle hParams )
{
    
int entity DHookGetParamhParams);
    if( 
entity <= MaxClients && IsClientInGameentity ) )
    {
        
PrintToServer"ProcessMovement hook finished for %N"entity );
    }
    
    return 
MRES_Ignored;

Used some gamedata/code from peacemakers ramp slope fix since hook is so similar
Attached Files
File Type: txt processmove_hook.games.txt (725 Bytes, 212 views)

Last edited by hmmmmm; 01-08-2018 at 11:04.
hmmmmm is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 01-08-2018 , 13:01   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #8

Alright so I decided to do a bit more work on this. I made a simple (kinda aids) plugin which sets a players frametime to whatever they set using sm_frametime.

Turns out that prediction wasn't that bad, and the method works pretty well. However just changing frametime doesn't really do what you were hoping since the amount of times its called is still dependent on the tickrate. So the best way to do this is to both change the frametime and also change the amount of times the function is called.
e.g. Current tickrate is 128 and we want to emulate 64 tick. Multiply frametime by 2.0 (128.0 / 64.0) and block half the ProcessMovement calls. If the calls weren't blocked, even though the frametime was doubled, it still gets called 128 times a second instead of 64 times a second so player just go "faster".
Same goes for emulating movement in one tickrate to any other.

Another thing you can do is set the clients m_fLaggedMovement value to cur_tickrate/desired_tickrate before function and then back after its finished, rather than directly changing the frametime. In ProcessMovement frametime is multiplied by LaggedMovementValue and set back (unless that code is outdated).
Attached Files
File Type: sp Get Plugin or Get Source (frametime_changer.sp - 410 views - 4.2 KB)
File Type: txt frametime_changer.games.txt (1.3 KB, 433 views)

Last edited by hmmmmm; 01-08-2018 at 13:03.
hmmmmm is offline
Nickelony
Junior Member
Join Date: Aug 2017
Location: Poland
Old 02-03-2018 , 09:35   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #9

I still have no clue how to use it to simulate a different tickrate since it's just slowing down the player's movement. I don't see anything useful in it. :/
Nickelony is offline
zhell
Member
Join Date: Oct 2016
Location: Sweden
Old 03-05-2019 , 10:18   Re: [PROJECT] Strafebooster (strafing tickrate simulation) [Need help!]
Reply With Quote #10

Any further improvements on this? Did you ever finish the project or did it come to a halt due to the issue?
__________________
Community Servers: zhell.nu
Steam: zhell
Discord: zhell#7227

Contact me on Steam for inquiries
zhell is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 19:58.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode