Advertisement
Guest User

SAM VS

a guest
Apr 19th, 2020
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 12.49 KB | None | 0 0
  1. #define PLUGIN_VERSION "1.2"
  2.  
  3. #pragma semicolon 1
  4. #include <sourcemod>
  5. #include <sdktools>
  6. #define debug 0
  7.  
  8. #define CHECK_TIME              5.0
  9. #define PRE_MAPCHANGE_COUNT 3
  10.  
  11. #define SOUND_SPECALERT     "buttons/bell1.wav" // default = "items/suitchargeok1.wav"
  12. #define SOUND_SPECMOVE      "npc/Soldier2/NAGS02.wav" // default = "items/suitchargeok1.wav"
  13. #define SOUND_SPECMOVE2     "npc/soldier/RadioNag01.wav" // default = "items/suitchargeok1.wav"
  14. #define SOUND_SPECMOVE3     "npc/Whitaker/Nags01.wav" // default = "items/suitchargeok1.wav"
  15. #define SOUND_SPECMOVE4     "npc/Whitaker/Nags05.wav" // default = "items/suitchargeok1.wav"
  16. #define SOUND_BACK              "npc/Soldier2/SURVIVORTALK02.wav" // default = "items/suitchargeok1.wav"
  17. #define SOUND_KICK              "UI/Menu_Enter05.wav" // default = "items/suitchargeok1.wav"
  18.  
  19. public Plugin:myinfo =
  20. {
  21.     name = "[L4D & L4D2] Simple AFK Manager VS",
  22.     author = "raziEiL [disawar1]",
  23.     description = "Players constantly take slot on your server? Plugin take care of them",
  24.     version = PLUGIN_VERSION,
  25.     url = "http://steamcommunity.com/id/raziEiL"
  26. }
  27.  
  28. native L4DReady_IsReadyMode();
  29. native IsInReady();
  30. native IsInPause();
  31. native L4D_IsFirstMapInScenario();
  32.  
  33. static  Float:g_fCvarKickT, g_iCvarAdmFlag, bool:g_bCvarImBack, g_iCvarSpecT, bool:g_bCvarTank, Handle:g_hTimer[MAXPLAYERS+1], Handle:g_hfwdOnClientAwake, Handle:g_hfwdOnClientAFK,
  34.         Float:g_fButtonTime[MAXPLAYERS+1], bool:g_bTempBlock[MAXPLAYERS+1], bool:g_bLeft4Dead2, bool:g_bLoadLate, bool:g_bCvarKickF, g_iRoundEnd;
  35.  
  36. public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
  37. {
  38.     // supports competitive mods
  39.     MarkNativeAsOptional("L4DReady_IsReadyMode");
  40.     MarkNativeAsOptional("IsInReady");
  41.     MarkNativeAsOptional("IsInPause");
  42.     MarkNativeAsOptional("L4D_IsFirstMapInScenario");
  43.     g_bLoadLate = late;
  44.  
  45.     return APLRes_Success;
  46. }
  47.  
  48. public OnPluginStart()
  49. {
  50.     decl String:sGameFolder[32];
  51.     GetGameFolderName(sGameFolder, 32);
  52.     g_bLeft4Dead2 = StrEqual(sGameFolder, "left4dead2");
  53.  
  54.     g_hfwdOnClientAwake = CreateGlobalForward("SAM_OnClientAwake", ET_Ignore, Param_Cell);
  55.     g_hfwdOnClientAFK = CreateGlobalForward("SAM_OnClientAFK", ET_Event, Param_Cell);
  56.  
  57.     CreateConVar("sam_vs_version", PLUGIN_VERSION, "Simple AFK Manager Versus plugin version", FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD);
  58.  
  59.     new Handle:hSpecT       = CreateConVar("sam_vs_spec_time",      "90", "Time before idle player will be moved to spectator in seconds", 0, true, 10.0);
  60.     new Handle:hKickT       = CreateConVar("sam_vs_kick_time",      "0", "Time before idle spectator player will be kicked in seconds. 0 = never kick", 0, true, 0.0);
  61.     new Handle:hImBack  = CreateConVar("sam_vs_respect_spec",   "1", "Don't kick spectators players if they is no longer AFK", 0, true, 0.0, true, 1.0);
  62.     new Handle:hTank        = CreateConVar("sam_vs_respect_tank",   "1", "Don't move AFK players to spectator if they playing as Tank", 0, true, 0.0, true, 1.0);
  63.     new Handle:hAdmin       = CreateConVar("sam_vs_respect_admins", "z", "Admins have immunity againts AFK manager. Flag value or empty \"\" to don't protect admins", 0);
  64.     new Handle:hKickF       = CreateConVar("sam_vs_force_kick",     "1", "Kicks all idle spectator players when map changes. (Requires for plugins compatibility that puts spec to spec after map change)", 0, true, 0.0, true, 1.0);
  65.     AutoExecConfig(true, "SimpleAFKManagerVs");
  66.  
  67.     decl String:sFlags[2];
  68.     GetConVarString(hAdmin, sFlags, 2);
  69.  
  70.     g_iCvarAdmFlag  = ReadFlagString(sFlags);
  71.     g_iCvarSpecT        = GetConVarInt(hSpecT);
  72.     g_fCvarKickT        = GetConVarFloat(hKickT);
  73.     g_bCvarImBack   = GetConVarBool(hImBack);
  74.     g_bCvarTank     = GetConVarBool(hTank);
  75.     g_bCvarKickF        = GetConVarBool(hKickF);
  76.  
  77.     HookConVarChange(hSpecT,    OnCvarChange_SpecT);
  78.     HookConVarChange(hKickT,    OnCvarChange_KickT);
  79.     HookConVarChange(hImBack,   OnCvarChange_ImBack);
  80.     HookConVarChange(hTank,     OnCvarChange_Tank);
  81.     HookConVarChange(hKickF,    OnCvarChange_KickF);
  82.     HookConVarChange(hAdmin,    OnCvarChange_Admin);
  83.  
  84.     HookEvent("player_team",    SAM_ev_PlayerTeam);
  85.     HookEvent("player_say", SAM_ev_PlayerSay);
  86.     HookEvent("round_end",  SAM_ev_RoundEnd, EventHookMode_PostNoCopy);
  87.  
  88.     CreateTimer(CHECK_TIME, SAM_t_CheckIdles, _, TIMER_REPEAT);
  89.  
  90.     if (g_bLoadLate)
  91.         for (new i = 1; i <= MaxClients; i++)
  92.             if (IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) != 1)
  93.                 SetEngineTime(i);
  94. }
  95.  
  96. public OnMapStart()
  97. {
  98.     g_iRoundEnd = 0;
  99.     PrecacheSound(SOUND_SPECALERT);
  100.     PrecacheSound(SOUND_SPECMOVE);
  101.     PrecacheSound(SOUND_SPECMOVE2);
  102.     PrecacheSound(SOUND_SPECMOVE3);
  103.     PrecacheSound(SOUND_SPECMOVE4);
  104.     PrecacheSound(SOUND_BACK);
  105.     PrecacheSound(SOUND_KICK);
  106.  
  107. }
  108.  
  109. public SAM_ev_RoundEnd(Handle:event, String:event_name[], bool:dontBroadcast)
  110. {
  111.     if (g_bCvarKickF && ++g_iRoundEnd == PRE_MAPCHANGE_COUNT){
  112.  
  113.         for (new i = 1; i <= MaxClients; i++)
  114.             if (g_hTimer[i] != INVALID_HANDLE)
  115.                 SAM_t_ActionKick(INVALID_HANDLE, i);
  116.     }
  117. }
  118.  
  119. public SAM_ev_PlayerSay(Handle:event, String:event_name[], bool:dontBroadcast)
  120. {
  121.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  122.     if (!client) return;
  123.  
  124.     if (GetClientTeam(client) != 1){
  125.  
  126.         #if debug
  127.             PrintToChatAll("[debug] %N chatting", client);
  128.         #endif
  129.  
  130.         SetEngineTime(client);
  131.     }
  132.     else
  133.         RespectSpecCheck(client);
  134. }
  135.  
  136. public Action:OnPlayerRunCmd(client, &buttons)
  137. {
  138.     if (buttons && !g_bTempBlock[client] && !IsFakeClient(client)){
  139.  
  140.         switch (GetClientTeam(client)){
  141.  
  142.             case 1:
  143.                 RespectSpecCheck(client);
  144.             case 2:
  145.                 if (IsPlayerAlive(client))
  146.                     SAM_PluseTime(client);
  147.             case 3:
  148.                 SAM_PluseTime(client);
  149.         }
  150.     }
  151. }
  152.  
  153. SAM_PluseTime(client)
  154. {
  155.     #if debug
  156.         PrintToChatAll("[debug] %N pressed a button (%d)", client, GetClientButtons(client));
  157.     #endif
  158.  
  159.     SetEngineTime(client);
  160.  
  161.     g_bTempBlock[client] = true;
  162.     CreateTimer(CHECK_TIME, SAM_t_Unlock, client);
  163. }
  164. public Action:SAM_t_Unlock(Handle:timer, any:client)
  165. {
  166.     g_bTempBlock[client] = false;
  167. }
  168. public Action:SAM_t_CheckIdles(Handle:timer, int client)
  169. {
  170.     static Float:fTheTime, bool:bRUP, bool:bPAUSE, bool:bFIRST, iTeam, Action:iResult, iSound;
  171.     fTheTime = GetEngineTime(), bRUP = false, bPAUSE = IsPauseActive(), bFIRST = IsFirstMap();
  172.  
  173.     #if debug
  174.         PrintToChatAll("[debug] SAM_t_CheckIdles()-> fired, RUP = %b!", bRUP);
  175.     #endif
  176.  
  177.     for (new i = 1; i <= MaxClients; i++){
  178.  
  179.         if (bRUP && IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) != 1){
  180.  
  181.             g_fButtonTime[i] = fTheTime;
  182.             continue;
  183.         }
  184.  
  185.         if (bPAUSE && IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) != 1){
  186.  
  187.             g_fButtonTime[i] = fTheTime;
  188.             continue;
  189.         }
  190.  
  191.         if (bFIRST && !GameRules_GetProp("m_bInSecondHalfOfRound") && IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) != 1){
  192.  
  193.             g_fButtonTime[i] = fTheTime;
  194.             continue;
  195.         }
  196.  
  197.         if (g_fButtonTime[i] && (fTheTime - g_fButtonTime[i]) > g_iCvarSpecT){
  198.  
  199.             if (IsClientInGame(i) && (iTeam = GetClientTeam(i)) != 1){
  200.  
  201.                 if (IsPlayerBussy(i, iTeam) || g_bCvarTank && iTeam == 3 && IsPlayerTank(i)){
  202.  
  203.                     #if debug
  204.                         PrintToChatAll("[debug] SAM_t_CheckIdles()-> %N are bussy/tank. We skip him...", i);
  205.                     #endif
  206.  
  207.                     g_fButtonTime[i] = fTheTime;
  208.                     continue;
  209.                 }
  210.  
  211.                 Call_StartForward(g_hfwdOnClientAFK);
  212.                 Call_PushCell(i);
  213.                 Call_Finish(iResult);
  214.  
  215.                 if (iResult == Plugin_Handled){
  216.  
  217.                     g_fButtonTime[i] = fTheTime;
  218.                     continue;
  219.                 }
  220.  
  221.                 ChangeClientTeam(i, 1);
  222.  
  223.                 EmitSoundToAll(SOUND_SPECALERT);
  224.  
  225.                 iSound = GetRandomInt( 1, 4 );
  226.                 switch (iSound)
  227.                 {
  228.                     case 1: // if is 1
  229.                     {
  230.                         EmitSoundToAll(SOUND_SPECMOVE);
  231.                     }
  232.                     case 2: // if is 2
  233.                     {
  234.                         EmitSoundToAll(SOUND_SPECMOVE2);
  235.                     }
  236.           case 3: // ...
  237.                     {
  238.                         EmitSoundToAll(SOUND_SPECMOVE3);
  239.                     }
  240.                     case 4: // ...
  241.                     {
  242.                         EmitSoundToAll(SOUND_SPECMOVE4);
  243.                     }
  244.                 }
  245.  
  246.                 PrintToChatAll("[AFK Manager] %N moved to spec (Was AFK for %.1fsec)", i, fTheTime - g_fButtonTime[i]);
  247.                 PrintToChatAll("[AFK Manager] If %N does not return soon, they will be kicked and lose their spot in the game.", i);
  248.  
  249.                 if (bWhoAmI(i) || !g_fCvarKickT) continue;
  250.  
  251.                 g_hTimer[i] = CreateTimer(g_fCvarKickT, SAM_t_ActionKick, i, TIMER_FLAG_NO_MAPCHANGE);
  252.  
  253.                 #if debug
  254.                     PrintToChatAll("[debug] SAM_t_CheckIdles()-> %N AFK, timer %x hndl", i, g_hTimer[i]);
  255.                 #endif
  256.             }
  257.             else
  258.                 g_fButtonTime[i] = 0.0;
  259.         }
  260.     }
  261. }
  262.  
  263. public OnClientDisconnect(client)
  264. {
  265.     if (client){
  266.  
  267.         SAM_TimeToKill(client);
  268.         g_fButtonTime[client] = 0.0;
  269.     }
  270. }
  271.  
  272. public SAM_ev_PlayerTeam(Handle:event, String:event_name[], bool:dontBroadcast)
  273. {
  274.     if (GetEventBool(event, "disconnect")) return;
  275.  
  276.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  277.  
  278.     if (client && !IsFakeClient(client) && GetEventInt(event, "team") != 1){
  279.  
  280.         SAM_TimeToKill(client);
  281.         SetEngineTime(client);
  282.     }
  283. }
  284.  
  285. SAM_TimeToKill(client)
  286. {
  287.     if (g_hTimer[client] != INVALID_HANDLE){
  288.  
  289.         #if debug
  290.             PrintToChatAll("[debug] SAM_TimeToKill(%N)-> Kill %x timer hndl", client, g_hTimer[client]);
  291.         #endif
  292.  
  293.         KillTimer(g_hTimer[client]);
  294.         g_hTimer[client] = INVALID_HANDLE;
  295.     }
  296. }
  297.  
  298. public Action:SAM_t_ActionKick(Handle:timer, any:client)
  299. {
  300.     #if debug
  301.         PrintToChatAll("[debug] SAM_t_ActionKick(%N) Kick player", client);
  302.     #endif
  303.  
  304.     if (IsClientInGame(client) && !bWhoAmI(client)) {
  305.         EmitSoundToAll(SOUND_KICK);
  306.         KickClient(client, "You were kicked for being AFK too long. You have lost your spot in the game.");
  307.     }
  308.     g_hTimer[client] = INVALID_HANDLE;
  309. }
  310.  
  311. SetEngineTime(client)
  312. {
  313.     g_fButtonTime[client] = GetEngineTime();
  314. }
  315.  
  316. RespectSpecCheck(client)
  317. {
  318.     if (g_bCvarImBack && g_hTimer[client] != INVALID_HANDLE){
  319.  
  320.         SAM_TimeToKill(client);
  321.  
  322.         Call_StartForward(g_hfwdOnClientAwake);
  323.         Call_PushCell(client);
  324.         Call_Finish();
  325.  
  326.         EmitSoundToAll(SOUND_BACK);
  327.         PrintToChatAll("[AFK Manager] %N is no longer AFK.", client);
  328.  
  329.     }
  330. }
  331.  
  332. bool:IsReadyUpActive()
  333. {
  334.     return !IsServerProcessing() || (GetFeatureStatus(FeatureType_Native, "L4DReady_IsReadyMode") == FeatureStatus_Available && L4DReady_IsReadyMode() || GetFeatureStatus(FeatureType_Native, "IsInReady") == FeatureStatus_Available && IsInReady());
  335. }
  336. bool:IsPauseActive()
  337. {
  338.     return !IsServerProcessing() || (GetFeatureStatus(FeatureType_Native, "IsInPause") == FeatureStatus_Available && IsInPause());
  339. }
  340. bool:IsFirstMap()
  341. {
  342.     return !IsServerProcessing() || (GetFeatureStatus(FeatureType_Native, "L4D_IsFirstMapInScenario") == FeatureStatus_Available && L4D_IsFirstMapInScenario());
  343. }
  344.  
  345. bool:IsPlayerTank(client)
  346. {
  347.     return GetEntProp(client, Prop_Send, "m_zombieClass") == (g_bLeft4Dead2 ? 8 : 5);
  348. }
  349.  
  350. bool:IsPlayerBussy(client, team)
  351. {
  352.     return team == 2 && (!IsPlayerAlive(client) || IsSurvivorBussy(client) || GetEntProp(client, Prop_Send, "m_isIncapacitated") || GetEntProp(client, Prop_Send, "m_isHangingFromLedge")) ||
  353.         (GetEntProp(client, Prop_Send, "m_iHealth") == 1 || IsInfectedBussy(client));
  354. }
  355.  
  356. bool:IsSurvivorBussy(client)
  357. {
  358.     return GetEntProp(client, Prop_Send, "m_tongueOwner") > 0 || GetEntProp(client, Prop_Send, "m_pounceAttacker") > 0 || g_bLeft4Dead2 && (GetEntProp(client, Prop_Send, "m_pummelAttacker") > 0 || GetEntProp(client, Prop_Send, "m_jockeyAttacker") > 0);
  359. }
  360.  
  361. bool:IsInfectedBussy(client)
  362. {
  363.     return GetEntProp(client, Prop_Send, "m_tongueVictim") > 0 || GetEntProp(client, Prop_Send, "m_pounceVictim") > 0 || g_bLeft4Dead2 && (GetEntProp(client, Prop_Send, "m_pummelVictim") > 0 || GetEntProp(client, Prop_Send, "m_jockeyVictim") > 0);
  364. }
  365.  
  366. bool:bWhoAmI(client)
  367. {
  368.     return g_iCvarAdmFlag && GetUserFlagBits(client) && CheckCommandAccess(client, "", g_iCvarAdmFlag);
  369. }
  370.  
  371. public OnCvarChange_SpecT(Handle:hConVar, const String:sOldVal[], const String:sNewVal[])
  372. {
  373.     if (!StrEqual(sOldVal, sNewVal))
  374.         g_iCvarSpecT = GetConVarInt(hConVar);
  375. }
  376.  
  377. public OnCvarChange_KickT(Handle:hConVar, const String:sOldVal[], const String:sNewVal[])
  378. {
  379.     if (!StrEqual(sOldVal, sNewVal))
  380.         g_fCvarKickT = GetConVarFloat(hConVar);
  381. }
  382.  
  383. public OnCvarChange_ImBack(Handle:hConVar, const String:sOldVal[], const String:sNewVal[])
  384. {
  385.     if (!StrEqual(sOldVal, sNewVal))
  386.         g_bCvarImBack = GetConVarBool(hConVar);
  387. }
  388.  
  389. public OnCvarChange_Tank(Handle:hConVar, const String:sOldVal[], const String:sNewVal[])
  390. {
  391.     if (!StrEqual(sOldVal, sNewVal))
  392.         g_bCvarTank = GetConVarBool(hConVar);
  393. }
  394.  
  395. public OnCvarChange_KickF(Handle:hConVar, const String:sOldVal[], const String:sNewVal[])
  396. {
  397.     if (!StrEqual(sOldVal, sNewVal))
  398.         g_bCvarKickF = GetConVarBool(hConVar);
  399. }
  400.  
  401. public OnCvarChange_Admin(Handle:hConVar, const String:sOldVal[], const String:sNewVal[])
  402. {
  403.     if (!StrEqual(sOldVal, sNewVal)){
  404.  
  405.         decl String:sFlags[2];
  406.         GetConVarString(hConVar, sFlags, 2);
  407.         g_iCvarAdmFlag = ReadFlagString(sFlags);
  408.     }
  409. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement