Skip to content

Commit

Permalink
更新left4dhooks和l4d_target_override
Browse files Browse the repository at this point in the history
  • Loading branch information
fantasylidong committed Dec 5, 2022
1 parent 8589590 commit 08701ce
Show file tree
Hide file tree
Showing 12 changed files with 309 additions and 33 deletions.
52 changes: 46 additions & 6 deletions addons/sourcemod/gamedata/left4dhooks.l4d2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1601,6 +1601,18 @@
}
}

"CTerrorPlayer::CanBecomeGhost::Address"
{
"windows"
{
"signature" "CTerrorPlayer::CanBecomeGhost"
}
"linux"
{
"signature" "CTerrorPlayer::CanBecomeGhost"
}
}

// Used for dynamic searching of memory address for SDKCall
"Molotov_StrFind"
{
Expand Down Expand Up @@ -1763,12 +1775,11 @@
"linux" "36"
}

/* Offset into CTerrorPlayer
* Is this right? How do we find it?
*/
// Can be found in "CTerrorPlayer::SetBecomeGhostAt": *((float *)this + 2816) = s2;
// 2816 * 4 - 8
"SpawnTimer"
{
"windows" "11308"
"windows" "11276"
"linux" "11256"
}

Expand All @@ -1791,6 +1802,22 @@
"linux" "528"
}

"CTerrorPlayer::CanBecomeGhost::Offset"
{
"windows" "2375"
"linux" "1585"
}
"CTerrorPlayer::CanBecomeGhost::Bytes"
{
"windows" "232" // 0xE8
"linux" "232" // 0xE8
}
"CTerrorPlayer::CanBecomeGhost::Count"
{
"windows" "5"
"linux" "5"
}

"MobSpawnTimer"
{
"windows" "468"
Expand Down Expand Up @@ -3963,6 +3990,19 @@
/* ? ? ? ? ? ? 83 BE ? ? ? ? 00 7E 07 32 C0 5E 5D C2 04 00 8B 0D */
}

/*
* CTerrorPlayer::SetBecomeGhostAt(CTerrorPlayer *this, float s2)
* unique string "ghost_spawn_time"
*/
"CTerrorPlayer::SetBecomeGhostAt"
{
"library" "server"
"linux" "@_ZN13CTerrorPlayer16SetBecomeGhostAtEf"
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x56\x6A\x2A\x68\x2A\x2A\x2A\x2A\x8B\x2A\x68\x2A\x2A\x2A\x2A\xF3"
/* ? ? ? ? ? ? ? ? 56 6A ? 68 ? ? ? ? 8B ? 68 ? ? ? ? F3 */
/* Search: "ghost_spawn_time" target is called is above */
}

/*
* CTerrorPlayer::CanBecomeGhost(bool areSpawnsDisabled)
* unique string "ghost_spawn_time"
Expand All @@ -3971,8 +4011,8 @@
{
"library" "server"
"linux" "@_ZN13CTerrorPlayer14CanBecomeGhostEb"
"windows" "\x53\x8B\xDC\x83\xEC\x08\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x83\xEC\x78\x56\x57\x8B\xF1"
/* 53 8B DC 83 EC ? 83 E4 F0 83 C4 ? 55 8B 6B 04 89 6C 24 ? 8B EC 83 EC 78 56 57 8B F1 */
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x83\xEC\x78\x56\x57\x8B\xF1"
/* ? ? ? ? ? ? 83 E4 F0 83 C4 ? 55 8B 6B 04 89 6C 24 ? 8B EC 83 EC 78 56 57 8B F1 */
}

/*
Expand Down
Binary file modified addons/sourcemod/plugins/left4dhooks.smx
Binary file not shown.
Binary file modified addons/sourcemod/plugins/optional/AnneHappy/l4d_target_override.smx
Binary file not shown.
45 changes: 44 additions & 1 deletion addons/sourcemod/scripting/AnneHappy/l4d_target_override.sp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@



#define PLUGIN_VERSION "2.23"
#define PLUGIN_VERSION "2.24"
#define DEBUG_BENCHMARK 0 // 0=Off. 1=Benchmark only (for command). 2=Benchmark (displays on server). 3=PrintToServer various data.

/*======================================================================================
Expand All @@ -33,6 +33,9 @@
========================================================================================
Change Log:
2.24 (24-Nov-2022)
- Fixed plugin not accounting for idle or disconnected players being replaced by bots. Thanks to "HarryPotter" for help.
2.23 (28-Oct-2022)
- Fixed Special Infected not being able to target other SI. Tank vs SI is still not capable. Thanks to "Tonblader" for reporting.
- Fixed the "voms" and "voms2" options not working correctly.
Expand Down Expand Up @@ -633,6 +636,8 @@ void IsAllowed()
HookEvent("tongue_release", Event_SmokerEnd);
HookEvent("player_left_checkpoint", Event_LeftCheckpoint);
HookEvent("player_entered_checkpoint", Event_EnteredCheckpoint);
HookEvent("player_bot_replace", Event_PlayerReplace);
HookEvent("bot_player_replace", Event_BotReplace);

if( g_bLeft4Dead2 )
{
Expand Down Expand Up @@ -668,6 +673,8 @@ void IsAllowed()
UnhookEvent("tongue_release", Event_SmokerEnd);
UnhookEvent("player_left_checkpoint", Event_LeftCheckpoint);
UnhookEvent("player_entered_checkpoint", Event_EnteredCheckpoint);
UnhookEvent("player_bot_replace", Event_PlayerReplace);
UnhookEvent("bot_player_replace", Event_BotReplace);

if( g_bLeft4Dead2 )
{
Expand Down Expand Up @@ -783,6 +790,42 @@ void Event_LeftCheckpoint(Event event, const char[] name, bool dontBroadcast)
g_bCheckpoint[GetClientOfUserId(event.GetInt("userid"))] = false;
}

void Event_PlayerReplace(Event event, const char[] name, bool dontBroadcast)
{
int bot = GetClientOfUserId(GetEventInt(event, "bot"));
int player = GetClientOfUserId(GetEventInt(event, "player"));

g_bCheckpoint[bot] = g_bCheckpoint[player];
g_bIncapped[bot] = g_bIncapped[player];
g_bLedgeGrab[bot] = g_bLedgeGrab[player];
g_bPinSmoker[bot] = g_bPinSmoker[player];
g_bPinHunter[bot] = g_bPinHunter[player];
if( g_bLeft4Dead2 )
{
g_bPinJockey[bot] = g_bPinJockey[player];
g_bPinCharger[bot] = g_bPinCharger[player];
g_bPumCharger[bot] = g_bPumCharger[player];
}
}

void Event_BotReplace(Event event, const char[] name, bool dontBroadcast)
{
int bot = GetClientOfUserId(GetEventInt(event, "bot"));
int player = GetClientOfUserId(GetEventInt(event, "player"));

g_bCheckpoint[player] = g_bCheckpoint[bot];
g_bIncapped[player] = g_bIncapped[bot];
g_bLedgeGrab[player] = g_bLedgeGrab[bot];
g_bPinSmoker[player] = g_bPinSmoker[bot];
g_bPinHunter[player] = g_bPinHunter[bot];
if( g_bLeft4Dead2 )
{
g_bPinJockey[player] = g_bPinJockey[bot];
g_bPinCharger[player] = g_bPinCharger[bot];
g_bPumCharger[player] = g_bPumCharger[bot];
}
}

void HookPlayerHurt(bool doHook)
{
// Hook player_hurt for order type 7 - target last attacker.
Expand Down
35 changes: 32 additions & 3 deletions addons/sourcemod/scripting/include/left4dhooks.inc
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@



// Natives: 238
// L4D1 = 30 [left4downtown] + 47 [l4d_direct] + 15 [l4d2addresses] + 50 [silvers - mine!] + 4 [anim] = 140
// L4D2 = 66 [left4downtown] + 61 [l4d_direct] + 26 [l4d2addresses] + 92 [silvers - mine!] + 4 [anim] = 237
// Natives: 240
// L4D1 = 30 [left4downtown] + 47 [l4d_direct] + 15 [l4d2addresses] + 52 [silvers - mine!] + 4 [anim] = 142
// L4D2 = 66 [left4downtown] + 61 [l4d_direct] + 26 [l4d2addresses] + 94 [silvers - mine!] + 4 [anim] = 239

// Forwards: 168
// L4D1 = 123;
Expand Down Expand Up @@ -137,6 +137,7 @@ public void __pl_l4dh_SetNTVOptional()
MarkNativeAsOptional("L4D_GetEntityFromAddress");
MarkNativeAsOptional("L4D_ReadMemoryString");
MarkNativeAsOptional("L4D_GetServerOS");
MarkNativeAsOptional("Left4DHooks_Version");
MarkNativeAsOptional("L4D2_GetScriptScope");
MarkNativeAsOptional("L4D2_GetVScriptEntity");
MarkNativeAsOptional("L4D2_ExecVScriptCode");
Expand All @@ -147,6 +148,7 @@ public void __pl_l4dh_SetNTVOptional()
MarkNativeAsOptional("L4D_SetHumanSpec");
MarkNativeAsOptional("L4D_TakeOverBot");
MarkNativeAsOptional("L4D_CanBecomeGhost");
MarkNativeAsOptional("L4D_SetBecomeGhostAt");
MarkNativeAsOptional("L4D2_AreWanderersAllowed");
MarkNativeAsOptional("L4D2_GetCurrentFinaleStage");
MarkNativeAsOptional("L4D2_ForceNextStage");
Expand Down Expand Up @@ -2798,6 +2800,24 @@ native int L4D_ReadMemoryString(Address addy, char[] buffer, int maxlength);
*/
native int L4D_GetServerOS();

/**
* @brief Returns the Left4DHooks version number. For example version "1.122" is 1122.
* @note This will only work from Left4DHooks version 1.122 or newer.
*
* @remarks Use to verify a newer version is running from a certain version number, where for example a new native or forward was added.
* @remarks Each version number will be greater than the previous.
* @remarks Example code:
* @remarks Put: MarkNativeAsOptional("Left4DHooks_Version") in your plugins "AskPluginLoad2" section.
* @remarks Then run this code to determine the version:
* @remarks if( GetFeatureStatus(FeatureType_Native, "Left4DHooks_Version") == FeatureStatus_Available && Left4DHooks_Version() >= 1122 )
*
* @remarks Alternatively, to support all versions, it would be better to use the "left4dhooks_version" convar, retrieve as a float and check.
* @remarks For example: FindConVar("left4dhooks_version").FloatValue >= 1.122
*
* @return Version number
*/
native int Left4DHooks_Version();

/**
* @brief Returns an entities script scope (HSCRIPT)
*
Expand Down Expand Up @@ -3331,6 +3351,15 @@ native bool L4D_TakeOverBot(int client);
*/
native bool L4D_CanBecomeGhost(int client);

/**
* @brief Set a dead Special Infected players time until they transition into ghost state. Can be used when the "ghost_spawn_time" event triggers.
*
* @param client Client ID to check
*
* @return True or false
*/
native void L4D_SetBecomeGhostAt(int client, float time);

/**
* @brief Sets a client as idle, afk - away from keyboard.
*
Expand Down
23 changes: 13 additions & 10 deletions addons/sourcemod/scripting/l4dd/l4dd_forwards.sp
Original file line number Diff line number Diff line change
Expand Up @@ -1578,18 +1578,21 @@ MRESReturn DTR_CTerrorPlayer_GetWalkTopSpeed_Post(int pThis, DHookReturn hReturn

MRESReturn GetSpeed(int pThis, Handle hForward, DHookReturn hReturn)
{
float a2 = hReturn.Value;
if( IsClientInGame(pThis) )
{
float a2 = hReturn.Value;

Action aResult = Plugin_Continue;
Call_StartForward(hForward);
Call_PushCell(pThis);
Call_PushFloatRef(a2);
Call_Finish(aResult);
Action aResult = Plugin_Continue;
Call_StartForward(hForward);
Call_PushCell(pThis);
Call_PushFloatRef(a2);
Call_Finish(aResult);

if( aResult == Plugin_Handled )
{
hReturn.Value = a2;
return MRES_Supercede;
if( aResult == Plugin_Handled )
{
hReturn.Value = a2;
return MRES_Supercede;
}
}

return MRES_Ignored;
Expand Down
45 changes: 45 additions & 0 deletions addons/sourcemod/scripting/l4dd/l4dd_gamedata.sp
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,18 @@ void LoadGameData()
LogError("Failed to create SDKCall: \"CTerrorPlayer::CanBecomeGhost\" (%s)", g_sSystem);
}

StartPrepSDKCall(SDKCall_Player);
if( PrepSDKCall_SetFromConf(hGameData, SDKConf_Signature, "CTerrorPlayer::SetBecomeGhostAt") == false )
{
LogError("Failed to find signature: \"CTerrorPlayer::SetBecomeGhostAt\" (%s)", g_sSystem);
} else {
PrepSDKCall_AddParameter(SDKType_Float, SDKPass_Plain);
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
g_hSDK_CTerrorPlayer_SetBecomeGhostAt = EndPrepSDKCall();
if( g_hSDK_CTerrorPlayer_SetBecomeGhostAt == null )
LogError("Failed to create SDKCall: \"CTerrorPlayer::SetBecomeGhostAt\" (%s)", g_sSystem);
}

StartPrepSDKCall(SDKCall_Player);
if( PrepSDKCall_SetFromConf(hGameData, SDKConf_Signature, "CTerrorPlayer::GoAwayFromKeyboard") == false )
{
Expand Down Expand Up @@ -1964,6 +1976,39 @@ void LoadGameData()



// ====================
// Patch to allow "L4D_SetBecomeGhostAt" to work. Thanks to "sorallll" for this method.
// ====================
// Address to function
g_pCTerrorPlayer_CanBecomeGhost = hGameData.GetAddress("CTerrorPlayer::CanBecomeGhost::Address");
ValidateAddress(g_pCTerrorPlayer_CanBecomeGhost, "CTerrorPlayer::CanBecomeGhost::Address", true);

// Offset to patch
g_iCanBecomeGhostOffset = hGameData.GetOffset("CTerrorPlayer::CanBecomeGhost::Offset");
ValidateOffset(g_iCanBecomeGhostOffset, "CTerrorPlayer::CanBecomeGhost::Offset");

// Patch count and byte match
int bytes = hGameData.GetOffset("CTerrorPlayer::CanBecomeGhost::Bytes");
int count = hGameData.GetOffset("CTerrorPlayer::CanBecomeGhost::Count");

// Verify bytes and patch
int byte = LoadFromAddress(g_pCTerrorPlayer_CanBecomeGhost + view_as<Address>(g_iCanBecomeGhostOffset), NumberType_Int8);
if( byte == bytes )
{
for( int i = 0; i < count; i++ )
{
g_hCanBecomeGhost.Push(LoadFromAddress(g_pCTerrorPlayer_CanBecomeGhost + view_as<Address>(g_iCanBecomeGhostOffset), NumberType_Int8));
StoreToAddress(g_pCTerrorPlayer_CanBecomeGhost + view_as<Address>(g_iCanBecomeGhostOffset + i), 0x90, NumberType_Int8, true);
}
}
else if( byte != 0x90 )
{
LogError("CTerrorPlayer::CanBecomeGhost patch: byte mis-match. %X", LoadFromAddress(g_pCTerrorPlayer_CanBecomeGhost + view_as<Address>(g_iCanBecomeGhostOffset), NumberType_Int8));
}
// ====================



if( g_bLeft4Dead2 )
{
g_iOff_AddonEclipse1 = hGameData.GetOffset("AddonEclipse1");
Expand Down
Loading

0 comments on commit 08701ce

Please sign in to comment.