upstream to 1.7.7-alpha-10

This commit is contained in:
Sachin 2025-10-03 17:18:24 +05:30
commit 2de2924cef
106 changed files with 5897 additions and 3306 deletions

View file

@ -28,13 +28,13 @@ namespace CS2_SimpleAdmin;
public partial class CS2_SimpleAdmin
{
bool IsStringValid(string input)
{
{
if (!string.IsNullOrEmpty(input) && (string.IsNullOrEmpty(Config.ChatLog.ExcludeMessageContains) || !input.Any(c => Config.ChatLog.ExcludeMessageContains.Contains(c))) && !char.IsWhiteSpace(input.Last()))
{
return true;
}
return false;
}
{
return true;
}
return false;
}
static int CountLetters(string input)
{
@ -75,32 +75,28 @@ internal static class Helper
public static List<CCSPlayerController> GetPlayerFromName(string name)
{
return Utilities.GetPlayers().FindAll(x => x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase));
return GetValidPlayers().FindAll(x => x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase));
}
public static CCSPlayerController? GetPlayerFromSteamid64(string steamid)
public static CCSPlayerController? GetPlayerFromSteamid64(ulong steamid)
{
return GetValidPlayers().FirstOrDefault(x => x.SteamID.ToString().Equals(steamid, StringComparison.OrdinalIgnoreCase));
return GetValidPlayers().FirstOrDefault(x => x.SteamID == steamid);
}
public static CCSPlayerController? GetPlayerFromIp(string ipAddress)
public static List<CCSPlayerController> GetPlayerFromIp(string ipAddress)
{
return GetValidPlayers().FirstOrDefault(x => x.IpAddress != null && x.IpAddress.Split(":")[0].Equals(ipAddress));
return CS2_SimpleAdmin.CachedPlayers.FindAll(x => x.IpAddress != null && x.IpAddress.Split(":")[0].Equals(ipAddress));
}
public static List<CCSPlayerController> GetValidPlayers()
{
return Utilities.GetPlayers().AsValueEnumerable()
.Where(p => p is { IsValid: true, IsBot: false, Connected: PlayerConnectedState.PlayerConnected })
.ToList();
}
public static List<CCSPlayerController> GetValidPlayersWithBots()
{
return Utilities.GetPlayers().AsValueEnumerable()
.Where(p => p is { IsValid: true, IsHLTV: false, Connected: PlayerConnectedState.PlayerConnected }).ToList();
return CS2_SimpleAdmin.CachedPlayers.AsValueEnumerable().ToList();
}
public static List<CCSPlayerController> GetValidPlayersWithBots()
{
return CS2_SimpleAdmin.CachedPlayers.Concat(CS2_SimpleAdmin.BotPlayers).AsValueEnumerable().ToList();
}
public static bool IsValidSteamId64(string input)
{
@ -166,21 +162,48 @@ internal static class Helper
if (player == null || !player.IsValid || player.IsHLTV)
return;
if (player.UserId.HasValue && CS2_SimpleAdmin.PlayersInfo.TryGetValue(player.UserId.Value, out var value))
if (player.UserId.HasValue && CS2_SimpleAdmin.PlayersInfo.TryGetValue(player.SteamID, out var value))
value.WaitingForKick = true;
player.CommitSuicide(true, true);
// player.CommitSuicide(true, true);
player.VoiceFlags = VoiceFlags.Muted;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.LifeState == (int)LifeState_t.LIFE_ALIVE)
{
playerPawn.Freeze();
playerPawn.Colorize(255, 0, 0);
var weaponServices = playerPawn.WeaponServices;
if (weaponServices == null)
return;
foreach (var _weap in weaponServices.MyWeapons)
{
var 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);
});
}
@ -188,9 +211,10 @@ internal static class Helper
{
// Server.ExecuteCommand($"kickid {player.UserId}");
player.Disconnect(reason);
playerPawn?.Colorize();
player.Disconnect(reason);
}
if (CS2_SimpleAdmin.UnlockedCommands && reason == NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED)
Server.ExecuteCommand($"banid 1 {new SteamID(player.SteamID).SteamId3}");
@ -206,24 +230,54 @@ internal static class Helper
//
// 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 (player.UserId.HasValue && CS2_SimpleAdmin.PlayersInfo.TryGetValue(player.UserId.Value, out var value))
if (CS2_SimpleAdmin.PlayersInfo.TryGetValue(player.SteamID, out var value))
{
if (value.WaitingForKick)
return;
value.WaitingForKick = true;
player.CommitSuicide(true, true);
}
player.VoiceFlags = VoiceFlags.Muted;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.LifeState == (int)LifeState_t.LIFE_ALIVE)
{
playerPawn.Freeze();
playerPawn.Colorize(255, 0, 0);
var weaponServices = playerPawn.WeaponServices;
if (weaponServices == null)
return;
foreach (var _weap in weaponServices.MyWeapons)
{
var 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([';', '|']);
@ -244,7 +298,7 @@ internal static class Helper
player.Disconnect(reason);
}
if (CS2_SimpleAdmin.UnlockedCommands && reason == NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED)
Server.ExecuteCommand($"banid 1 {new SteamID(player.SteamID).SteamId3}");
@ -263,6 +317,7 @@ internal static class Helper
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.");
@ -282,15 +337,14 @@ internal static class Helper
{ "y", 525600 } // Year (365 * 24 * 60)
};
// Check if the input is purely numeric (e.g., "10" for 10 minutes)
if (int.TryParse(time, out var numericMinutes))
{
return numericMinutes;
}
int totalMinutes = 0;
var regex = new Regex(@"(\d+)([a-z]+)");
var matches = regex.Matches(time);
@ -308,7 +362,7 @@ internal static class Helper
throw new ArgumentException($"Invalid time unit '{unit}' in time string.", nameof(time));
}
}
return totalMinutes > 0 ? totalMinutes : -1;
}
@ -326,13 +380,12 @@ internal static class Helper
return;
var playerName = caller?.PlayerName ?? CS2_SimpleAdmin._localizer["sa_console"];
var 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);
}
@ -405,20 +458,20 @@ internal static class Helper
public static void ShowAdminActivity(string messageKey, string? callerName = null, bool dontPublish = false, params object[] messageArgs)
{
string[] publishActions = ["ban", "gag", "silence", "mute"];
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.ShowActivityType == 0) return;
if (CS2_SimpleAdmin._localizer == null) return;
if (string.IsNullOrWhiteSpace(callerName))
callerName = CS2_SimpleAdmin._localizer["sa_console"];
var formattedMessageArgs = messageArgs.Select(arg => arg.ToString() ?? string.Empty).ToArray();
if (dontPublish == false && publishActions.Any(messageKey.Contains))
{
CS2_SimpleAdmin.SimpleAdminApi?.OnAdminShowActivityEvent(messageKey, callerName, dontPublish, messageArgs);
}
// // Replace placeholder based on showActivityType
// for (var i = 0; i < formattedMessageArgs.Length; i++)
// {
@ -442,7 +495,7 @@ internal static class Helper
AdminManager.PlayerHasPermissions(new SteamID(c.SteamID), "@css/kick") ||
AdminManager.PlayerHasPermissions(new SteamID(c.SteamID), "@css/ban"));
}
foreach (var controller in validPlayers.ToList())
{
var currentMessageArgs = (string[])formattedMessageArgs.Clone();
@ -471,16 +524,13 @@ internal static class Helper
{
if (CS2_SimpleAdmin._localizer == null) return;
// Determine the localized message key
var localizedMessageKey = $"{messageKey}";
var formattedMessageArgs = messageArgs.Select(arg => arg?.ToString() ?? string.Empty).ToArray();
// Replace placeholder based on showActivityType
for (var i = 0; i < formattedMessageArgs.Length; i++)
{
var arg = formattedMessageArgs[i]; // Convert argument to string if not null
// Replace "CALLER" placeholder in the argument string
var arg = formattedMessageArgs[i];
formattedMessageArgs[i] = CS2_SimpleAdmin.Instance.Config.OtherSettings.ShowActivityType switch
{
1 => arg.Replace("CALLER", CS2_SimpleAdmin._localizer["sa_admin"]),
@ -488,7 +538,6 @@ internal static class Helper
};
}
// Print the localized message to the center of the screen for the player
using (new WithTemporaryCulture(player.GetLanguage()))
{
player.PrintToCenter(CS2_SimpleAdmin._localizer[localizedMessageKey, formattedMessageArgs.Cast<object>().ToArray()]);
@ -537,7 +586,7 @@ internal static class Helper
time = duration != 0 ? $"<t:{futureUnixTimestamp}:R>" : localizer["sa_permanent"];
else
time = duration != 0 ? ConvertMinutesToTime(duration) : localizer["sa_permanent"];
string[] fieldNames = [
localizer["sa_player"],
localizer["sa_steamid"],
@ -549,13 +598,11 @@ internal static class Helper
$"[{targetName}]({targetCommunityUrl})", $"||{targetSteamId}||", time, reason,
$"[{callerName}]({callerCommunityUrl})"
];
bool[] inlineFlags = [true, true, true, false, false];
var hostname = ConVar.Find("hostname")?.StringValue ?? localizer["sa_unknown"];
var colorHex = penaltySetting.FirstOrDefault(s => s.Name.Equals("Color"))?.Value ?? "#FFFFFF";
if (string.IsNullOrEmpty(colorHex))
colorHex = "#FFFFFF";
var colorValue = penaltySetting.FirstOrDefault(s => s.Name.Equals("Color"))?.Value;
var colorHex = string.IsNullOrWhiteSpace(colorValue) ? "#FFFFFF" : colorValue.Trim();
var embed = new Embed
{
@ -576,7 +623,7 @@ internal static class Helper
{
Text = penaltySetting.FirstOrDefault(s => s.Name.Equals("Footer"))?.Value
},
Timestamp = Time.ActualDateTime().ToUniversalTime().ToString("o"),
};
@ -598,7 +645,7 @@ internal static class Helper
}
});
}
public static void SendDiscordPenaltyMessage(CCSPlayerController? caller, string steamId, string reason, int duration, PenaltyType penalty, IStringLocalizer? localizer)
{
if (localizer == null) return;
@ -633,7 +680,7 @@ internal static class Helper
time = duration != 0 ? $"<t:{futureUnixTimestamp}:R>" : localizer["sa_permanent"];
else
time = duration != 0 ? ConvertMinutesToTime(duration) : localizer["sa_permanent"];
string[] fieldNames = [
localizer["sa_player"],
localizer["sa_steamid"],
@ -645,10 +692,11 @@ internal static class Helper
$"[{targetName}]({targetCommunityUrl})", $"||{targetSteamId}||", time, reason,
$"[{callerName}]({callerCommunityUrl})"
];
bool[] inlineFlags = [true, true, true, false, false];
var hostname = ConVar.Find("hostname")?.StringValue ?? localizer["sa_unknown"];
var colorHex = penaltySetting.FirstOrDefault(s => s.Name.Equals("Color"))?.Value ?? "#FFFFFF";
var colorValue = penaltySetting.FirstOrDefault(s => s.Name.Equals("Color"))?.Value;
var colorHex = string.IsNullOrWhiteSpace(colorValue) ? "#FFFFFF" : colorValue.Trim();
var embed = new Embed
{
@ -669,7 +717,7 @@ internal static class Helper
{
Text = penaltySetting.FirstOrDefault(s => s.Name.Equals("Footer"))?.Value
},
Timestamp = Time.ActualDateTime().ToUniversalTime().ToString("o"),
};
@ -690,7 +738,7 @@ internal static class Helper
}
});
}
private static string GenerateMessageDiscord(string message)
{
var hostname = ConVar.Find("hostname")?.StringValue ?? CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown";
@ -783,18 +831,20 @@ internal static class Helper
// Use Reflection to access the private _pluginManager field
var pluginManagerField = typeof(Application).GetField("_pluginManager", BindingFlags.NonPublic | BindingFlags.Instance);
var pluginManager = pluginManagerField?.GetValue(applicationInstance) as IPluginManager;
return pluginManager;
}
}
public static class PluginInfo
{
internal static async Task CheckVersion(string localVersion, ILogger logger)
{
ShowAd(localVersion);
const string versionUrl = "https://raw.githubusercontent.com/cruze03/CS2-SimpleAdmin/main/CS2-SimpleAdmin/VERSION";
var client = CS2_SimpleAdmin.HttpClient;
client.Timeout = TimeSpan.FromSeconds(3);
try
{
@ -834,8 +884,8 @@ public static class PluginInfo
logger.LogError(ex, "An error occurred while checking version.");
}
}
internal static void ShowAd(string moduleVersion)
private static void ShowAd(string moduleVersion)
{
Console.WriteLine(" ");
Console.WriteLine(" _______ ___ __ __ _______ ___ _______ _______ ______ __ __ ___ __ _ ");
@ -877,25 +927,26 @@ public static class Time
{
public static DateTime ActualDateTime()
{
string timezoneId = CS2_SimpleAdmin.Instance.Config.Timezone;
DateTime utcNow = DateTime.UtcNow;
return DateTime.UtcNow;
// string timezoneId = CS2_SimpleAdmin.Instance.Config.Timezone;
// DateTime utcNow = DateTime.UtcNow;
try
{
TimeZoneInfo timezone = TimeZoneInfo.FindSystemTimeZoneById(timezoneId);
DateTime userTime = TimeZoneInfo.ConvertTimeFromUtc(utcNow, timezone);
return userTime;
}
catch (TimeZoneNotFoundException)
{
CS2_SimpleAdmin._logger?.LogWarning($"Time zone '{timezoneId}' not found. Returning UTC time.");
return utcNow;
}
catch (InvalidTimeZoneException)
{
CS2_SimpleAdmin._logger?.LogWarning($"Time zone '{timezoneId}' is invalid. Returning UTC time.");
return utcNow;
}
// try
// {
// TimeZoneInfo timezone = TimeZoneInfo.FindSystemTimeZoneById(timezoneId);
// DateTime userTime = TimeZoneInfo.ConvertTimeFromUtc(utcNow, timezone);
// return userTime;
// }
// catch (TimeZoneNotFoundException)
// {
// CS2_SimpleAdmin._logger?.LogWarning($"Time zone '{timezoneId}' not found. Returning UTC time.");
// return utcNow;
// }
// catch (InvalidTimeZoneException)
// {
// CS2_SimpleAdmin._logger?.LogWarning($"Time zone '{timezoneId}' is invalid. Returning UTC time.");
// return utcNow;
// }
}
}
@ -914,13 +965,13 @@ public static class WeaponHelper
if (field.GetValue(null) is not CsItem csItem)
continue;
var enumValue = field.GetValue(null);
dictionary.TryAdd(attribute.Value, csItem);
}
return dictionary;
}
public static CsItem? GetEnumFromWeaponName(string weaponName)
{
if (WeaponsEnumCache.Value.TryGetValue(weaponName, out var csItem))
@ -930,7 +981,7 @@ public static class WeaponHelper
return null;
}
public static List<(string EnumMemberValue, CsItem EnumValue)> GetWeaponsByPartialName(string input)
{
// Normalize input for case-insensitive comparison
@ -965,10 +1016,23 @@ public static class IpHelper
{
public static uint IpToUint(string ipAddress)
{
return (uint)BitConverter.ToInt32(System.Net.IPAddress.Parse(ipAddress).GetAddressBytes().Reverse().ToArray(),
0);
if (string.IsNullOrWhiteSpace(ipAddress))
throw new ArgumentException("IP address cannot be null or empty.", nameof(ipAddress));
if (!System.Net.IPAddress.TryParse(ipAddress, out var ip))
throw new FormatException($"Invalid IP address format: {ipAddress}");
// Ensure it's IPv4 (IPv6 will throw)
if (ip.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
throw new FormatException("Only IPv4 addresses are supported.");
byte[] bytes = ip.GetAddressBytes();
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes); // Ensure big-endian (network order)
return BitConverter.ToUInt32(bytes, 0);
}
public static bool TryConvertIpToUint(string ipString, out uint ipUint)
{
ipUint = 0;