diff --git a/CS2-SimpleAdmin/Api/CS2_SimpleAdminApi.cs b/CS2-SimpleAdmin/Api/CS2_SimpleAdminApi.cs index c66c344..2a960a6 100644 --- a/CS2-SimpleAdmin/Api/CS2_SimpleAdminApi.cs +++ b/CS2-SimpleAdmin/Api/CS2_SimpleAdminApi.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Entities; diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs index e67a1b4..81a7a05 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs @@ -3,7 +3,6 @@ using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Core.Capabilities; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Commands.Targeting; -using CounterStrikeSharp.API.Modules.Entities; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CS2_SimpleAdmin.Managers; using CS2_SimpleAdminApi; @@ -20,7 +19,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)"); public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)"; public override string ModuleAuthor => "daffyy & Dliix66"; - public override string ModuleVersion => "1.6.3b"; + public override string ModuleVersion => "1.6.4a"; public override void Load(bool hotReload) { diff --git a/CS2-SimpleAdmin/Commands/basebans.cs b/CS2-SimpleAdmin/Commands/basebans.cs index 7c2f6cd..7262eb8 100644 --- a/CS2-SimpleAdmin/Commands/basebans.cs +++ b/CS2-SimpleAdmin/Commands/basebans.cs @@ -237,7 +237,7 @@ public partial class CS2_SimpleAdmin { if (caller == null) return true; - bool canPermBan = AdminManager.PlayerHasPermissions(caller, "@css/permban"); + var canPermBan = AdminManager.PlayerHasPermissions(caller, "@css/permban"); if (duration <= 0 && canPermBan == false) { diff --git a/CS2-SimpleAdmin/Commands/basechat.cs b/CS2-SimpleAdmin/Commands/basechat.cs index 3e8896f..bc72d69 100644 --- a/CS2-SimpleAdmin/Commands/basechat.cs +++ b/CS2-SimpleAdmin/Commands/basechat.cs @@ -1,5 +1,4 @@ using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; diff --git a/CS2-SimpleAdmin/Commands/basecommands.cs b/CS2-SimpleAdmin/Commands/basecommands.cs index 7447c3e..02d29b4 100644 --- a/CS2-SimpleAdmin/Commands/basecommands.cs +++ b/CS2-SimpleAdmin/Commands/basecommands.cs @@ -1,6 +1,5 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; diff --git a/CS2-SimpleAdmin/Commands/basecomms.cs b/CS2-SimpleAdmin/Commands/basecomms.cs index 4aa3f3d..bdd365c 100644 --- a/CS2-SimpleAdmin/Commands/basecomms.cs +++ b/CS2-SimpleAdmin/Commands/basecomms.cs @@ -1,6 +1,5 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; using CS2_SimpleAdmin.Managers; @@ -50,6 +49,7 @@ public partial class CS2_SimpleAdmin { if (Database == null || !player.IsValid || !player.UserId.HasValue) return; if (!caller.CanTarget(player)) return; + if (!CheckValidMute(caller, time)) return; // Set default caller name if not provided callerName ??= caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName; @@ -126,6 +126,7 @@ public partial class CS2_SimpleAdmin : (_localizer?["sa_unknown"] ?? "Unknown"); int.TryParse(command.GetArg(2), out var time); + if (!CheckValidMute(caller, time)) return; // Get player and admin info var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; @@ -264,6 +265,7 @@ public partial class CS2_SimpleAdmin { if (Database == null || !player.IsValid || !player.UserId.HasValue) return; if (!caller.CanTarget(player)) return; + if (!CheckValidMute(caller, time)) return; // Set default caller name if not provided callerName ??= caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName; @@ -343,6 +345,7 @@ public partial class CS2_SimpleAdmin : (_localizer?["sa_unknown"] ?? "Unknown"); int.TryParse(command.GetArg(2), out var time); + if (!CheckValidMute(caller, time)) return; // Get player and admin info var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; @@ -483,6 +486,7 @@ public partial class CS2_SimpleAdmin { if (Database == null || !player.IsValid || !player.UserId.HasValue) return; if (!caller.CanTarget(player)) return; + if (!CheckValidMute(caller, time)) return; // Set default caller name if not provided callerName ??= caller == null ? _localizer?["sa_console"] ?? "Console" : caller.PlayerName; @@ -499,6 +503,7 @@ public partial class CS2_SimpleAdmin // Add penalty to the player's penalty manager PlayerPenaltyManager.AddPenalty(player.Slot, PenaltyType.Silence, Time.ActualDateTime().AddMinutes(time), time); + player.VoiceFlags = VoiceFlags.Muted; // Determine message keys and arguments based on silence time (permanent or timed) var (messageKey, activityMessageKey, playerArgs, adminActivityArgs) = time == 0 @@ -559,6 +564,7 @@ public partial class CS2_SimpleAdmin : (_localizer?["sa_unknown"] ?? "Unknown"); int.TryParse(command.GetArg(2), out var time); + if (!CheckValidMute(caller, time)) return; // Get player and admin info var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null; @@ -663,4 +669,22 @@ public partial class CS2_SimpleAdmin command.ReplyToCommand($"Unsilenced offline player with pattern {pattern}."); } } + + private bool CheckValidMute(CCSPlayerController? caller, int duration) + { + if (caller == null) return true; + + var canPermMute = AdminManager.PlayerHasPermissions(caller, "@css/permmute"); + + if (duration <= 0 && canPermMute == false) + { + caller.PrintToChat($"{_localizer!["sa_prefix"]} {_localizer["sa_ban_perm_restricted"]}"); + return false; + } + + if (duration <= Config.OtherSettings.MaxMuteDuration || canPermMute) return true; + + caller.PrintToChat($"{_localizer!["sa_prefix"]} {_localizer["sa_ban_max_duration_exceeded", Config.OtherSettings.MaxMuteDuration]}"); + return false; + } } \ No newline at end of file diff --git a/CS2-SimpleAdmin/Commands/basevotes.cs b/CS2-SimpleAdmin/Commands/basevotes.cs index f65d9dc..374c8d8 100644 --- a/CS2-SimpleAdmin/Commands/basevotes.cs +++ b/CS2-SimpleAdmin/Commands/basevotes.cs @@ -1,5 +1,4 @@ using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; diff --git a/CS2-SimpleAdmin/Commands/funcommands.cs b/CS2-SimpleAdmin/Commands/funcommands.cs index 19b52a1..9f67c47 100644 --- a/CS2-SimpleAdmin/Commands/funcommands.cs +++ b/CS2-SimpleAdmin/Commands/funcommands.cs @@ -1,5 +1,4 @@ using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; diff --git a/CS2-SimpleAdmin/Commands/playercommands.cs b/CS2-SimpleAdmin/Commands/playercommands.cs index 5debea2..c9ae79c 100644 --- a/CS2-SimpleAdmin/Commands/playercommands.cs +++ b/CS2-SimpleAdmin/Commands/playercommands.cs @@ -67,18 +67,11 @@ public partial class CS2_SimpleAdmin var weaponName = command.GetArg(2); // check if item is typed - if (weaponName.Length < 5) - { - command.ReplyToCommand($"No weapon typed."); - return; - } - - // check if item is valid - if (!weaponName.Contains("weapon_") && !weaponName.Contains("item_")) - { - command.ReplyToCommand($"{weaponName} is not a valid item."); - return; - } + // if (weaponName.Length < 2) + // { + // command.ReplyToCommand($"No weapon typed."); + // return; + // } // check if weapon is knife if (weaponName.Contains("_knife") || weaponName.Contains("bayonet")) @@ -105,9 +98,22 @@ public partial class CS2_SimpleAdmin // Set default caller name if not provided callerName ??= caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console"; + var weapons = WeaponHelper.GetWeaponsByPartialName(weaponName); + + switch (weapons.Count) + { + case 0: + return; + case > 1: + { + var weaponList = string.Join(", ", weapons.Select(w => w.EnumMemberValue)); + command?.ReplyToCommand($"Found weapons with a similar name: {weaponList}"); + return; + } + } // Give weapon to the player - player.GiveNamedItem(weaponName); + player.GiveNamedItem(weapons.First().EnumValue); // Log the command if (command == null) diff --git a/CS2-SimpleAdmin/Config.cs b/CS2-SimpleAdmin/Config.cs index f523734..df40481 100644 --- a/CS2-SimpleAdmin/Config.cs +++ b/CS2-SimpleAdmin/Config.cs @@ -201,6 +201,9 @@ public class OtherSettings [JsonPropertyName("MaxBanDuration")] public int MaxBanDuration { get; set; } = 60 * 24 * 7; + + [JsonPropertyName("MaxMuteDuration")] + public int MaxMuteDuration { get; set; } = 60 * 24 * 7; [JsonPropertyName("ExpireOldIpBans")] public int ExpireOldIpBans { get; set; } = 0; @@ -220,7 +223,7 @@ public class OtherSettings public class CS2_SimpleAdminConfig : BasePluginConfig { - [JsonPropertyName("ConfigVersion")] public override int Version { get; set; } = 21; + [JsonPropertyName("ConfigVersion")] public override int Version { get; set; } = 22; [JsonPropertyName("DatabaseHost")] public string DatabaseHost { get; set; } = ""; diff --git a/CS2-SimpleAdmin/Helper.cs b/CS2-SimpleAdmin/Helper.cs index ce6f797..238360a 100644 --- a/CS2-SimpleAdmin/Helper.cs +++ b/CS2-SimpleAdmin/Helper.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using CounterStrikeSharp.API; +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Translations; using CounterStrikeSharp.API.Modules.Admin; @@ -15,9 +14,11 @@ using Microsoft.Extensions.Logging; 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.RegularExpressions; +using CounterStrikeSharp.API.Modules.Entities.Constants; using CS2_SimpleAdmin.Managers; namespace CS2_SimpleAdmin; @@ -625,4 +626,47 @@ public static class Time return utcNow; } } -} \ No newline at end of file +} + +public static class WeaponHelper +{ + private static readonly Lazy> WeaponsEnumCache = new(BuildEnumMemberMap); + + private static Dictionary BuildEnumMemberMap() + { + var dictionary = new Dictionary(); + + foreach (var field in typeof(CsItem).GetFields(BindingFlags.Public | BindingFlags.Static)) + { + var attribute = field.GetCustomAttribute(); + if (attribute?.Value == null) continue; + 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)) + { + return csItem; + } + + return null; + } + + public static List<(string EnumMemberValue, CsItem EnumValue)> GetWeaponsByPartialName(string input) + { + var matchingWeapons = WeaponsEnumCache.Value + .Where(kvp => kvp.Key.Contains(input)) + .Select(kvp => (kvp.Key, kvp.Value)) + .ToList(); + + return matchingWeapons; + } +} diff --git a/CS2-SimpleAdmin/VERSION b/CS2-SimpleAdmin/VERSION index 12bfe62..9ff7676 100644 --- a/CS2-SimpleAdmin/VERSION +++ b/CS2-SimpleAdmin/VERSION @@ -1 +1 @@ -1.6.3b \ No newline at end of file +1.6.4a \ No newline at end of file diff --git a/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdminApi.dll b/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdminApi.dll new file mode 100644 index 0000000..b7283c2 Binary files /dev/null and b/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdminApi.dll differ diff --git a/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.cs b/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.cs new file mode 100644 index 0000000..ebba37b --- /dev/null +++ b/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.cs @@ -0,0 +1,59 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; +using CounterStrikeSharp.API.Core.Capabilities; +using CounterStrikeSharp.API.Modules.Admin; +using CounterStrikeSharp.API.Modules.Commands; +using CS2_SimpleAdminApi; +using Microsoft.Extensions.Logging; + +namespace CS2_SimpleAdmin_CleanModule; + +public class CS2_SimpleAdmin_CleanModule: BasePlugin +{ + public override string ModuleName => "[CS2-SimpleAdmin] Clean module"; + public override string ModuleDescription => "Module allows you to remove all weapons lying on the ground"; + public override string ModuleVersion => "v1.0.0"; + public override string ModuleAuthor => "daffyy"; + + private static ICS2_SimpleAdminApi? _sharedApi; + private readonly PluginCapability _pluginCapability = new("simpleadmin:api"); + + public override void OnAllPluginsLoaded(bool hotReload) + { + _sharedApi = _pluginCapability.Get(); + + if (_sharedApi == null) + { + Logger.LogError("CS2-SimpleAdmin SharedApi not found"); + Unload(false); + } + } + + [ConsoleCommand("css_clean")] + [ConsoleCommand("css_clear")] + [RequiresPermissions("@css/cheat")] + public void OnCleanCommand(CCSPlayerController? caller, CommandInfo commandInfo) + { + var weapons = Utilities.FindAllEntitiesByDesignerName("weapon_"); + var defusers = Utilities.FindAllEntitiesByDesignerName("item_cutters"); + + foreach (var weapon in weapons) + { + if (!weapon.IsValid || weapon.State != CSWeaponState_t.WEAPON_NOT_CARRIED) + continue; + + weapon.Remove(); + } + + foreach (var defuser in defusers) + { + if (!defuser.IsValid || defuser.OwnerEntity.Value != null) + continue; + + defuser.Remove(); + } + + _sharedApi?.LogCommand(caller, commandInfo); + } +} \ No newline at end of file diff --git a/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.csproj b/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.csproj new file mode 100644 index 0000000..1aac41c --- /dev/null +++ b/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.csproj @@ -0,0 +1,20 @@ + + + + net8.0 + CS2_SimpleAdmin_CleanModule + enable + enable + + + + + + + + + CS2-SimpleAdminApi.dll + + + + diff --git a/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.sln b/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.sln new file mode 100644 index 0000000..f9e05b4 --- /dev/null +++ b/Modules/CS2-SimpleAdmin_ExampleModule — kopia/CS2-SimpleAdmin_CleanModule.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CS2-SimpleAdmin_CleanModule", "CS2-SimpleAdmin_CleanModule.csproj", "{D940F3E9-0E3F-467A-B336-149E3A624FB6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D940F3E9-0E3F-467A-B336-149E3A624FB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D940F3E9-0E3F-467A-B336-149E3A624FB6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D940F3E9-0E3F-467A-B336-149E3A624FB6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D940F3E9-0E3F-467A-B336-149E3A624FB6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Modules/CS2-SimpleAdmin_ExampleModule/CS2-SimpleAdminApi.dll b/Modules/CS2-SimpleAdmin_ExampleModule/CS2-SimpleAdminApi.dll index c2dbdee..b7283c2 100644 Binary files a/Modules/CS2-SimpleAdmin_ExampleModule/CS2-SimpleAdminApi.dll and b/Modules/CS2-SimpleAdmin_ExampleModule/CS2-SimpleAdminApi.dll differ