Skip to content

Commit 25e8f04

Browse files
authored
Update builtinvotes extension (#918)
**Improvements:** 1) Added the ability to add custom data to the callback after a successful vote. 2) Add the ability to block voting at the start. 3) Add native Game_GetVoteController. ** Description:** Github actions no longer supports Ubuntu 20.04, only 22.04 and above. You'll have to compile it yourself if your Linux version is lower than 22.04. Binary files from: https://github.com/L4D-Community/builtinvotes/actions/runs/19618897902 Files: builtinvotes-sm1.12-win-805e8e1, builtinvotes-sm1.12-oldlinux-805e8e1
1 parent d5af8da commit 25e8f04

5 files changed

Lines changed: 601 additions & 184 deletions

File tree

-106 KB
Binary file not shown.
-576 KB
Binary file not shown.
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
#pragma semicolon 1
2+
#pragma newdecls required
3+
4+
#include <sourcemod>
5+
#include <builtinvotes>
6+
7+
DataPack
8+
g_hCallBackPack = null;
9+
10+
Handle
11+
g_hVoteHandler = null;
12+
13+
ConVar
14+
g_hCvarBlockBVote = null,
15+
g_hCvarDisplayBVoteResult = null;
16+
17+
enum
18+
{
19+
eBlockNone = 0,
20+
eBlockOnCreation,
21+
eBlockAtStart
22+
};
23+
24+
enum
25+
{
26+
eVoteFail = 0,
27+
eVotePass
28+
};
29+
30+
stock const char g_sBuiltinVoteCreateError[][] =
31+
{
32+
"eBuiltinVoteErrorNone",
33+
"eBlockedWithForward",
34+
"eInvalidParamBuiltinVoteType"
35+
};
36+
37+
public Plugin myinfo =
38+
{
39+
name = "[L4D2] BuiltinVotes test",
40+
author = "A1m`",
41+
description = "Plugin to test the extension 'builtinvotes'",
42+
version = "2.5",
43+
url = "https://github.com/L4D-Community/builtinvotes"
44+
};
45+
46+
public void OnPluginStart()
47+
{
48+
g_hCvarBlockBVote = CreateConVar("sm_block_builtinvotes", \
49+
"0", \
50+
"Block all votes from extension 'builtinvotes' (used for debugging). 1 - block voting on creation, 2 - block voting at start.", \
51+
_, true, 0.0, true, 2.0 \
52+
);
53+
54+
g_hCvarDisplayBVoteResult = CreateConVar("sm_display_builtinvotes_result", \
55+
"1", \
56+
"Display the result of voting at the end of voting. 0 - not display, 1 - display.", \
57+
_, true, 0.0, true, 1.0 \
58+
);
59+
60+
RegAdminCmd("sm_bv_test", Cmd_BuiltinVotesTest, ADMFLAG_GENERIC);
61+
RegAdminCmd("sm_bv_close_data", Cmd_BuiltinVotesCloseData, ADMFLAG_GENERIC);
62+
RegAdminCmd("sm_getvotecontroller", Cmd_GetGameVoteController, ADMFLAG_GENERIC);
63+
}
64+
65+
Action Cmd_GetGameVoteController(int iClient, int iArgs)
66+
{
67+
int iEntIndex = Game_GetVoteController();
68+
69+
char sEntityName[64];
70+
FormatEx(sEntityName, sizeof(sEntityName), "Unknown entity");
71+
72+
if (iEntIndex > MaxClients && IsValidEntity(iEntIndex)) {
73+
GetEntityClassname(iEntIndex, sEntityName, sizeof(sEntityName));
74+
}
75+
76+
PrintToChat(iClient, "Entity name: %s, entity index: %d!", sEntityName, iEntIndex);
77+
78+
return Plugin_Handled;
79+
}
80+
81+
public Action OnBuiltinVoteCreate(Handle hPlugin, const char[] sPluginName)
82+
{
83+
PrintToChatAll("[OnBuiltinVoteCreate] hPlugin: %x, sPluginName: %s", hPlugin, sPluginName);
84+
85+
if (hPlugin != null) {
86+
char sPlName[32], sPlAuthor[32], sPlDescription[64], sPlVersion[16], sPlUrl[256];
87+
88+
GetPluginInfo(hPlugin, PlInfo_Name, sPlName, sizeof(sPlName));
89+
GetPluginInfo(hPlugin, PlInfo_Author, sPlAuthor, sizeof(sPlAuthor));
90+
GetPluginInfo(hPlugin, PlInfo_Description, sPlDescription, sizeof(sPlDescription));
91+
GetPluginInfo(hPlugin, PlInfo_Version, sPlVersion, sizeof(sPlVersion));
92+
GetPluginInfo(hPlugin, PlInfo_URL, sPlUrl, sizeof(sPlUrl));
93+
94+
PrintToChatAll("[OnBuiltinVoteCreate] Plugin name: %s ", sPlName);
95+
PrintToChatAll("[OnBuiltinVoteCreate] Plugin author: %s ", sPlAuthor);
96+
PrintToChatAll("[OnBuiltinVoteCreate] Plugin description: %s ", sPlDescription);
97+
PrintToChatAll("[OnBuiltinVoteCreate] Plugin version: %s ", sPlVersion);
98+
PrintToChatAll("[OnBuiltinVoteCreate] Plugin url: %s ", sPlUrl);
99+
PrintToChatAll("[OnBuiltinVoteCreate] Plugin status: %d", GetPluginStatus(hPlugin));
100+
}
101+
102+
return (g_hCvarBlockBVote.IntValue == eBlockOnCreation) ? Plugin_Handled : Plugin_Continue;
103+
}
104+
105+
public Action OnBuiltinVoteStart(Handle hVote, Handle hPlugin, const char[] sPluginName)
106+
{
107+
int iInitiator = GetBuiltinVoteInitiator(hVote);
108+
109+
char sInitiatorName[32] = "Unknown";
110+
111+
// Server (0) and clients (1-32)
112+
if (iInitiator >= 0 && iInitiator <= MaxClients && IsClientInGame(iInitiator)) {
113+
GetClientName(iInitiator, sInitiatorName, sizeof(sInitiatorName));
114+
}
115+
116+
PrintToChatAll("[OnBuiltinVoteStart] Initiator: %s (%d), hPlugin: %x, sPluginName: %s", sInitiatorName, iInitiator, hPlugin, sPluginName);
117+
118+
if (hPlugin != null) {
119+
char sPlName[32], sPlAuthor[32], sPlDescription[64], sPlVersion[16], sPlUrl[256];
120+
121+
GetPluginInfo(hPlugin, PlInfo_Name, sPlName, sizeof(sPlName));
122+
GetPluginInfo(hPlugin, PlInfo_Author, sPlAuthor, sizeof(sPlAuthor));
123+
GetPluginInfo(hPlugin, PlInfo_Description, sPlDescription, sizeof(sPlDescription));
124+
GetPluginInfo(hPlugin, PlInfo_Version, sPlVersion, sizeof(sPlVersion));
125+
GetPluginInfo(hPlugin, PlInfo_URL, sPlUrl, sizeof(sPlUrl));
126+
127+
PrintToChatAll("[OnBuiltinVoteStart] Plugin name: %s ", sPlName);
128+
PrintToChatAll("[OnBuiltinVoteStart] Plugin author: %s ", sPlAuthor);
129+
PrintToChatAll("[OnBuiltinVoteStart] Plugin description: %s ", sPlDescription);
130+
PrintToChatAll("[OnBuiltinVoteStart] Plugin version: %s ", sPlVersion);
131+
PrintToChatAll("[OnBuiltinVoteStart] Plugin url: %s ", sPlUrl);
132+
PrintToChatAll("[OnBuiltinVoteStart] Plugin status: %d", GetPluginStatus(hPlugin));
133+
}
134+
135+
return (g_hCvarBlockBVote.IntValue == eBlockAtStart) ? Plugin_Handled : Plugin_Continue;
136+
}
137+
138+
Action Cmd_BuiltinVotesCloseData(int iClient, int iArgs)
139+
{
140+
if (g_hCallBackPack == null) {
141+
PrintToChat(iClient, "User data was not passed to the callback!");
142+
return Plugin_Handled;
143+
}
144+
145+
delete g_hCallBackPack;
146+
g_hCallBackPack = null;
147+
148+
PrintToChat(iClient, "User data was successfully deleted!");
149+
150+
return Plugin_Handled;
151+
}
152+
153+
Action Cmd_BuiltinVotesTest(int iClient, int iArgs)
154+
{
155+
StartBuiltinVote(iClient, (iArgs == 1));
156+
157+
return Plugin_Handled;
158+
}
159+
160+
void StartBuiltinVote(const int iInitiator, bool bPassData = false)
161+
{
162+
if (!IsNewBuiltinVoteAllowed()) {
163+
PrintToChat(iInitiator, "Builtinvote cannot be started now.");
164+
return;
165+
}
166+
167+
int iNumPlayers;
168+
int[] iPlayers = new int[MaxClients];
169+
for (int i = 1; i <= MaxClients; i++) {
170+
if (!IsClientInGame(i) || IsFakeClient(i)) {
171+
continue;
172+
}
173+
174+
iPlayers[iNumPlayers++] = i;
175+
}
176+
177+
eBuiltinVoteCreateError iError;
178+
g_hVoteHandler = CreateBuiltinVoteEx(VoteActionHandler, BuiltinVoteType_Custom_YesNo, BuiltinVoteAction_Cancel | BuiltinVoteAction_VoteEnd | BuiltinVoteAction_End, iError);
179+
if (g_hVoteHandler == null) {
180+
PrintToChatAll("Failed to create vote. Reason %s (%d)!", g_sBuiltinVoteCreateError[iError], iError);
181+
return;
182+
}
183+
184+
char sBuffer[64];
185+
Format(sBuffer, sizeof(sBuffer), "Builtinvote test!");
186+
SetBuiltinVoteArgument(g_hVoteHandler, sBuffer);
187+
SetBuiltinVoteInitiator(g_hVoteHandler, iInitiator);
188+
189+
if (bPassData) {
190+
g_hCallBackPack = new DataPack();
191+
192+
g_hCallBackPack.WriteString("UserData 1");
193+
g_hCallBackPack.WriteString("UserData 2");
194+
g_hCallBackPack.WriteCell(1);
195+
g_hCallBackPack.WriteCell(2);
196+
197+
SetBuiltinVoteResultCallback(g_hVoteHandler, VoteResultHandlerUserData, g_hCallBackPack, BV_DATA_HNDL_CLOSE);
198+
} else {
199+
SetBuiltinVoteResultCallback(g_hVoteHandler, VoteResultHandler);
200+
}
201+
202+
DisplayBuiltinVote(g_hVoteHandler, iPlayers, iNumPlayers, 20);
203+
//FakeClientCommand(iInitiator, "Vote Yes");
204+
}
205+
206+
void VoteActionHandler(Handle hVote, BuiltinVoteAction iAction, int iParam1, int iParam2)
207+
{
208+
switch (iAction) {
209+
case BuiltinVoteAction_End: {
210+
g_hVoteHandler = null;
211+
g_hCallBackPack = null;
212+
delete hVote;
213+
}
214+
case BuiltinVoteAction_Cancel: {
215+
DisplayBVoteResult(hVote, eVoteFail);
216+
}
217+
}
218+
}
219+
220+
void VoteResultHandlerUserData(Handle hVote, int iNumVotes, int iNumClients, \
221+
const int[][] iClientInfo, int iNumItems, const int[][] iItemInfo, DataPack hPack)
222+
{
223+
for (int i = 0; i < iNumItems; i++) {
224+
if (iItemInfo[i][BUILTINVOTEINFO_ITEM_INDEX] != BUILTINVOTES_VOTE_YES) {
225+
continue;
226+
}
227+
228+
if (iItemInfo[i][BUILTINVOTEINFO_ITEM_VOTES] > (iNumClients / 2)) {
229+
hPack.Reset();
230+
231+
char sBuffer1[32], sBuffer2[32];
232+
hPack.ReadString(sBuffer1, sizeof(sBuffer1));
233+
hPack.ReadString(sBuffer2, sizeof(sBuffer2));
234+
235+
int iBuff1 = hPack.ReadCell();
236+
int iBuff2 = hPack.ReadCell();
237+
PrintToChatAll("String1: %s, String2: %s, int1: %d, int2: %d", sBuffer1, sBuffer2, iBuff1, iBuff2);
238+
239+
DisplayBVoteResult(hVote, eVotePass, "Builtinvote test end...");
240+
241+
return;
242+
}
243+
}
244+
245+
DisplayBVoteResult(hVote, eVoteFail);
246+
}
247+
248+
void VoteResultHandler(Handle hVote, int iNumVotes, int iNumClients, \
249+
const int[][] iClientInfo, int iNumItems, const int[][] iItemInfo)
250+
{
251+
for (int i = 0; i < iNumItems; i++) {
252+
if (iItemInfo[i][BUILTINVOTEINFO_ITEM_INDEX] != BUILTINVOTES_VOTE_YES) {
253+
continue;
254+
}
255+
256+
if (iItemInfo[i][BUILTINVOTEINFO_ITEM_VOTES] > (iNumClients / 2)) {
257+
DisplayBVoteResult(hVote, eVotePass, "Builtinvote test end...");
258+
259+
return;
260+
}
261+
}
262+
263+
DisplayBVoteResult(hVote, eVoteFail);
264+
}
265+
266+
void DisplayBVoteResult(Handle hVote, int iResultType, char[] sPassArg = "")
267+
{
268+
if (!g_hCvarDisplayBVoteResult.BoolValue) {
269+
return;
270+
}
271+
272+
if (iResultType == eVotePass) {
273+
DisplayBuiltinVotePass(hVote, sPassArg);
274+
275+
return;
276+
}
277+
278+
DisplayBuiltinVoteFail(hVote, BuiltinVoteFail_Loses);
279+
}

0 commit comments

Comments
 (0)