-
Notifications
You must be signed in to change notification settings - Fork 30
/
custom_votes.py
492 lines (442 loc) · 24.8 KB
/
custom_votes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# This file is part of the Quake Live server implementation by TomTec Solutions. Do not copy or redistribute or link to this file without the emailed consent of Thomas Jones (thomas@tomtecsolutions.com).
# custom_votes.py - a minqlx plugin to enable the ability to have custom vote functionality in-game.
# This plugin is released to everyone, for any purpose. It comes with no warranty, no guarantee it works, it's released AS IS.
# You can modify everything, except for lines 1-4 and the !tomtec_versions code. They're there to indicate I whacked this together originally. Please make it better :D
"""
The following cvars are used on this plugin:
qlx_rulesetLocked: Is used to prevent '/cv ruleset' votes. Default: 0
qlx_disablePlayerRemoval: Prevents non-privileged players from using '/cv kick' or '/cv tempban'. Default: 0
qlx_disableCvarVoting: Prevents anyone from calling a CVAR vote. Default: 0
qlx_cvarVotePermissionRequired: Required permission level to call a CVAR vote. Default: 3
"""
#
# List of custom votes this plugin provides: http://tomtecsolutions.com.au/thepurgery/index.php?title=Special_votes
#
import minqlx
class custom_votes(minqlx.Plugin):
def __init__(self):
self.add_hook("vote_called", self.handle_vote_called)
self.add_hook("player_loaded", self.player_loaded)
self.add_command("tomtec_versions", self.cmd_showversion)
self.add_command("excessiveweaps", self.cmd_excessive_weaps, 5, usage="on/off")
self.add_command("ruleset", self.cmd_ruleset, 5, usage="pql/vql")
self.set_cvar_once("qlx_rulesetLocked", "0")
self.set_cvar_once("qlx_excessive", "0")
self.set_cvar_once("qlx_disablePlayerRemoval", "0")
self.set_cvar_once("qlx_disableCvarVoting", "0")
self.set_cvar_once("qlx_cvarVotePermissionRequired", "3")
self.plugin_version = "2.3"
def player_loaded(self, player):
if (self.get_cvar("qlx_excessive", bool)):
player.tell("Excessive weapons are ^2enabled^7. To disable them, ^2/cv excessive off^7.")
def cmd_ruleset(self, player, msg, channel):
if len(msg) < 2:
return minqlx.RET_USAGE
if msg[1].lower() == "pql":
minqlx.set_cvar("pmove_airControl", "1")
minqlx.set_cvar("pmove_rampJump", "1")
minqlx.set_cvar("weapon_reload_rg", "1200")
minqlx.set_cvar("pmove_weaponRaiseTime", "10")
minqlx.set_cvar("pmove_weaponDropTime", "10")
minqlx.set_cvar("g_damage_lg", "7")
minqlx.set_cvar("dmflags", "60")
if self.game.type_short == "ca":
minqlx.set_cvar("g_startingHealth", "200")
minqlx.set_cvar("g_startingArmor", "200")
minqlx.console_command("map_restart")
self.msg("PQL ruleset is now set.")
if msg[1].lower() == "vql":
minqlx.set_cvar("pmove_airControl", "0")
minqlx.set_cvar("pmove_rampJump", "0")
minqlx.set_cvar("weapon_reload_rg", "1500")
minqlx.set_cvar("pmove_weaponRaiseTime", "200")
minqlx.set_cvar("pmove_weaponDropTime", "200")
minqlx.set_cvar("g_damage_lg", "6")
if self.game.type_short == "ca":
minqlx.set_cvar("dmflags", "28")
else:
minqlx.console_command("reset dmflags")
minqlx.console_command("reset g_startingHealth")
minqlx.console_command("reset g_startingArmor")
minqlx.console_command("map_restart")
self.msg("VQL ruleset is now set.")
def cmd_excessive_weaps(self, player, msg, channel):
if len(msg) < 2:
return minqlx.RET_USAGE
if msg[1] == "on":
minqlx.set_cvar("weapon_reload_sg", "200")
minqlx.set_cvar("weapon_reload_rl", "200")
minqlx.set_cvar("weapon_reload_rg", "50")
minqlx.set_cvar("weapon_reload_prox", "200")
minqlx.set_cvar("weapon_reload_pg", "40")
minqlx.set_cvar("weapon_reload_ng", "800")
minqlx.set_cvar("weapon_reload_mg", "40")
minqlx.set_cvar("weapon_reload_hmg", "40")
minqlx.set_cvar("weapon_reload_gl", "200")
minqlx.set_cvar("weapon_reload_gauntlet", "100")
minqlx.set_cvar("weapon_reload_cg", "30")
minqlx.set_cvar("weapon_reload_bfg", "75")
minqlx.set_cvar("qlx_excessive", "1")
self.msg("Excessive weapons are enabled.")
if msg[1] == "off":
minqlx.console_command("reset weapon_reload_sg")
minqlx.console_command("reset weapon_reload_rl")
if (minqlx.get_cvar("pmove_airControl")) == "1":
minqlx.set_cvar("weapon_reload_rg", "1200")
else:
minqlx.console_command("reset weapon_reload_rg")
minqlx.console_command("reset weapon_reload_prox")
minqlx.console_command("reset weapon_reload_pg")
minqlx.console_command("reset weapon_reload_ng")
minqlx.console_command("reset weapon_reload_mg")
minqlx.console_command("reset weapon_reload_hmg")
minqlx.console_command("reset weapon_reload_gl")
minqlx.console_command("reset weapon_reload_gauntlet")
minqlx.console_command("reset weapon_reload_cg")
minqlx.console_command("reset weapon_reload_bfg")
minqlx.set_cvar("qlx_excessive", "0")
self.msg("Excessive weapons are disabled.")
def handle_vote_called(self, caller, vote, args):
if not (self.get_cvar("g_allowSpecVote", bool)) and caller.team == "spectator":
if caller.privileges == None:
caller.tell("You are not allowed to call a vote as spectator.")
return minqlx.RET_STOP_ALL
if vote.lower() == "infiniteammo":
# enables the '/cv infiniteammo [on/off]' command
if args.lower() == "off":
self.callvote("set g_infiniteAmmo 0", "infinite ammo: off")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "on":
self.callvote("set g_infiniteAmmo 1", "infinite ammo: on")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv infiniteammo [on/off]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "freecam":
# enables the '/cv freecam [on/off]' command
if args.lower() == "off":
self.callvote("set g_teamSpecFreeCam 0", "team spectator free-cam: off")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "on":
self.callvote("set g_teamSpecFreeCam 1", "team spectator free-cam: on")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv freecam [on/off]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "floordamage":
# enables the '/cv floordamage [on/off]' command
if args.lower() == "off":
self.callvote("set g_forceDmgThroughSurface 0", "damage through floor: off")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "on":
self.callvote("set g_forceDmgThroughSurface 1", "damage through floor: on")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv floordamage [on/off]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "alltalk":
# enables the '/cv alltalk [on/off]' command
if args.lower() == "off":
self.callvote("set g_allTalk 0", "voice comm between teams: off")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "on":
self.callvote("set g_allTalk 1", "voice comm between teams: on")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv alltalk [on/off]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "allready":
# enables the '/cv allready' command
if self.game.state == "warmup":
self.callvote("allready", "begin game immediately")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("You can't vote to begin the game when the game is already on.")
return minqlx.RET_STOP_ALL
if vote.lower() == "ruleset":
# enables the '/cv ruleset [pql/vql]' command
if (minqlx.get_cvar("qlx_rulesetLocked")) == "1":
caller.tell("Voting to change the ruleset is disabled on ruleset-locked servers.")
return minqlx.RET_STOP_ALL
if args.lower() == "pql":
self.callvote("qlx !ruleset pql", "ruleset: pql")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "vql":
self.callvote("qlx !ruleset vql", "ruleset: vql")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv ruleset [pql/vql]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "abort":
# enables the '/cv abort' command
if self.game.state != "warmup":
self.callvote("abort", "abort the game", 30)
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("You can't vote to abort the game when the game isn't in progress.")
return minqlx.RET_STOP_ALL
if vote.lower() == "chatsounds":
# enables the '/cv chatsounds [on/off]' command
if args.lower() == "off":
self.callvote("qlx !unload fun", "chat-activated sounds: off")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "on":
self.callvote("qlx !load fun", "chat-activated sounds: on")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv chatsounds [on/off]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() in ("silence", "mute"):
# enables the '/cv silence <id>' command
try:
player_name = self.player(int(args)).clean_name
player_id = self.player(int(args)).id
except:
caller.tell("^1Invalid ID.^7 Use a client ID from the ^2/players^7 command.")
return minqlx.RET_STOP_ALL
if self.get_cvar("qlx_serverExemptFromModeration") == "1":
caller.tell("This server has the serverExemptFromModeration flag set, and therefore, silencing is disabled.")
return minqlx.RET_STOP_ALL
self.callvote("qlx !silence {} 10 minutes You were call-voted silent for 10 minutes.; mute {}".format(player_id, player_id), "silence {} for 10 minutes".format(player_name))
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if vote.lower() == "tempban":
# enables the '/cv tempban <id>' command
if self.get_cvar("qlx_disablePlayerRemoval", bool):
# if player removal cvar is set, do not permit '/cv tempban'
if caller.privileges == None:
caller.tell("Voting to tempban is disabled in this server.")
caller.tell("^2/cv spec <id>^7 and ^2/cv silence <id>^7 exist as substitutes to kicking/tempbanning.")
return minqlx.RET_STOP_ALL
try:
player_name = self.player(int(args)).clean_name
player_id = self.player(int(args)).id
except:
caller.tell("^1Invalid ID.^7 Use a client ID from the ^2/players^7 command.")
return minqlx.RET_STOP_ALL
if self.player(int(args)).privileges != None:
caller.tell("The player specified is an admin, a mod or banned, and cannot be tempbanned.")
return minqlx.RET_STOP_ALL
self.callvote("tempban {}".format(player_id), "^1ban {} until the map changes^3".format(player_name))
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if vote.lower() == "spec":
# enables the '/cv spec <id>' command
try:
player_name = self.player(int(args)).clean_name
player_id = self.player(int(args)).id
except:
caller.tell("^1Invalid ID.^7 Use a client ID from the ^2/players^7 command.")
return minqlx.RET_STOP_ALL
if self.player(int(args)).team == "spectator":
caller.tell("That player is already in the spectators.")
return minqlx.RET_STOP_ALL
self.callvote("put {} spec".format(player_id), "move {} to the spectators".format(player_name))
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if vote.lower() == "excessive":
# enables the '/cv excessive [on/off]' command
if args.lower() == "off":
self.callvote("qlx !excessiveweaps off", "excessive weapons: off")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "on":
self.callvote("qlx !excessiveweaps on", "excessive weapons: on")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv excessive [on/off]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() in ("kick", "clientkick"):
# if player removal cvar is set, do not permit '/cv kick' or '/cv clientkick'
if self.get_cvar("qlx_disablePlayerRemoval", bool):
if caller.privileges == None:
caller.tell("Voting to kick/clientkick is disabled in this server.")
caller.tell("^2/cv spec <id>^7 and ^2/cv silence <id>^7 exist as substitutes to kicking.")
return minqlx.RET_STOP_ALL
if vote.lower() == "lock":
# enables the '/cv lock <team>' command
if len(args) <= 1:
self.callvote("lock", "lock all teams")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
if args.lower() == "blue":
self.callvote("lock blue", "lock the ^4blue^3 team")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "red":
self.callvote("lock red", "lock the ^1red^3 team")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv lock^7 or ^2/cv lock <blue/red>^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "unlock":
# enables the '/cv unlock <team>' command
if len(args) <= 1:
self.callvote("unlock", "unlock all teams")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
if args.lower() == "blue":
self.callvote("unlock blue", "unlock the ^4blue^3 team")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "red":
self.callvote("unlock red", "unlock the ^1red^3 team")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv unlock^7 or ^2/cv unlock <blue/red>^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "balancing":
# enables the '/cv balancing on/off' command
if args.lower() == "off":
self.callvote("qlx !unload balance", "glicko-based team balancing: off")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "on":
self.callvote("qlx !load balance", "glicko-based team balancing: on")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv balancing [on/off]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "roundtimelimit":
# enables the '/cv roundtimelimit [90/120/180]' command
if args.lower() == "180":
self.callvote("set roundtimelimit 180", "round time limit: 180")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if args.lower() == "120":
self.callvote("set roundtimelimit 120", "round time limit: 120")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if args.lower() == "90":
self.callvote("set roundtimelimit 90", "round time limit: 90")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv roundtimelimit [90/120/180]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "balance":
# enables the '/cv balance' command
self.callvote("qlx !balance", "balance the teams")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if vote.lower() == "lgammo":
# enables the '/cv lgammo [150/200]' command
if args.lower() == "150":
self.callvote("set g_startingAmmo_lg 150", "Lightning gun ammo: 150")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if args.lower() == "200":
self.callvote("set g_startingAmmo_lg 200", "Lightning gun ammo: 200")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv lgammo [150/200]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "glammo":
# enables the '/cv glammo [25/10/6]' command
if args.lower() == "25":
self.callvote("set g_startingAmmo_gl 25", "Grenade launcher ammo: 25")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if args.lower() == "10":
self.callvote("set g_startingAmmo_gl 10", "Grenade launcher ammo: 10")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if args.lower() == "6":
self.callvote("set g_startingAmmo_gl 6", "Grenade launcher ammo: 6")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv glammo [25/10/6]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "lgdamage":
# enables the '/cv lgdamage [6/7]' command
if args.lower() == "6":
self.callvote("set g_damage_lg 6; set g_knockback_lg 1.75", "^7Lightning gun damage: 6")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if args.lower() == "7":
self.callvote("set g_damage_lg 7; set g_knockback_lg 1.50", "^7Lightning gun damage: 7 (with appropriate knockback)")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv lgdamage [6/7]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "rgdamage":
# enables the '/cv rgdamage [80/100]' command
if args.lower() == "80":
self.callvote("set g_damage_rg 80", "^2Railgun^3 damage: 80")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
if args.lower() == "100":
self.callvote("set g_damage_rg 100", "^2Railgun^3 damage: 100")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv rgdamage [80/100]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "runes":
# enables the '/cv runes on/off' command
if self.game.state != "warmup":
caller.tell("Voting to alter runes is only allowed during the warm-up period.")
return minqlx.RET_STOP_ALL
if args.lower() == "off":
self.callvote("set g_runes 0; map_restart", "runes: off")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
elif args.lower() == "on":
self.callvote("set g_runes 1; map_restart", "runes: on")
self.msg("{}^7 called a vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv runes [on/off]^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
if vote.lower() == "cvar":
if not self.get_cvar("qlx_disableCvarVoting", bool):
if not len(args) <= 1:
# enables the '/cv cvar <variable> <value>' command
if self.db.has_permission(caller.steam_id, self.get_cvar("qlx_cvarVotePermissionRequired", int)):
self.callvote("set {}".format(args), "Server CVAR change: {}^3".format(args))
self.msg("{}^7 called a server vote.".format(caller.name))
return minqlx.RET_STOP_ALL
else:
caller.tell("^1Insufficient privileges to change a server cvar.^7 Permission Level required: ^43^7.")
return minqlx.RET_STOP_ALL
else:
caller.tell("^2/cv cvar <variable> <value>^7 is the usage for this callvote command.")
return minqlx.RET_STOP_ALL
else:
caller.tell("Voting to change server CVARs is disabled on this server.")
return minqlx.RET_STOP_ALL
if vote.lower() == "do":
if "balance" in self.plugins:
if self.plugins["balance"].suggested_pair:
self.callvote("qlx !do", "force the suggested switch")
self.msg("{}^7 called a vote.".format(caller.name))
else:
caller.tell("A switch hasn't been suggested yet by ^4!teams^7, you cannot vote to apply a suggestion that doesn't exist.")
else:
caller.tell("The ^4balance^7 system isn't currently loaded. This vote cannot function.")
return minqlx.RET_STOP_ALL
def cmd_showversion(self, player, msg, channel):
channel.reply("^4custom_votes.py^7 - version {}, created by Thomas Jones on 01/01/2016.".format(self.plugin_version))