Skip to content

Commit

Permalink
Use memory patch instead of detour to allow bunnyjumping (#2)
Browse files Browse the repository at this point in the history
* Use memory patch instead of detour to allow bunnyjumping

* Remove dhooks dependency from README

* Create function to init patches and rename bunnyjump patch

* Change some wording in the README
  • Loading branch information
Mikusch authored Jan 13, 2021
1 parent 2c64f67 commit 573439a
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 49 deletions.
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
# Team Fortress 2 Bunnyhop
# Team Fortress 2 Bunnyhopping

This is a simple SourceMod plugin that allows players to bunnyhop in Team Fortress 2.

It is different to most other bunnyhop plugins, as it allows you to re-jump before the engine zeroes out
your z-velocity. This makes bunnyhopping feel incedibly smooth, since no speed is lost and no velocity needs to be manually
added by the plugin.
Unlike most other bunnyhop plugins, this implementation makes you jump before the engine zeroes out your z-velocity, preserving 100% of your speed and making each jump feel buttery smooth.

## Features

* Smooth auto-bhop by holding down the jump button
* Smooth auto-bunnyhopping by holding down the jump button
* No speed loss on a successful jump
* Works well even with high ping
* Allows crouch-bhopping
* Allows jumping while ducked
* Unlimited speed while bunnyhopping
* Prevents `CTFGameMovement::PreventBunnyJumping` from getting called
* Support for multiple jumps in mid-air (e.g. Scout's air dash, halloween spells, etc.)
Expand All @@ -20,7 +18,6 @@ added by the plugin.
## Dependencies

* SourceMod 1.10
* [DHooks with Detour Support](https://forums.alliedmods.net/showpost.php?p=2588686&postcount=589)
* [MemoryPatch](https://github.com/Kenzzer/MemoryPatch) (compile only)

## ConVars
Expand Down
42 changes: 25 additions & 17 deletions addons/sourcemod/gamedata/tf-bhop.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@
{
"Signatures"
{
"CTFGameMovement::PreventBunnyJumping"
{
"library" "server"
"linux" "@_ZN15CTFGameMovement19PreventBunnyJumpingEv"
"windows" "\x56\x8B\xF1\x6A\x52\x8B\x8E\xA8\x07\x00\x00\x81\xC1\xB0\x19\x00\x00\xE8\x2A\x2A\x2A\x2A\x84\xC0\x75\x2A"
}
"CTFPlayer::CanAirDash"
{
"library" "server"
"linux" "@_ZNK9CTFPlayer10CanAirDashEv"
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x57\x8B\xF9\xF7\x87\x84\x1A\x00\x00\x00\x00\x04\x00"
"windows" "\x55\x8B\xEC\x83\xEC\x08\x57\x8B\xF9\xF7\x87\x84\x1A\x00\x00\x00\x00\x04\x00"
}
"CTFGameMovement::CheckJumpButton"
{
"library" "server"
"linux" "@_ZN15CTFGameMovement15CheckJumpButtonEv"
"windows" "\x55\x8B\xEC\x83\xEC\x0C\x57\x8B\xF9\x8B\x47\x04\x80\xB8\x54\x0A\x00\x00\x00"
}
"CTFGameMovement::PreventBunnyJumping"
{
"library" "server"
"linux" "@_ZN15CTFGameMovement19PreventBunnyJumpingEv"
"windows" "\x56\x8B\xF1\x6A\x52\x8B\x8E\xA8\x07\x00\x00\x81\xC1\xB0\x19\x00\x00\xE8\x2A\x2A\x2A\x2A\x84\xC0\x75\x2A"
}
}
"Addresses"
{
"MemoryPatch_AllowDuckJump"
"MemoryPatch_AllowDuckJumping"
{
"linux"
{
Expand All @@ -38,20 +38,28 @@
"offset" "499" // CTFGameMovement::CheckJumpButton+1F3
}
}
}
"Functions"
{
"CTFGameMovement::PreventBunnyJumping"
"MemoryPatch_AllowBunnyJumping"
{
"signature" "CTFGameMovement::PreventBunnyJumping"
"callconv" "thiscall"
"return" "void"
"this" "ignore"
"linux"
{
"signature" "CTFGameMovement::PreventBunnyJumping"
"offset" "39" // CTFGameMovement::PreventBunnyJumping+27
}
"windows"
{
"signature" "CTFGameMovement::PreventBunnyJumping"
"offset" "24" // CTFGameMovement::PreventBunnyJumping+18
}
}
}
"Keys"
{
"MemoryPatch_AllowDuckJump"
"MemoryPatch_AllowDuckJumping"
{
"linux" "\xEB" // jz short -> jmp short
"windows" "\xEB" // jz short -> jmp short
}
"MemoryPatch_AllowBunnyJumping"
{
"linux" "\xEB" // jz short -> jmp short
"windows" "\xEB" // jz short -> jmp short
Expand Down
57 changes: 32 additions & 25 deletions addons/sourcemod/scripting/tf-bhop.sp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

#include <sourcemod>
#include <dhooks>
#include <sdktools>
#include <memorypatch>

#pragma semicolon 1
Expand All @@ -35,7 +35,8 @@ ConVar sv_autobunnyhopping;
ConVar sv_duckbunnyhopping;

Handle g_SDKCallCanAirDash;
MemoryPatch g_MemoryPatchAllowDuckJump;
MemoryPatch g_MemoryPatchAllowDuckJumping;
MemoryPatch g_MemoryPatchAllowBunnyJumping;

bool g_InJumpRelease[MAXPLAYERS + 1];

Expand All @@ -44,13 +45,14 @@ public Plugin myinfo =
name = "Team Fortress 2 Bunnyhop",
author = "Mikusch",
description = "Simple TF2 bunnyhopping plugin",
version = "1.1.0",
version = "1.2.0",
url = "https://github.com/Mikusch/tf-bhop"
}

public void OnPluginStart()
{
sv_enablebunnyhopping = CreateConVar("sv_enablebunnyhopping", "1", "Allow player speed to exceed maximum running speed", FCVAR_REPLICATED, true, 0.0, true, 1.0);
sv_enablebunnyhopping.AddChangeHook(ConVarChanged_PreventBunnyJumping);
sv_autobunnyhopping = CreateConVar("sv_autobunnyhopping", "1", "Players automatically re-jump while holding jump button", FCVAR_REPLICATED, true, 0.0, true, 1.0);
sv_duckbunnyhopping = CreateConVar("sv_duckbunnyhopping", "1", "Allow jumping while ducked", FCVAR_REPLICATED, true, 0.0, true, 1.0);
sv_duckbunnyhopping.AddChangeHook(ConVarChanged_DuckBunnyhopping);
Expand All @@ -59,12 +61,6 @@ public void OnPluginStart()
if (gamedata == null)
SetFailState("Could not find tf-bhop gamedata");

DynamicDetour detour = DynamicDetour.FromConf(gamedata, "CTFGameMovement::PreventBunnyJumping");
if (detour != null)
detour.Enable(Hook_Pre, DHookCallback_PreventBunnyJumpingPre);
else
LogError("Failed to create detour setup handle for function CTFGameMovement::PreventBunnyJumping");

StartPrepSDKCall(SDKCall_Player);
if (PrepSDKCall_SetFromConf(gamedata, SDKConf_Signature, "CTFPlayer::CanAirDash"))
{
Expand All @@ -79,20 +75,19 @@ public void OnPluginStart()
}

MemoryPatch.SetGameData(gamedata);

g_MemoryPatchAllowDuckJump = new MemoryPatch("MemoryPatch_AllowDuckJump");
if (g_MemoryPatchAllowDuckJump != null)
g_MemoryPatchAllowDuckJump.Enable();
else
LogError("Failed to create memory patch MemoryPatch_AllowDuckJump");
CreateMemoryPatch(g_MemoryPatchAllowDuckJumping, "MemoryPatch_AllowDuckJumping");
CreateMemoryPatch(g_MemoryPatchAllowBunnyJumping, "MemoryPatch_AllowBunnyJumping");

delete gamedata;
}

public void OnPluginEnd()
{
if (g_MemoryPatchAllowDuckJump != null)
g_MemoryPatchAllowDuckJump.Disable();
if (g_MemoryPatchAllowDuckJumping != null)
g_MemoryPatchAllowDuckJumping.Disable();

if (g_MemoryPatchAllowBunnyJumping != null)
g_MemoryPatchAllowBunnyJumping.Disable();
}

public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
Expand Down Expand Up @@ -128,21 +123,33 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3

public void ConVarChanged_DuckBunnyhopping(ConVar convar, const char[] oldValue, const char[] newValue)
{
if (convar.BoolValue)
if (g_MemoryPatchAllowDuckJumping != null)
{
if (g_MemoryPatchAllowDuckJump != null)
g_MemoryPatchAllowDuckJump.Enable();
if (convar.BoolValue)
g_MemoryPatchAllowDuckJumping.Enable();
else
g_MemoryPatchAllowDuckJumping.Disable();
}
else
}

public void ConVarChanged_PreventBunnyJumping(ConVar convar, const char[] oldValue, const char[] newValue)
{
if (g_MemoryPatchAllowBunnyJumping != null)
{
if (g_MemoryPatchAllowDuckJump != null)
g_MemoryPatchAllowDuckJump.Disable();
if (convar.BoolValue)
g_MemoryPatchAllowBunnyJumping.Enable();
else
g_MemoryPatchAllowBunnyJumping.Disable();
}
}

public MRESReturn DHookCallback_PreventBunnyJumpingPre()
void CreateMemoryPatch(MemoryPatch &handle, const char[] name)
{
return sv_enablebunnyhopping.BoolValue ? MRES_Supercede : MRES_Ignored;
handle = new MemoryPatch(name);
if (handle != null)
handle.Enable();
else
LogError("Failed to create memory patch %s", name);
}

bool CanAirDash(int client)
Expand Down

0 comments on commit 573439a

Please sign in to comment.