AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Solved [L4D2] Tank hits multi players with one punch in Coop? (https://forums.alliedmods.net/showthread.php?t=332046)

HarryPotter 04-20-2021 08:08

[L4D2] Tank hits multi players with one punch in Coop?
 
In L4D coop/realism mode, each time tank can hit only one player with a punch.
But in versus/survival, tank can hit multi players with a punch.

So I want to ask is it possible that tank can hit multi players with one punch in coop/realism mode.

Edit: Thanks Forgetest and everyone, plugin here

Psyk0tik 04-20-2021 17:17

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
You can detour "CTankClaw::SweepFist" and patch this line:

L4D1:
PHP Code:

if ( g_pGameRules
    
&& ((unsigned __int8)CTerrorGameRules::IsVersusMode(ptra) || (unsigned __int8)CTerrorGameRules::IsHoldoutMode(ptrb)) ) 

PHP Code:

Linux: @_ZN9CTankClaw9SweepFistERK6VectorS2_
Windows
: \x81\xEC\x68\x01\x00\x00\x55
    
/* 81 EC 68 01 00 00 55 */ 

L4D2:
PHP Code:

if ( (unsigned __int8)CTerrorGameRules::HasPlayerControlledZombies()
      || (
unsigned __int8)CTerrorGameRules::IsSurvivalMode(v36) ) 

PHP Code:

Linux: @_ZN9CTankClaw9SweepFistERK6VectorS2_
Windows
: \x53\x8B\xDC\x83\xEC\x08\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x81\xEC\xA8\x01\x00\x00\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x8B\x43\x0C
    
/* 53 8B DC 83 EC 08 83 E4 F0 83 C4 04 55 8B 6B 04 89 6C 24 04 8B EC 81 EC A8 01 00 00 A1 ? ? ? ? 33 C5 89 45 FC 8B 43 0C */ 

How to find Windows sigs:

1a. (L4D1) Search "ValveBiped.Bip01_R_Hand" string which will lead you to "CTankClaw::DoSwing".
1b. (L4D2) Search "ValveBiped.Bip01_L_Hand" string which will lead you to "CTankClaw::DoSwing".
2. Look for "CTankClaw::SweepFist" as the very last function call.

I recommend detouring "CTankClaw::SweepFist" with a pre and post hook so you can patch in pre and revert back in post. Seeing as how "CTankClaw::DoSwing" can be called in multiple cases, it's best to remove the patch after the swing. (Not 100% sure on this so you decide.)

Forgetest 04-21-2021 08:49

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
Can I know how to patch those values?
Started from straight reading a single byte from signature HasPlayerControlledZombies, and it failed with crashing the server.
I'm confused as there seems to be no clue to find out whether it was missing offset to the value, or just made no sense to do so.

cravenge 04-21-2021 14:40

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
Quote:

Originally Posted by Crasher_3637 (Post 2744661)
[...]

Or instead of detouring, simply patching out that check from the function alone should suffice. Now to find the offset(s) of said check.

Psyk0tik 04-21-2021 18:36

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
The reason I recommend detouring the function first and patching those lines within the detour is to give more flexibility. If HP wants a global patch, then yeah, there’s no need for a detour, just patch it right on OnPluginStart() and call it a day. But if he wants to apply the patch only in certain scenarios, then the detour allows him to do just that.

I also stated that I’m not entirely sure if those lines can affect other scenarios that we’re not thinking of right now aside from when hitting all survivors within range of the swing, hence why I think it’s best to take the safe route from the start and just patch those lines when we actually need to.

cravenge 04-22-2021 08:59

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
Quote:

Originally Posted by Crasher_3637 (Post 2744748)
[...]

I think the detour method is unsafe and makes a server quite vulnerable to crashes since as you said, the function where it gets called from is called often.

Psyk0tik 04-22-2021 12:36

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
No, the detour method is safe. It's what you do inside the detour that would determine the server's vulnerability to crashes.

Here's a list of functions I've detoured in Mutant Tanks that are called way more often than "CTankClaw::SweepFist":

CTerrorGameMovement::DoJump - called for each player which can get very spammy on servers with high gravity.
CEnvRockLauncher::LaunchCurrentDir - can be called very often since one of the Tank abilities I coded spawns 1-2 rocks every second.
CTankClaw::OnPlayerHit - called each time a player gets hit; basically "CTankClaw::SweepFist" x number of survivors within range of the swing; so this would be more unsafe than detouring "CTankClaw::SweepFist" if anything.
CTerrorWeapon::SecondaryAttack - called very often considering my server doesn't have shove penalty and in some cases, the shove rate is increased.
CTerrorPlayer::StartReviving - can be spammed by players trolling their teammates.
CTankRock::Create - called after "CEnvRockLauncher::LaunchCurrentDir" which can be very often since one of the Tank abilities I coded spawns 1-2 rocks every second.
CTerrorPlayer::DoAnimationEvent - called multiple times because of all the different animations that each survivor can have even when just standing completely still.
CTerrorGun::FireBullet - self-explanatory
CTerrorMeleeWeapon::SecondaryAttack - called very often considering my server doesn't have shove penalty and in some cases, the shove rate is increased.
CBaseBackpackItem::StartAction - called each time an action starts which can get spammy when players cancel their actions.
CTerrorMeleeWeapon::TestMeleeSwingCollision - called very often depending on the swing rate of each player.

For context, I've had these detours for months now and my server hasn't crashed from any of these detours nor have I experienced any performance issues related to them even during high traffic.

Psyk0tik 04-22-2021 18:11

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
Quote:

Originally Posted by Forgetest (Post 2744708)
Can I know how to patch those values?
Started from straight reading a single byte from signature HasPlayerControlledZombies, and it failed with crashing the server.
I'm confused as there seems to be no clue to find out whether it was missing offset to the value, or just made no sense to do so.

Sorry for the late response. I just now found the time to do this myself and it worked. All you have to do is patch both calls to the game mode checks.

Keep in mind that I haven't tested this out thoroughly. I've only watched the Tank beat up all survivors at the same time in a corner. I've only tested on Windows so far for both games.

Here's the relevant gamedata info you will need:

Detour:
PHP Code:

/* CTankClaw::SweepFist(Vector const&, Vector const&) */
"CTankClaw::SweepFist"
{
    
"signature"    "CTankClaw::SweepFist"
    "callconv"    "thiscall"
    "return"    "void"
    "this"        "entity"
    "arguments"
    
{
        
"a1"
        
{
            
"type"        "vectorptr"
        
}
        
"a2"
        
{
            
"type"        "vectorptr"
        
}
    }


Offsets:
PHP Code:

L4D1:
"CTankClaw::SweepFist::Check1"
{
    
"windows"    "1067" // start at E8 and patch 5 bytes with NOPs (0x90)
    
"linux"        "1565" // start at E8 and patch 5 bytes with NOPs (0x90)
}

"CTankClaw::SweepFist::Check2"
{
    
"windows"    "1076" // start at E8 and patch 5 bytes with NOPs (0x90)
    
"linux"        "3078" // start at E8 and patch 5 bytes with NOPs (0x90)
}

L4D2:
"CTankClaw::SweepFist::Check1"
{
    
"windows"    "1382" // start at E8 and patch 5 bytes with NOPs (0x90)
    
"linux"        "2519" // start at E8 and patch 5 bytes with NOPs (0x90)
}

"CTankClaw::SweepFist::Check2"
{
    
"windows"    "1391" // start at E8 and patch 5 bytes with NOPs (0x90)
    
"linux"        "3473" // start at E8 and patch 5 bytes with NOPs (0x90)


Signatures:
PHP Code:

L4D1:
"CTankClaw::SweepFist"
{
    
"library"    "server"
    "linux"        "@_ZN9CTankClaw9SweepFistERK6VectorS2_"
    "windows"    "\x2A\x2A\x2A\x2A\x2A\x2A\x55\x56\x8B\x2A\xE8\x2A\x2A\x2A\x2A\x8B\x2A\x85\xF6\x0F\x84\x2A\x2A\x2A\x2A\x8B\x0D"
}

L4D2:
"CTankClaw::SweepFist"
{
    
"library"    "server"
    "linux"        "@_ZN9CTankClaw9SweepFistERK6VectorS2_"
    "windows"    "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x81\xEC\xA8\x01\x00\x00\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x8B\x43\x0C"


Here are the bytes you need to patch:
PHP Code:

"verify"        "\xE8" // make sure the call instruction starts with E8
"bytes"            "\x90\x90\x90\x90\x90" // patch the call instruction with NOPs
"length"        "5" // patch a total of 5 bytes 


Lux 04-22-2021 19:33

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
I do recommend using sourcescramble crasher if you are applying and removing a patch within a detour.
https://forums.alliedmods.net/showthread.php?t=317175

Psyk0tik 04-22-2021 20:00

Re: [L4D2] Tank hits multi players with one punch in Coop?
 
Quote:

Originally Posted by Lux (Post 2744845)
I do recommend using sourcescramble crasher if you are applying and removing a patch within a detour.
https://forums.alliedmods.net/showthread.php?t=317175

Thank you. I may start using this for private plugins. Only reason I haven’t used this yet is because I haven’t released any new plugins publicly that patch stuff. MT has its own simple patching system that I implemented before finding out about SourceScramble.


All times are GMT -4. The time now is 06:33.

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