using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Translations;
using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Timers;
using CS2_SimpleAdmin.Menus;
using PanoramaUiKit.Shared.Api;
using PanoramaUiKit.Shared.Votes;
namespace CS2_SimpleAdmin;
public partial class CS2_SimpleAdmin
{
private const float VoteDurationSeconds = 30f;
///
/// Handles the vote command: shows the vote screen to every player, collects one answer each
/// and prints the results when the countdown ends.
///
/// The player/admin who initiated the vote, or null for console.
/// Command object containing question and options.
[RequiresPermissions("@css/generic")]
[CommandHelper(minArgs: 2, usage: " [... options ...]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnVoteCommand(CCSPlayerController? caller, CommandInfo command)
{
if (command.ArgCount < 2 || _localizer == null)
{
return;
}
Helper.LogCommand(caller, command);
if (caller != null && SilentPlayers.Contains(caller.Slot))
{
return;
}
IPanoramaUiKit? kit = UiKit.Instance;
if (kit == null)
{
return;
}
string question = command.GetArg(1);
string callerName = Helper.GetCallerName(caller);
List answers = [];
for (int i = 2; i < command.ArgCount; i++)
{
answers.Add(command.GetArg(i));
}
int[] counts = new int[answers.Count];
Dictionary ballots = [];
VoteInProgress = true;
foreach (CCSPlayerController player in Helper.GetValidPlayers())
{
kit.Votes.Show(player, BuildVote(player, question, answers, counts, null, OnVote));
player.SendLocalizedMessage(_localizer, "sa_admin_vote_message", callerName, question);
}
Helper.PrintToCenterAll(_localizer["sa_admin_vote_message", callerName, question]);
AddTimer(VoteDurationSeconds, () =>
{
UiKit.Instance?.Votes.HideAll(UiKit.VoteLayout);
VoteInProgress = false;
if (_localizer == null)
{
return;
}
foreach (CCSPlayerController player in Helper.GetValidPlayers())
{
player.SendLocalizedMessage(_localizer, "sa_admin_vote_message_results", question);
for (int i = 0; i < answers.Count; i++)
{
player.SendLocalizedMessage(_localizer, "sa_admin_vote_message_results_answer", answers[i], counts[i]);
}
}
}, TimerFlags.STOP_ON_MAPCHANGE);
return;
void OnVote(VoteEvent vote)
{
if (!VoteInProgress || ballots.ContainsKey(vote.Player.SteamID))
{
return;
}
ballots[vote.Player.SteamID] = vote.Index;
counts[vote.Index]++;
IPanoramaUiKit? currentKit = UiKit.Instance;
if (currentKit == null)
{
return;
}
foreach (CCSPlayerController player in Helper.GetValidPlayers())
{
int? selected = null;
if (ballots.TryGetValue(player.SteamID, out int index))
{
selected = index;
}
currentKit.Votes.Update(player, BuildVote(player, question, answers, counts, selected, OnVote));
}
}
}
///
/// The vote screen for one player, locked once that player has voted.
///
private static VoteOptions BuildVote(CCSPlayerController player, string question, List answers, int[] counts,
int? selected, Action onVote)
{
string title;
using (new WithTemporaryCulture(player.GetLanguage()))
{
title = _localizer?["sa_admin_vote_menu_title", question] ?? question;
}
List choices = [];
for (int i = 0; i < answers.Count; i++)
{
choices.Add(new VoteChoice(answers[i], counts[i]));
}
return new VoteOptions
{
Layout = UiKit.VoteLayout,
Title = title,
Choices = choices,
Selected = selected,
Locked = selected.HasValue,
Seconds = VoteDurationSeconds,
OnVote = onVote
};
}
}