Skip to content

Commit

Permalink
v0.0.4
Browse files Browse the repository at this point in the history
- Added verification for those who stay at SPEC.
  • Loading branch information
NiGHT757 committed Nov 9, 2023
1 parent 463f82a commit e3661c8
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 85 deletions.
206 changes: 127 additions & 79 deletions AFKManager/AFKManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
namespace AFKManager;
public class AFKManager : BasePlugin
{
#region definitions
public override string ModuleAuthor => "NiGHT & K4ryuu";
public override string ModuleName => "AFK Manager";
public override string ModuleVersion => "0.0.3";
public override string ModuleVersion => "0.0.4";
public static string Directory = string.Empty;
private CCSGameRules? g_GameRulesProxy = null;

Expand All @@ -18,9 +19,13 @@ private class PlayerAbsOrigin
public QAngle Angles { get; set; }
public Vector Origin { get; set; }
public int WarningCount { get; set; }
public bool Whitelisted { get; set; }
public int SpecWarningCount { get; set; }
public Whitelist? Whitelisted { get; set; }
public float fAfkTime { get; set; }
}

private PlayerAbsOrigin[] g_PlayerAbsOrigin = new PlayerAbsOrigin[Server.MaxPlayers + 1];
#endregion
public override void Load(bool hotReload)
{
Directory = ModuleDirectory;
Expand All @@ -33,6 +38,7 @@ public override void Load(bool hotReload)
g_GameRulesProxy = null;
});

#region OnClientConnected
RegisterListener<Listeners.OnClientConnected>(playerSlot =>
{
int finalSlot = playerSlot + 1;
Expand All @@ -46,14 +52,20 @@ public override void Load(bool hotReload)
{
Angles = new QAngle(),
Origin = new Vector(),
Whitelisted = false,
Whitelisted = null,
SpecWarningCount = 0,
fAfkTime = 0,
WarningCount = 0
};
}
g_PlayerAbsOrigin[finalSlot].Whitelisted = CFG.config.WhiteListUsers.Contains(player.SteamID);
if (CFG.config.WhiteListUsers.ContainsKey(player.SteamID))
{
g_PlayerAbsOrigin[finalSlot].Whitelisted = CFG.config.WhiteListUsers[player.SteamID];
}
});

#endregion
#region hotReload
if (hotReload)
{
AddTimer(1.0f, () =>
Expand All @@ -73,15 +85,20 @@ public override void Load(bool hotReload)
{
Angles = new QAngle(),
Origin = new Vector(),
Whitelisted = false,
Whitelisted = null,
SpecWarningCount = 0,
fAfkTime = 0,
WarningCount = 0
};
}
g_PlayerAbsOrigin[i].Whitelisted = CFG.config.WhiteListUsers.Contains(player.SteamID);
if(CFG.config.WhiteListUsers.ContainsKey(player.SteamID))
{
g_PlayerAbsOrigin[i].Whitelisted = CFG.config.WhiteListUsers[player.SteamID];
}
}
});
}
#endregion
}

private void AfkTimer_Callback()
Expand All @@ -102,107 +119,138 @@ private void AfkTimer_Callback()
for (int i = 1; i <= Server.MaxPlayers; i++)
{
CCSPlayerController player = Utilities.GetPlayerFromIndex(i);
if (g_PlayerAbsOrigin[i] == null || g_PlayerAbsOrigin[i].Whitelisted || !player.IsValid || player.IsBot || player.ControllingBot || !player.PawnIsAlive || player.TeamNum < 2 || player.TeamNum > 3)
{
if (g_PlayerAbsOrigin[i] == null || !player.IsValid || player.IsBot || player.ControllingBot)
continue;
}

var playerPawn = player.PlayerPawn.Value;
var playerFlags = player.Pawn.Value.Flags;

if ((playerFlags & ((uint)PlayerFlags.FL_ONGROUND | (uint)PlayerFlags.FL_FROZEN)) != (uint)PlayerFlags.FL_ONGROUND)
#region AFK Time
if (!g_PlayerAbsOrigin[i].Whitelisted.SkipAFK && player.PawnIsAlive && (player.TeamNum == 2 || player.TeamNum == 3))
{
continue;
}
g_PlayerAbsOrigin[i].SpecWarningCount = 0;
g_PlayerAbsOrigin[i].fAfkTime = 0;

QAngle angles = playerPawn.EyeAngles;
Vector origin = player.PlayerPawn.Value.CBodyComponent?.SceneNode?.AbsOrigin;
var playerPawn = player.PlayerPawn.Value;
var playerFlags = player.Pawn.Value.Flags;

if (g_PlayerAbsOrigin[i].Angles.X == angles.X && g_PlayerAbsOrigin[i].Angles.Y == angles.Y &&
g_PlayerAbsOrigin[i].Origin.X == origin.X && g_PlayerAbsOrigin[i].Origin.Y == origin.Y)
{
string sFormat = null;
if (g_PlayerAbsOrigin[i].WarningCount == CFG.config.Warnings)
if ((playerFlags & ((uint)PlayerFlags.FL_ONGROUND | (uint)PlayerFlags.FL_FROZEN)) != (uint)PlayerFlags.FL_ONGROUND)
{
g_PlayerAbsOrigin[i].WarningCount = 0;
continue;
}

QAngle angles = playerPawn.EyeAngles;
Vector origin = player.PlayerPawn.Value.CBodyComponent?.SceneNode?.AbsOrigin;

if (g_PlayerAbsOrigin[i].Angles.X == angles.X && g_PlayerAbsOrigin[i].Angles.Y == angles.Y &&
g_PlayerAbsOrigin[i].Origin.X == origin.X && g_PlayerAbsOrigin[i].Origin.Y == origin.Y)
{
string sFormat = null;
if (g_PlayerAbsOrigin[i].WarningCount == CFG.config.Warnings)
{
g_PlayerAbsOrigin[i].WarningCount = 0;

switch (CFG.config.Punishment)
{
case 0:
sFormat = CFG.config.ChatKillMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);

playerPawn.CommitSuicide(false, true);
Server.PrintToChatAll(sFormat);
break;
case 1:
sFormat = CFG.config.ChatMoveMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);

playerPawn.CommitSuicide(false, true);
var changeTeam = VirtualFunction.CreateVoid<IntPtr, CsTeam>(player.Handle, CFG.config.Offset);
changeTeam(player.Handle, CsTeam.Spectator);

Server.PrintToChatAll(sFormat);
break;
case 2:
sFormat = CFG.config.ChatKickMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);

Server.ExecuteCommand($"kickid {player.UserId}");
Server.PrintToChatAll(sFormat);
break;
}

continue;
}

switch (CFG.config.Punishment)
{
case 0:
sFormat = CFG.config.ChatKillMessage;
sFormat = CFG.config.ChatWarningKillMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);
sFormat = sFormat.Replace("{time}", $"{(((float)CFG.config.Warnings * CFG.config.Timer) - ((float)g_PlayerAbsOrigin[i].WarningCount * CFG.config.Timer)):F1}");

playerPawn.CommitSuicide(false, true);
Server.PrintToChatAll(sFormat);
player.PrintToChat(sFormat);
break;
case 1:
sFormat = CFG.config.ChatMoveMessage;
sFormat = CFG.config.ChatWarningMoveMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);
sFormat = sFormat.Replace("{time}", $"{(((float)CFG.config.Warnings * CFG.config.Timer) - ((float)g_PlayerAbsOrigin[i].WarningCount * CFG.config.Timer)):F1}");

playerPawn.CommitSuicide(false, true);
var changeTeam = VirtualFunction.CreateVoid<IntPtr, CsTeam>(player.Handle, CFG.config.Offset);
changeTeam(player.Handle, CsTeam.Spectator);

Server.PrintToChatAll(sFormat);
player.PrintToChat(sFormat);
break;
case 2:
sFormat = CFG.config.ChatKickMessage;
sFormat = CFG.config.ChatWarningKickMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);
sFormat = sFormat.Replace("{time}", $"{(((float)CFG.config.Warnings * CFG.config.Timer) - ((float)g_PlayerAbsOrigin[i].WarningCount * CFG.config.Timer)):F1}");

Server.ExecuteCommand($"kickid {player.UserId}");
Server.PrintToChatAll(sFormat);
player.PrintToChat(sFormat);
break;
}

continue;
g_PlayerAbsOrigin[i].WarningCount++;
}
else
g_PlayerAbsOrigin[i].WarningCount = 0;

g_PlayerAbsOrigin[i].Angles = new QAngle(
x: angles.X,
y: angles.Y,
z: angles.Z
);

g_PlayerAbsOrigin[i].Origin = new Vector(
x: origin.X,
y: origin.Y,
z: origin.Z
);

switch (CFG.config.Punishment)
continue;
}
#endregion
#region SPEC Time
if (!g_PlayerAbsOrigin[i].Whitelisted.SkipSPEC && player.TeamNum == 1)
{
g_PlayerAbsOrigin[i].fAfkTime += CFG.config.Timer;

if (g_PlayerAbsOrigin[i].fAfkTime >= CFG.config.SpecWarnPlayerEveryXSeconds) // for example, warn player every 20 seconds ( add +1 warn every 20 sec )
{
case 0:
sFormat = CFG.config.ChatWarningKillMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);
sFormat = sFormat.Replace("{time}", $"{(((float)CFG.config.Warnings * CFG.config.Timer) - ((float)g_PlayerAbsOrigin[i].WarningCount * CFG.config.Timer)):F1}");

player.PrintToChat(sFormat);
break;
case 1:
sFormat = CFG.config.ChatWarningMoveMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);
sFormat = sFormat.Replace("{time}", $"{(((float)CFG.config.Warnings * CFG.config.Timer) - ((float)g_PlayerAbsOrigin[i].WarningCount * CFG.config.Timer)):F1}");

player.PrintToChat(sFormat);
break;
case 2:
sFormat = CFG.config.ChatWarningKickMessage;
sFormat = sFormat.Replace("{chatprefix}", CFG.config.ChatPrefix);
sFormat = sFormat.Replace("{playername}", player.PlayerName);
sFormat = sFormat.Replace("{time}", $"{(((float)CFG.config.Warnings * CFG.config.Timer) - ((float)g_PlayerAbsOrigin[i].WarningCount * CFG.config.Timer)):F1}");

player.PrintToChat(sFormat);
break;
if (g_PlayerAbsOrigin[i].SpecWarningCount == CFG.config.SpecKickPlayerAfterXWarnings)
{
Server.ExecuteCommand($"kickid {player.UserId}");

g_PlayerAbsOrigin[i].SpecWarningCount = 0;
g_PlayerAbsOrigin[i].fAfkTime = 0; // reset counter
continue;
}

player.PrintToChat($"{CFG.config.ChatPrefix} You\'re Idle/ AFK. Move or you\'ll be kicked in {(((float)CFG.config.SpecKickPlayerAfterXWarnings * CFG.config.SpecWarnPlayerEveryXSeconds) - ((float)g_PlayerAbsOrigin[i].SpecWarningCount * CFG.config.SpecWarnPlayerEveryXSeconds)):F1} seconds.");
g_PlayerAbsOrigin[i].SpecWarningCount++;
g_PlayerAbsOrigin[i].fAfkTime = 0; // reset counter
}
g_PlayerAbsOrigin[i].WarningCount++;
}
else
g_PlayerAbsOrigin[i].WarningCount = 0;

g_PlayerAbsOrigin[i].Angles = new QAngle(
x: angles.X,
y: angles.Y,
z: angles.Z
);

g_PlayerAbsOrigin[i].Origin = new Vector(
x: origin.X,
y: origin.Y,
z: origin.Z
);

#endregion
}
}
}
34 changes: 28 additions & 6 deletions AFKManager/CFG.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
using CounterStrikeSharp.API.Modules.Utils;
using System.Reflection;
using System.Text.Json;
using System.Xml;

namespace AFKManager;

internal class CFG
{
public static Config config = new();

public void CheckConfig(string moduleDirectory)
public void CheckConfig(string moduleDirectory)
{
string path = Path.Join(moduleDirectory, "config.json");

Expand Down Expand Up @@ -74,14 +75,20 @@ private static void CreateAndWriteFile(string path)

Config config = new Config
{
WhiteListUsers = new List<ulong>() { 76561198143759075 },
ChatPrefix = "[{LightRed}AFK{Default}]",
// create dictionary with default values
WhiteListUsers = new Dictionary<ulong, Whitelist>()
{
{ 76561198143759075, new Whitelist { SkipAFK = true, SkipSPEC = false } }
},
ChatPrefix = "[{LightRed}AFK{Default}]",
ChatMoveMessage = "{chatprefix} {playername} was moved to SPEC being AFK.",
ChatKillMessage = "{chatprefix} {playername} was killed for being AFK.",
ChatKillMessage = "{chatprefix} {playername} was killed for being AFK.",
ChatKickMessage = "{chatprefix} {playername} was kicked for being AFK.",
ChatWarningKickMessage = "{chatprefix} You\'re{LightRed} Idle/ AFK{Default}. Move or you\'ll be kicked in {Darkred}{time}{Default} seconds.",
ChatWarningKickMessage = "{chatprefix} You\'re{LightRed} Idle/ AFK{Default}. Move or you\'ll be kicked in {Darkred}{time}{Default} seconds.",
ChatWarningMoveMessage = "{chatprefix} You\'re{LightRed} Idle/ AFK{Default}. Move or you\'ll be moved to SPEC in {Darkred}{time}{Default} seconds.",
ChatWarningKillMessage = "{chatprefix} You\'re{LightRed} Idle/ AFK{Default}. Move or you\'ll killed in {Darkred}{time}{Default} seconds.",
SpecWarnPlayerEveryXSeconds = 20,
SpecKickPlayerAfterXWarnings = 5,
Warnings = 3,
Punishment = 1,
Timer = 5.0f,
Expand Down Expand Up @@ -116,10 +123,17 @@ private string ModifyColorValue(string msg)
return string.IsNullOrEmpty(msg) ? "[AFK]" : msg;
}
}
// Add some default random values to WhiteListUsers dictionary
// WhiteListUsers = new Dictionary<
// ulong, Whitelist>() { 76561198143759075, new Whitelist { SkipAFK = true, SkipSPEC = false } },
// 76561198143759075, new Whitelist { SkipAFK = false, SkipSPEC = true } },
// 76561198143759075, new Whitelist { SkipAFK = true, SkipSPEC = true } },
// 76561198143759075, new Whitelist { SkipAFK = false, SkipSPEC = false } },
// 76561198143759075, new Whitelist { SkipAFK = true, SkipSPEC = false } },

internal class Config
{
public List<ulong> WhiteListUsers { get; set; }
public Dictionary<ulong, Whitelist> WhiteListUsers { get; set; }
public string? ChatPrefix { get; set; }
public string? ChatKickMessage { get; set; }
public string? ChatMoveMessage { get; set; }
Expand All @@ -130,6 +144,14 @@ internal class Config

public int Warnings { get; set; }
public int Punishment { get; set; }
public int SpecWarnPlayerEveryXSeconds { get; set; }
public int SpecKickPlayerAfterXWarnings { get; set; }
public float Timer { get; set; }
public int Offset { get; set; }
}

public class Whitelist
{
public bool SkipAFK { get; set; }
public bool SkipSPEC { get; set; }
}

0 comments on commit e3661c8

Please sign in to comment.