diff --git a/README.md b/README.md index 665bc23..570f74d 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,17 @@ ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/b3none/cs2-retakes/plugin-build.yml?branch=master&style=flat-square&label=Latest%20Build) # CS2 Retakes + CS2 implementation of retakes written in C# for CounterStrikeSharp. Based on the version for CS:GO by Splewis. ## Share the love + If you appreciate the project then please take the time to star the repository 🙏 ![Star us](https://github.com/b3none/gdprconsent/raw/development/.github/README_ASSETS/star_us.png) ## Features / Roadmap + - [x] Bombsite selection - [x] Per map configurations - [x] Ability to add spawns @@ -30,22 +33,28 @@ If you appreciate the project then please take the time to star the repository - [x] Add a release zip file without spawns too ## Installation + - Download the zip file from the [latest release](https://github.com/B3none/cs2-retakes/releases), and extract the contents into your `counterstrikesharp/plugins` directory. - Download the [shared plugin zip file](https://github.com/B3none/cs2-retakes/releases/download/2.0.0/cs2-retakes-plugin-shared-2.0.0.zip) and put it into your `counterstrikesharp/shared` directory. ## Recommendations + I also recommend installing these plugins for an improved player experience -- Instadefuse: https://github.com/B3none/cs2-instadefuse -- Clutch Announce: https://github.com/B3none/cs2-clutch-announce -- Instaplant (if not using autoplant): https://github.com/B3none/cs2-instaplant + +- Instadefuse: +- Clutch Announce: +- Instaplant (if not using autoplant): ## Allocators + Although this plugin comes with it's own weapon allocation system, I would recommend using **one** of the following plugins for a better experience: -- Yoni's Allocator: https://github.com/yonilerner/cs2-retakes-allocator -- NokkviReyr's Allocator: https://github.com/nokkvireyr/kps-allocator -- Ravid's Allocator: https://github.com/Ravid-A/cs2-retakes-weapon-allocator + +- Yoni's Allocator: +- NokkviReyr's Allocator: +- Ravid's Allocator: ## Configuration + When the plugin is first loaded it will create a `retakes_config.json` file in the plugin directory. This file contains all of the configuration options for the plugin: | Config | Description | Default | Min | Max | @@ -64,8 +73,10 @@ When the plugin is first loaded it will create a `retakes_config.json` file in t | IsDebugMode | Whether to enable debug output to the server console or not. | false | false | true | | ShouldForceEvenTeamsWhenPlayerCountIsMultipleOf10 | Whether to force even teams when the active players is a multiple of 10 or not. (this means you will get 5v5 @ 10 players / 10v10 @ 20 players) | true | false | true | | EnableFallbackBombsiteAnnouncement | Whether to enable the fallback bombsite announcement. | true | false | true | +| RemoveSpectators | When a player is moved to spectators, remove them from all retake queues. Ensures that AFK plugins work as expected. | true | false | true | ## Commands + | Command | Arguments | Description | Permissions | |-----------------|-----------------------------------|----------------------------------------------------------------------|-------------| | !showspawns | | Show the spawns for the specified bombsite. | @css/root | @@ -78,9 +89,11 @@ When the plugin is first loaded it will create a `retakes_config.json` file in t | css_debugqueues | | **SERVER ONLY** Shows the current queue state in the server console. | | ## Stay up to date + Subscribe to **release** notifications and stay up to date with the latest features and patches: ![image](https://github.com/B3none/cs2-retakes/assets/24966460/e288a882-0f1f-4e8c-b67f-e4c066af34ea) ## Credits + This was inspired by the [CS:GO Retakes project](https://github.com/splewis/csgo-retakes) written by [splewis](https://github.com/splewis). diff --git a/RetakesPlugin/Modules/Configs/RetakesConfigData.cs b/RetakesPlugin/Modules/Configs/RetakesConfigData.cs index b290f1e..5359aec 100644 --- a/RetakesPlugin/Modules/Configs/RetakesConfigData.cs +++ b/RetakesPlugin/Modules/Configs/RetakesConfigData.cs @@ -2,7 +2,7 @@ public class RetakesConfigData { - public static int CurrentVersion = 8; + public static int CurrentVersion = 9; public int Version { get; set; } = CurrentVersion; public int MaxPlayers { get; set; } = 9; @@ -19,4 +19,6 @@ public class RetakesConfigData public bool IsDebugMode { get; set; } = false; public bool ShouldForceEvenTeamsWhenPlayerCountIsMultipleOf10 { get; set; } = true; public bool EnableFallbackBombsiteAnnouncement { get; set; } = true; + public bool RemoveSpectators { get; set; } = true; + } diff --git a/RetakesPlugin/Modules/Managers/GameManager.cs b/RetakesPlugin/Modules/Managers/GameManager.cs index 9a2b96a..e1d185e 100644 --- a/RetakesPlugin/Modules/Managers/GameManager.cs +++ b/RetakesPlugin/Modules/Managers/GameManager.cs @@ -1,6 +1,7 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; +using Serilog.Debugging; namespace RetakesPlugin.Modules.Managers; @@ -11,17 +12,18 @@ public class GameManager public readonly QueueManager QueueManager; private readonly int _consecutiveRoundWinsToScramble; private readonly bool _isScrambleEnabled; - + private readonly bool _RemoveSpectatorsEnabled; public const int ScoreForKill = 50; public const int ScoreForAssist = 25; public const int ScoreForDefuse = 50; - public GameManager(Translator translator, QueueManager queueManager, int? roundsToScramble, bool? isScrambleEnabled) + public GameManager(Translator translator, QueueManager queueManager, int? roundsToScramble, bool? isScrambleEnabled, bool? RemoveSpectatorsEnabled) { _translator = translator; QueueManager = queueManager; _consecutiveRoundWinsToScramble = roundsToScramble ?? 5; _isScrambleEnabled = isScrambleEnabled ?? true; + _RemoveSpectatorsEnabled = RemoveSpectatorsEnabled ?? true; } private bool _scrambleNextRound; @@ -245,4 +247,29 @@ private void SetTeams(List? terrorists, List _hasMutedVoices) + { + if (_RemoveSpectatorsEnabled) + { + CCSPlayerController? player = @event.Userid; + + if (!Helpers.IsValidPlayer(player)) + { + return HookResult.Continue; + } + int team = @event.Team; + + if (team == (int)CsTeam.Spectator) + { + // Ensure player is active ingame. + if (QueueManager.ActivePlayers.Contains(player)) + { + QueueManager.RemovePlayerFromQueues(player); + _hasMutedVoices.Remove(player); + } + } + } + return HookResult.Continue; + } } diff --git a/RetakesPlugin/RetakesPlugin.cs b/RetakesPlugin/RetakesPlugin.cs index b624148..af7ed5d 100644 --- a/RetakesPlugin/RetakesPlugin.cs +++ b/RetakesPlugin/RetakesPlugin.cs @@ -487,7 +487,8 @@ private void OnMapStart(string mapName) _retakesConfig?.RetakesConfigData?.ShouldForceEvenTeamsWhenPlayerCountIsMultipleOf10 ), _retakesConfig?.RetakesConfigData?.RoundsToScramble, - _retakesConfig?.RetakesConfigData?.IsScrambleEnabled + _retakesConfig?.RetakesConfigData?.IsScrambleEnabled, + _retakesConfig?.RetakesConfigData?.RemoveSpectators ); _breakerManager = new BreakerManager( @@ -815,30 +816,12 @@ public HookResult OnPlayerTeam(EventPlayerTeam @event, GameEventInfo info) // Ensure all team join events are silent. @event.Silent = true; - CCSPlayerController? player = @event.Userid; - if (_gameManager == null) { Helpers.Debug($"Game manager not loaded."); return HookResult.Continue; } - - if (!Helpers.IsValidPlayer(player)) - { - return HookResult.Continue; - } - int team = @event.Team; - - if (team == (int)CsTeam.Spectator) - { - // Ensure player is active ingame. - if (_gameManager.QueueManager.ActivePlayers.Contains(player)) - { - _gameManager.QueueManager.RemovePlayerFromQueues(player); - _hasMutedVoices.Remove(player); - } - } - return HookResult.Continue; + return _gameManager.RemoveSpectators(@event, _hasMutedVoices); } private HookResult OnCommandJoinTeam(CCSPlayerController? player, CommandInfo commandInfo)