VoteManagerApi 1.2.0
dotnet add package VoteManagerApi --version 1.2.0
NuGet\Install-Package VoteManagerApi -Version 1.2.0
<PackageReference Include="VoteManagerApi" Version="1.2.0" />
<PackageVersion Include="VoteManagerApi" Version="1.2.0" />
<PackageReference Include="VoteManagerApi" />
paket add VoteManagerApi --version 1.2.0
#r "nuget: VoteManagerApi, 1.2.0"
#:package VoteManagerApi@1.2.0
#addin nuget:?package=VoteManagerApi&version=1.2.0
#tool nuget:?package=VoteManagerApi&version=1.2.0
VoteManagerApi
Shared API for the VoteManager CounterStrikeSharp plugin. Reference
this package to start and observe votes from your own plugin. VoteManagerCore runs them and draws them on a
Panorama HUD, and only one vote runs at a time, server-wide.
The server must have VoteManagerCore installed (addons/counterstrikesharp/plugins/VoteManagerCore/) plus
VoteManagerApi.dll in addons/counterstrikesharp/shared/VoteManagerApi/; both ship in the
release zip. Clients need the
Vote Manager HUD workshop item mounted
on the server, or the vote runs with nothing drawn.
Install
dotnet add package VoteManagerApi
CounterStrikeSharp loads VoteManagerApi.dll from shared/, so your plugin must not ship its own copy:
<PackageReference Include="VoteManagerApi" Version="1.0.*" ExcludeAssets="runtime" Private="false" />
Usage
Resolve the plugin capability once all plugins are loaded, then start a vote:
using VoteManagerApi;
using VoteManagerApi.Enums;
using VoteManagerApi.Votes;
private IVoteManagerApi? _voteManager;
public override void OnAllPluginsLoaded(bool hotReload)
{
_voteManager = IVoteManagerApi.PluginCapability.Get();
}
private void StartMapVote()
{
var players = Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot).ToList();
var vote = new YesNoVoteInfo(
title: "Change map to de_dust2?",
duration: 20,
potentialClients: players,
thresholdType: VoteThresholdType.Percentage,
voteThreshold: 0.6f);
var state = _voteManager?.InitiateVote(vote,
onVoteFinish: (info, _, selected) =>
{
if (info is YesNoVoteInfo yesNo && yesNo.IsVoteSuccessful())
Server.ExecuteCommand("changelevel de_dust2");
},
onFailure: (_, failed) => Server.PrintToChatAll($"Vote failed: {failed}"));
if (state != VoteState.InitializeAccepted)
Server.PrintToChatAll("A vote is already running.");
}
A multi-option vote is decided by plurality, no threshold involved:
var vote = new MultiOptionsVote(
title: "Next map?",
options: [new("de_dust2", "Dust II"), new("de_mirage", "Mirage")],
duration: 20,
potentialClients: players);
_voteManager?.InitiateVote(vote, onVoteFinish: (_, _, selected) =>
{
if (selected is not null)
Server.ExecuteCommand($"changelevel {selected.Identifier}");
});
Input mode and layout
All are init properties on any VoteInfo:
var vote = new MultiOptionsVote("Next map?", options, 20, players)
{
InputMode = VoteInputMode.Keys, // Cursor, Keys, or Both (default)
AllowRevote = false, // default true
Layout = new VoteLayout("panorama/layout/custom_game/my_vote.vxml_c", "MyVoteRoot", OptionSlots: 8),
};
| Property | Default | Meaning |
|---|---|---|
InputMode |
Both |
Cursor takes the mouse while the card is up so options can be clicked. Keys leaves the mouse alone; players run css_1..css_6 for the option on their current page (1 = Yes, 2 = No on a yes/no vote), css_7 for the previous page and css_8 for the next. Both does both |
AllowRevote |
true |
Whether a player can change their vote after casting. When false the first cast is final; later clicks, keys and css_revote are ignored for that player |
Layout |
null |
The Panorama layout that draws the vote. null is the built-in design. A custom layout must follow the built-in id contract; see the repository README, "Custom vote layouts", and the skills/vote-manager-layout agent skill |
The HUD shows live counts, share bars, a threshold marker on yes/no votes, a countdown, the viewer's own vote, the current leader, and the result for a few seconds after the vote ends. More options than a layout has rows paginate, per viewer.
API
| Member | Purpose |
|---|---|
IVoteManagerApi.PluginCapability |
PluginCapability<IVoteManagerApi?> for "votemanager:api" |
InitiateVote(vote, finishOnAllVote, onVoteFinish, onFailure, onVoteCast) |
Starts a vote; returns InitializeAccepted on success |
CancelVote() |
Cancels the running vote |
IsVoteInProgress / GetCurrentVoteState() |
Whether a vote is running, and its VoteState |
GetCurrentVote() |
The running VoteInfo, or null |
finishOnAllVote (default true) ends the vote as soon as every potential client has voted, instead of
waiting out the full duration. Players can change their vote until it ends unless AllowRevote is false.
Callbacks
| Delegate | Signature |
|---|---|
VoteFinishHandler |
(VoteInfo vote, VoteState state, VoteOption? selectedOption) |
VoteFailureHandler |
(VoteInfo vote, VoteState state) |
VoteCastHandler |
(VoteInfo vote, CCSPlayerController? player, VoteOption option) |
Exceptions thrown by a callback are logged by VoteManagerCore and do not stop the vote from completing.
Vote types
| Type | Constructor | Result |
|---|---|---|
YesNoVoteInfo |
(title, duration, potentialClients, thresholdType, voteThreshold) |
IsVoteSuccessful(): yes-votes / total votes vs. the threshold |
MultiOptionsVote |
(title, options, duration, potentialClients) |
GetSelectedOption(): the option with the most votes |
VoteThresholdType.Percentage takes voteThreshold in 0.0..1.0 (out-of-range falls back to 0.5).
VoteThresholdType.AbsoluteValue ignores voteThreshold, so use Percentage for YesNoVoteInfo.
Subclass VoteInfo for anything else: override GetSelectedOption() / IsVoteFinished() to change how a
winner is picked, and use GetVotes(identifier) / GetTotalVotes() for the tallies. Any other VoteInfo
subclass is drawn with the multi-option layout.
License
Apache-2.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CounterStrikeSharp.API (>= 1.0.371)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.