Add sm_autoidle_ping_max tool

This commit is contained in:
Jackzie 2021-03-23 22:52:55 -05:00
parent 66f63b4528
commit 2851e70de0
No known key found for this signature in database
GPG key ID: 1E834FE36520537A
5 changed files with 151 additions and 5 deletions

1
.gitignore vendored
View file

@ -2,6 +2,7 @@
!plugins
!scripting
!scripting/include
!gamedata/
template.config.js
.*
scripting/sm_give.sp

View file

@ -132,11 +132,13 @@ A collection of small tools:
* Set the survivor models of any survivor to another correctly.
* Chat Alert when a player activates a car alarm
* Automatically gives melee weapons that an idle bot dropped once no longer idle
* Automatically make players go idle when ping spikes
* **Convars:**
* `sm_laser_use_notice <0/1>` - Enable notification of when a laser box was used first
* `sm_time_finale <0/1/2>` - Record the time it takes to complete finale. 0 -> OFF, 1 -> Gauntlets Only, 2 -> All finales
* `sm_ff_notice <0/1/2>` - Should we record FF damages? 0: OFF, 1: To chat, 2: To HUD text.
* `sm_autoidle_ping_max <30.0...>` - "The highest ping a player can have until they will automatically go idle.\n0=OFF, Min is 30
* **Commands:**
* `sm_model <player> <character>` - Sets the survivor model of the target player(s). 'character' is name or ID of character.

58
gamedata/l4d2tools.txt Normal file
View file

@ -0,0 +1,58 @@
"Games" {
"#default" {
"Offsets" {
"OS" { // Thank you Sammy-ROCK!
"windows" "1"
"linux" "0"
}
}
}
// Big thanks to cravenge and Spirit_12 on AlliedModders for being awesome :D
"left4dead2" {
"Signatures" {
"State_Transition" {
"library" "server"
"linux" "@_ZN9CCSPlayer16State_TransitionE13CSPlayerState"
"windows" "\x55\x8B\xEC\x56\x8B\xF1\x8B\x86\x2A\x2A\x2A\x2A\x57\x8B\x7D\x2A\x85\xC0\x74\x2A\x83"
/* 55 8B EC 56 8B F1 8B 86 ? ? ? ? 57 8B 7D ? 85 C0 74 ? 83 */
}
"TakeOverZombieBot" {
"library" "server"
"linux" "@_ZN13CTerrorPlayer17TakeOverZombieBotEPS_"
"windows" "\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\xA1\xD8\x2A\x2A\x2A\x33\xC5\x89\x45\x2A\x53\x8B\x5D\x2A\x80"
/* 55 8B EC 81 EC ? ? ? ? ? D8 ? ? ? 33 C5 89 45 ? 53 8B 5D ? 80 */
}
"RoundRespawn" {
"library" "server"
"linux" "@_ZN13CTerrorPlayer12RoundRespawnEv"
"windows" "\x56\x8B\xF1\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x84\xC0\x75"
/* 56 8B F1 E8 ? ? ? ? E8 ? ? ? ? 84 C0 75 */
}
"SetHumanSpec" {
"library" "server"
"linux" "@_ZN11SurvivorBot17SetHumanSpectatorEP13CTerrorPlayer"
"windows" "\x55\x8B\xEC\x56\x8B\xF1\x83\xBE\x2A\x2A\x2A\x2A\x00\x7E\x07\x32\xC0\x5E\x5D\xC2\x04\x00\x8B\x0D"
/* 55 8B EC 56 8B F1 83 BE ? ? ? ? 00 7E 07 32 C0 5E 5D C2 04 00 8B 0D */
}
"TakeOverBot" {
"library" "server"
"linux" "@_ZN13CTerrorPlayer11TakeOverBotEb"
"windows" "\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x53\x56\x8D\x85"
/* 55 8B EC 81 EC ? ? ? ? A1 ? ? ? ? 33 C5 89 45 FC 53 56 8D 85 */
}
"GoAwayFromKeyboard"
{
"library" "server"
"linux" "@_ZN13CTerrorPlayer18GoAwayFromKeyboardEv"
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x53\x56\x57\x8B\xF1\x8B\x06\x8B\x90\xC8\x08\x00\x00"
/* ? ? ? ? ? ? 53 56 57 8B F1 8B 06 8B 90 C8 08 00 00 */
}
}
}
}

Binary file not shown.

View file

@ -13,8 +13,10 @@
#include "l4d_survivor_identity_fix.inc"
static ArrayList LasersUsed;
static ConVar hLaserNotice, hFinaleTimer, hFFNotice, hMPGamemode;
static ConVar hLaserNotice, hFinaleTimer, hFFNotice, hMPGamemode, hPingDropThres;
static int iFinaleStartTime, botDropMeleeWeapon[MAXPLAYERS+1];
static bool isHighPingIdle[MAXPLAYERS+1];
static Handle hTakeOverBot, hGoAwayFromKeyboard;
static float OUT_OF_BOUNDS[3] = {0.0, -1000.0, 0.0};
@ -41,10 +43,24 @@ public void OnPluginStart() {
SetFailState("This plugin is for L4D/L4D2 only.");
}
LoadTranslations("common.phrases");
Handle hConfig = LoadGameConfigFile("l4d2tools");
if(hConfig == INVALID_HANDLE) SetFailState("Could not load l4d2tools gamedata.");
StartPrepSDKCall(SDKCall_Player);
PrepSDKCall_SetFromConf(hConfig, SDKConf_Signature, "TakeOverBot");
hTakeOverBot = EndPrepSDKCall();
StartPrepSDKCall(SDKCall_Player);
PrepSDKCall_SetFromConf(hConfig, SDKConf_Signature, "GoAwayFromKeyboard");
hGoAwayFromKeyboard = EndPrepSDKCall();
CloseHandle(hConfig);
if(hTakeOverBot == INVALID_HANDLE || hGoAwayFromKeyboard == INVALID_HANDLE) {
SetFailState("One of 3 signatures is invalid");
}
hLaserNotice = CreateConVar("sm_laser_use_notice", "1.0", "Enable notification of a laser box being used", FCVAR_NONE, true, 0.0, true, 1.0);
hFinaleTimer = CreateConVar("sm_time_finale", "0.0", "Record the time it takes to complete finale. 0 -> OFF, 1 -> Gauntlets Only, 2 -> All finales", FCVAR_NONE, true, 0.0, true, 2.0);
hFFNotice = CreateConVar("sm_ff_notice", "0.0", "Notify players if a FF occurs. 0 -> Disabled, 1 -> In chat, 2 -> In Hint text", FCVAR_NONE, true, 0.0, true, 2.0);
hLaserNotice = CreateConVar("sm_laser_use_notice", "1.0", "Enable notification of a laser box being used", FCVAR_NONE, true, 0.0, true, 1.0);
hFinaleTimer = CreateConVar("sm_time_finale", "0.0", "Record the time it takes to complete finale. 0 -> OFF, 1 -> Gauntlets Only, 2 -> All finales", FCVAR_NONE, true, 0.0, true, 2.0);
hFFNotice = CreateConVar("sm_ff_notice", "0.0", "Notify players if a FF occurs. 0 -> Disabled, 1 -> In chat, 2 -> In Hint text", FCVAR_NONE, true, 0.0, true, 2.0);
hPingDropThres = CreateConVar("sm_autoidle_ping_max", "0.0", "The highest ping a player can have until they will automatically go idle.\n0=OFF, Min is 30", FCVAR_NONE, true, 30.0, true, 1000.0);
hMPGamemode = FindConVar("mp_gamemode");
hFFNotice.AddChangeHook(CVC_FFNotice);
@ -78,6 +94,29 @@ public void OnPluginStart() {
RegAdminCmd("sm_surv", Cmd_SetSurvivor, ADMFLAG_ROOT);
RegAdminCmd("sm_respawn_all", Command_RespawnAll, ADMFLAG_CHEATS, "Makes all dead players respawn in a closet");
RegConsoleCmd("sm_pmodels", Command_ListClientModels, "Lists all player's models");
CreateTimer(5.0, Timer_CheckPlayerPings, _, TIMER_REPEAT);
}
public Action Timer_CheckPlayerPings(Handle timer) {
//hPingDropThres
if(hPingDropThres.IntValue != 0) {
for (int i = 1; i <= MaxClients; i++ ) {
if(IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i) && IsPlayerAlive(i) && GetClientTeam(i) > 1) {
int ping = GetEntProp(GetPlayerResourceEntity(), Prop_Send, "m_iPing", _, i);
if(isHighPingIdle[i] && ping <= hPingDropThres.IntValue) {
SDKCall(hTakeOverBot, i);
isHighPingIdle[i] = false;
}else if(ping > hPingDropThres.IntValue) {
PrintToChat(i, "Due to your high ping (%d ms) you have been moved to AFK.", ping);
PrintToChat(i, "You will be automatically switched back once your ping restores");
SDKCall(hGoAwayFromKeyboard, i);
isHighPingIdle[i] = true;
}
}
}
}
return Plugin_Continue;
}
public void CVC_FFNotice(ConVar convar, const char[] oldValue, const char[] newValue) {
@ -428,4 +467,50 @@ stock int GetIdleBot(int client) {
}
}
return -1;
}
}
void GoIdle(int client, int onteam=0) {
Echo(2, "GoIdle: %d %d", client, onteam);
if (GetQRecord(client)) {
int spec_target;
// going from idle survivor to infected, leaves an icon behind
if (IsClientValid(g_target, 2, 0)) {
SwitchToBot(client, g_target);
}
if (g_onteam == 2) {
SwitchToSpec(client);
if (onteam == 0) {
SetHumanSpecSig(g_target, client);
}
if (onteam == 1) {
SwitchToSpec(client);
Unqueue(client);
}
AssignModel(g_target, g_model, g_IdentityFix);
}
else {
SwitchToSpec(client);
}
if (g_onteam == 3 && onteam <= 1) {
g_QRecord.SetString("model", "", true);
}
switch (IsClientValid(g_target, 0, 0)) {
case 1: spec_target = g_target;
case 0: spec_target = GetSafeSurvivor(client);
}
if (IsClientValid(spec_target)) {
SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", spec_target);
SetEntProp(client, Prop_Send, "m_iObserverMode", 5);
}
}
}