using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Plugin.Host;
using CounterStrikeSharp.API.Core.Translations;
using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using CounterStrikeSharp.API.ValveConstants.Protobuf;
using CS2_SimpleAdmin.Managers;
using CS2_SimpleAdminApi;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using ZLinq;
namespace CS2_SimpleAdmin;
internal static class Helper
{
private static readonly string AssemblyName = Assembly.GetExecutingAssembly().GetName().Name ?? "";
private static readonly string CfgPath = $"{Server.GameDirectory}/csgo/addons/counterstrikesharp/configs/plugins/{AssemblyName}/{AssemblyName}.json";
private delegate nint CNetworkSystemUpdatePublicIp(nint a1);
private static CNetworkSystemUpdatePublicIp? _networkSystemUpdatePublicIp;
public static bool IsDebugBuild
{
get
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
public static string GetCallerName(CCSPlayerController? caller)
{
if (caller != null && !string.IsNullOrEmpty(caller.PlayerName))
{
return caller.PlayerName;
}
return CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console";
}
public static string GetReasonOrUnknown(string? reason)
{
if (!string.IsNullOrWhiteSpace(reason))
{
return reason;
}
return CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown";
}
///
/// Joins the command arguments from on as the penalty reason, "Unknown" when blank.
///
public static string GetArgsReason(CommandInfo command, int firstArg)
{
string reason = string.Empty;
if (command.ArgCount > firstArg)
{
reason = string.Join(" ", Enumerable.Range(firstArg, command.ArgCount - firstArg).Select(command.GetArg)).Trim();
}
return GetReasonOrUnknown(reason);
}
public static PlayerInfo? GetAdminInfo(CCSPlayerController? caller)
{
if (caller == null || !caller.UserId.HasValue)
{
return null;
}
return CS2_SimpleAdmin.PlayersInfo[caller.SteamID];
}
public static string GetLogName(CCSPlayerController player)
{
if (string.IsNullOrEmpty(player.PlayerName))
{
return player.SteamID.ToString();
}
return player.PlayerName;
}
public static string Truncate(string value, int maxLength)
{
if (value.Length > maxLength)
{
return value[..maxLength];
}
return value;
}
public static bool HasCommandPermission(CCSPlayerController admin, string command, string defaultFlag)
{
SteamID steamId = new SteamID(admin.SteamID);
if (AdminManager.CommandIsOverriden(command))
{
return AdminManager.PlayerHasPermissions(steamId, AdminManager.GetPermissionOverrides(command));
}
return AdminManager.PlayerHasPermissions(steamId, defaultFlag);
}
public static List GetPlayerFromName(string name)
{
return GetValidPlayers().FindAll(x => x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase));
}
public static CCSPlayerController? GetPlayerFromSteamid64(ulong steamid)
{
return GetValidPlayers().FirstOrDefault(x => x.SteamID == steamid);
}
public static List GetPlayerFromIp(string ipAddress)
{
return CS2_SimpleAdmin.CachedPlayers.FindAll(x => x.IpAddress != null && x.IpAddress.Split(":")[0].Equals(ipAddress));
}
public static List GetValidPlayers()
{
return CS2_SimpleAdmin.CachedPlayers.AsValueEnumerable().Where(p => p.IsValid && p.Connected == PlayerConnectedState.Connected).ToList();
}
public static List GetValidPlayersWithBots()
{
return CS2_SimpleAdmin.CachedPlayers.Concat(CS2_SimpleAdmin.BotPlayers).AsValueEnumerable().ToList();
}
// public static bool IsValidSteamId64(string input)
// {
// const string pattern = @"^\d{17}$";
// return Regex.IsMatch(input, pattern);
// }
public static bool ValidateSteamId(string input, out SteamID? steamId)
{
steamId = null;
if (string.IsNullOrEmpty(input))
{
return false;
}
if (!SteamID.TryParse(input, out SteamID? parsedSteamId))
{
return false;
}
steamId = parsedSteamId;
return true;
}
public static bool IsValidIp(string input)
{
const string pattern = @"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
return Regex.IsMatch(input, pattern);
}
public static void GivePlayerFlags(SteamID? steamid, List? flags = null, uint immunity = 0)
{
try
{
if (steamid == null || (flags == null && immunity == 0))
{
return;
}
if (flags == null)
{
return;
}
foreach (string? flag in flags.Where(flag => !string.IsNullOrEmpty(flag)))
{
if (flag.StartsWith($"@"))
{
//Console.WriteLine($"Adding permission {flag} to SteamID {steamid}");
AdminManager.AddPlayerPermissions(steamid, flag);
}
else if (flag.StartsWith($"#"))
{
//Console.WriteLine($"Adding SteamID {steamid} to group {flag}");
AdminManager.AddPlayerToGroup(steamid, flag);
}
}
AdminManager.SetPlayerImmunity(steamid, immunity);
}
catch
{
}
}
public static void KickPlayer(int userId, NetworkDisconnectionReason reason = NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKED, int delay = 0)
{
CCSPlayerController? player = Utilities.GetPlayerFromUserid(userId);
if (player == null || !player.IsValid || player.IsHLTV)
{
return;
}
if (player.UserId.HasValue && CS2_SimpleAdmin.PlayersInfo.TryGetValue(player.SteamID, out PlayerInfo? value))
{
value.WaitingForKick = true;
}
// player.CommitSuicide(true, true);
player.VoiceFlags = VoiceFlags.Muted;
CCSPlayerPawn? playerPawn = player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.LifeState == (int)LifeState_t.LIFE_ALIVE)
{
playerPawn.Freeze();
playerPawn.Colorize(255, 0, 0);
CPlayer_WeaponServices? weaponServices = playerPawn.WeaponServices;
if (weaponServices == null)
{
return;
}
foreach (CHandle _weap in weaponServices.MyWeapons)
{
CBasePlayerWeapon? weapon = _weap.Value; ;
if (weapon == null || !weapon.IsValid)
{
continue;
}
if (weapon.DesignerName.Contains("c4") || weapon.DesignerName.Contains("healthshot"))
{
continue;
}
weapon.NextPrimaryAttackTick = Server.TickCount + 999;
weapon.NextSecondaryAttackTick = Server.TickCount + 999;
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick");
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick");
}
}
if (delay > 0)
{
CS2_SimpleAdmin.Instance.AddTimer(delay, () =>
{
if (!player.IsValid || player.IsHLTV)
{
return;
}
// Server.ExecuteCommand($"kickid {player.UserId}");
playerPawn?.Colorize();
player.Disconnect(reason);
});
}
else
{
// Server.ExecuteCommand($"kickid {player.UserId}");
playerPawn?.Colorize();
player.Disconnect(reason);
}
if (CS2_SimpleAdmin.UnlockedCommands && reason == NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED)
{
Server.ExecuteCommand($"banid 1 {new SteamID(player.SteamID).SteamId3}");
}
// if (!string.IsNullOrEmpty(reason))
// {
// var escapeChars = reason.IndexOfAny([';', '|']);
//
// if (escapeChars != -1)
// {
// reason = reason[..escapeChars];
// }
// }
//
// Server.ExecuteCommand($"kickid {userId} {reason}");
}
public static void KickPlayer(CCSPlayerController player, NetworkDisconnectionReason reason = NetworkDisconnectionReason.NETWORK_DISCONNECT_KICKED, int delay = 0)
{
if (!player.IsValid || player.IsHLTV)
{
return;
}
if (CS2_SimpleAdmin.PlayersInfo.TryGetValue(player.SteamID, out PlayerInfo? value))
{
if (value.WaitingForKick)
{
return;
}
value.WaitingForKick = true;
}
player.VoiceFlags = VoiceFlags.Muted;
CCSPlayerPawn? playerPawn = player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.LifeState == (int)LifeState_t.LIFE_ALIVE)
{
playerPawn.Freeze();
playerPawn.Colorize(255, 0, 0);
CPlayer_WeaponServices? weaponServices = playerPawn.WeaponServices;
if (weaponServices == null)
{
return;
}
foreach (CHandle _weap in weaponServices.MyWeapons)
{
CBasePlayerWeapon? weapon = _weap.Value;
;
if (weapon == null || !weapon.IsValid)
{
continue;
}
if (weapon.DesignerName.Contains("c4") || weapon.DesignerName.Contains("healthshot"))
{
continue;
}
weapon.NextPrimaryAttackTick = Server.TickCount + 999;
weapon.NextSecondaryAttackTick = Server.TickCount + 999;
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick");
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick");
}
}
if (delay > 0)
{
CS2_SimpleAdmin.Instance.AddTimer(delay, () =>
{
if (!player.IsValid || player.IsHLTV)
{
return;
}
// if (!string.IsNullOrEmpty(reason))
// {
// var escapeChars = reason.IndexOfAny([';', '|']);
//
// if (escapeChars != -1)
// {
// reason = reason[..escapeChars];
// }
// }
//
// Server.ExecuteCommand($"kickid {player.UserId}");
player.Disconnect(reason);
});
}
else
{
// Server.ExecuteCommand($"kickid {player.UserId}");
player.Disconnect(reason);
}
if (CS2_SimpleAdmin.UnlockedCommands && reason == NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED)
{
Server.ExecuteCommand($"banid 1 {new SteamID(player.SteamID).SteamId3}");
}
// if (!string.IsNullOrEmpty(reason))
// {
// var escapeChars = reason.IndexOfAny([';', '|']);
//
// if (escapeChars != -1)
// {
// reason = reason[..escapeChars];
// }
// }
//
// Server.ExecuteCommand($"kickid {userId} {reason}");
}
public static int ParsePenaltyTime(string time)
{
time = time.ToLower();
if (string.IsNullOrWhiteSpace(time) || !time.Any(char.IsDigit))
{
// CS2_SimpleAdmin._logger?.LogError("Time string cannot be null or empty.");
return -1;
}
if (time.Equals($"0"))
{
return 0;
}
Dictionary timeUnits = new Dictionary
{
{ "m", 1 }, // Minute
{ "h", 60 }, // Hour
{ "d", 1440 }, // Day (24 * 60)
{ "w", 10080 }, // Week (7 * 24 * 60)
{ "mo", 43200 }, // Month (30 * 24 * 60)
{ "y", 525600 } // Year (365 * 24 * 60)
};
// Check if the input is purely numeric (e.g., "10" for 10 minutes)
if (int.TryParse(time, out int numericMinutes))
{
return numericMinutes;
}
int totalMinutes = 0;
Regex regex = new Regex(@"(\d+)([a-z]+)");
MatchCollection matches = regex.Matches(time);
foreach (Match match in matches)
{
int value = int.Parse(match.Groups[1].Value); // Numeric part
string unit = match.Groups[2].Value; // Unit part
if (timeUnits.TryGetValue(unit, out int minutesPerUnit))
{
totalMinutes += value * minutesPerUnit;
}
else
{
throw new ArgumentException($"Invalid time unit '{unit}' in time string.", nameof(time));
}
}
if (totalMinutes > 0)
{
return totalMinutes;
}
return -1;
}
public static void PrintToCenterAll(string message)
{
Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false }).ToList().ForEach(controller =>
{
controller.PrintToCenter(message);
});
}
internal static void LogCommand(CCSPlayerController? caller, CommandInfo command)
{
if (CS2_SimpleAdmin._localizer == null)
{
return;
}
string playerName = caller?.PlayerName ?? CS2_SimpleAdmin._localizer["sa_console"];
string hostname = ConVar.Find("hostname")?.StringValue ?? CS2_SimpleAdmin._localizer["sa_unknown"];
CS2_SimpleAdmin.Instance.Logger.LogInformation($"{CS2_SimpleAdmin._localizer[
"sa_discord_log_command",
playerName, command.GetCommandString]}".Replace("HOSTNAME", hostname).Replace("**", ""));
SendDiscordLogMessage(caller, command, CS2_SimpleAdmin._localizer);
}
internal static void LogCommand(CCSPlayerController? caller, string command)
{
if (CS2_SimpleAdmin._localizer == null)
{
return;
}
string playerName = caller?.PlayerName ?? CS2_SimpleAdmin._localizer["sa_console"];
ConVar? hostnameCvar = ConVar.Find("hostname");
string hostname = hostnameCvar?.StringValue ?? CS2_SimpleAdmin._localizer["sa_unknown"];
CS2_SimpleAdmin.Instance.Logger.LogInformation($"{CS2_SimpleAdmin._localizer["sa_discord_log_command",
playerName, command]}".Replace("HOSTNAME", hostname).Replace("**", ""));
SendDiscordLogMessage(caller, command, CS2_SimpleAdmin._localizer);
}
/*public static IEnumerable