Pages: 1 [2] 3 4   Go Down
  Print  
Author Topic: Voting Plugin  (Read 3173 times)
[ www.xlrstats.com ]
Project leader
Hero Member
*****
OS: Linux
Type: Owner dedicated server(s)
Gameservers: CoD, CoD2, CoD5, UrT
Posts: 1209
Offline Offline
WWW
« Reply #15 on: December 27, 2009, 02:31:52 AM »

My suggestion is that the developer of the plugin resets the votes on mapstart or mapend by adding a reset and release mechanism to the plugin, so this locked vote occurrence does not last longer than a map or round. It needs to reset itself to prevent this.

This is not a bug in the plugin, it just needs a minor modification. This event might happen when the rcon queue is too large, or the server is changing maps, or whatever so that the bot doesn't get to process to end the vote for whatever reason.

Since Ismael is the programmer for this plugin it's up to him to add/solve this.
Logged


Serving: CoD2 | CoD5 | UrT4.1
Dev. Team
Hero Member
*****
Posts: 1037
Offline Offline
Don't contact me on Xfire! I will just reject you!
« Reply #16 on: December 27, 2009, 02:48:48 AM »

Link

A map vote would not trigger a new map event, doing this would mean that after a vote you could be left without a vote for a whole map. I don't think adding an event based trigger would be good in this case.
« Last Edit: December 27, 2009, 02:51:17 AM by Bakes » Logged

Full Member
***
OS: Linux
Type: Owner dedicated server(s)
Gameservers: CoD4
Posts: 50
Offline Offline
« Reply #17 on: December 27, 2009, 05:12:57 AM »

About your link:
Quote
ou are not a participant in this wave.

Don't matter WHO fix this "small" problem, if somebody does it it's ok  Wink
Logged
Dev. Team
Hero Member
*****
Posts: 1037
Offline Offline
Don't contact me on Xfire! I will just reject you!
« Reply #18 on: December 27, 2009, 05:57:24 AM »

Yeah, that link was for xlr8or, who is a participant Wink

I'm writing my own mapvote plugin at the moment, which works differently. Should be done tonight, I'm writing it around that bug.
Logged

Full Member
***
OS: Linux
Type: Owner dedicated server(s)
Gameservers: CoD4
Posts: 50
Offline Offline
« Reply #19 on: December 27, 2009, 06:11:44 AM »

That is realy nice! Thank you already for you time etc.
Logged
Full Member
***
OS: Linux
Type: Owner dedicated server(s)
Gameservers: CoD4
Posts: 50
Offline Offline
« Reply #20 on: January 01, 2010, 10:09:08 AM »

Please, is the code ready  Huh  Roll Eyes
Logged
Jr. Member
**
Posts: 14
Offline Offline
« Reply #21 on: January 06, 2010, 01:11:09 PM »

If anybody is interestet i have changed this plugin to enable !votenextmap ( !vnm )

The vote.py is now

Code:
# BigBrotherBot(B3) (www.bigbrotherbot.com)
# Plugin for allowing registered users to kick
# Copyright (C) 2009 Ismael Garrido
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# CHANGELOG
# 06/01/10
# Added !votenextmap and !vnm
# 25/07/09
# Added !votemap
# Revamped the system, more modular now.
# 12/06/09
# !vk requires a motive to kick
# If more than a certain percent of voters vote yes, the victim is tempbanned
# added !vkveto
# Modlevel is read from admin plugin settings (thanks Bakes)
# 30/05/09
# Added delays between failed votes
# Initial version

__version__ = '1.6'
__author__  = 'KnightOrk'



import b3
import b3.plugin
import b3.cron
from b3 import clients

class VotingPlugin(b3.plugin.Plugin):
_adminPlugin = None
_currentVote = None

_caller = None

_in_progress = False
_yes = 0
_no = 0
_vetoed = 0
_times = 0
_vote_times = 3
_vote_interval = 0

_votes = {}

def startup(self):
"""\
Initialize plugin settings
"""

# get the plugin so we can register commands
self._adminPlugin = self.console.getPlugin('admin')
if not self._adminPlugin:
# something is wrong, can't start without admin plugin
self.error('Could not find admin plugin')
return False

self._vote_times = self.config.getint('settings', 'vote_times')
self._vote_interval = self.config.getint('settings', 'vote_interval')
minLevel_vote = self.config.getint('settings', 'min_level_vote')
modLevel = self._adminPlugin.config.getint("settings","admins_level") 

self._adminPlugin.registerCommand(self, 'voteyes', minLevel_vote,  self.cmd_voteyes,  'vy')
self._adminPlugin.registerCommand(self, 'voteno', minLevel_vote, self.cmd_voteno,  'vn')
self._adminPlugin.registerCommand(self, 'voteveto', modLevel, self.cmd_veto,  'vveto')

minLevel_kick = self.config.getint('votekick', 'min_level_kick')
self._adminPlugin.registerCommand(self, 'votekick', minLevel_kick, self.cmd_votekick,  'vk')

self._votes["kick"] = KickVote()
self._votes["kick"].startup(self._adminPlugin,  self.console,  self.config)

minLevel_map = self.config.getint('votemap', 'min_level_map')
self._adminPlugin.registerCommand(self, 'votemap', minLevel_map, self.cmd_votemap,  'vm')
self._adminPlugin.registerCommand(self, 'maplist', 0, self.cmd_maplist,  'mapl')
self._votes["map"] = MapVote()
self._votes["map"].startup(self._adminPlugin,  self.console,  self.config)

minLevel_nextmap = self.config.getint('votemap', 'min_level_nextmap')
self._adminPlugin.registerCommand(self, 'votenextmap', minLevel_nextmap, self.cmd_votenextmap,  'vnm')
self._votes["nextmap"] = NextMapVote()
self._votes["nextmap"].startup(self._adminPlugin,  self.console,  self.config)



def cmd_maplist(self,  data,  client,  cmd=None):
client.message("Maps available: " + ", ".join(self._votes["map"]._mapList))

def pre_vote(self,  client):
if self._in_progress:
client.message("A vote is already in progress, wait until it finishes")
return False

if client.var(self,  'holding_vote').value:
client.message("You have to wait between failed votes!")
return False
return True


def cmd_votekick(self, data, client, cmd=None):
"""\
<name> <motive> - call a votekick on that player for that motive
"""
if not self.pre_vote(client):
return False

self._currentVote = self._votes["kick"]

if not self._currentVote.start_vote(data,  client):
return False

self.go_vote(client)

def cmd_votemap(self, data, client, cmd=None):
"""\
<map> - call a votemap for that map
"""
if not self.pre_vote(client):
return False

self._currentVote = self._votes["map"]

if not self._currentVote.start_vote(data,  client):
return False

self.go_vote(client)


def cmd_votenextmap(self, data, client, cmd=None):
"""\
<map> - call a votemap for Nextmap
"""
if not self.pre_vote(client):
return False

self._currentVote = self._votes["nextmap"]

if not self._currentVote.start_vote(data,  client):
return False

self.go_vote(client)

def go_vote(self,  client):
self._caller = client
self._in_progress = True
self._times = self._vote_times
self._no = 0
self._vetoed = 0

self._yes = 1
client.var(self,  'voted').value = True #The caller of the vote votes yes by default

reason = self._currentVote.vote_reason()
self.console.say("Calling a vote " + reason)
self.console.say("Type ^1!vy ^7to vote ^1yes^7, ^2!vn ^7to vote ^2no")
self.console.cron + b3.cron.OneTimeCronTab(self.update_vote,  "*/1")


def cmd_veto(self, data, client, cmd=None):
self._vetoed = 1

def update_vote(self):
if not self._vetoed:
reason = self._currentVote.vote_reason()
self.console.say("[%d/%d] Voting " % (self._vote_times - self._times + 1,  self._vote_times) + reason)
self.console.say("Type ^1!vy ^7to vote ^1yes^7, ^2!vn ^7to vote ^2no")
self.console.say("^1Yes: %s^7, ^2No: %s" %(self._yes,  self._no))
self._times -= 1
if self._times > 0:
self.console.cron + b3.cron.OneTimeCronTab(self.update_vote,  "*/1")
else:
self.console.cron + b3.cron.OneTimeCronTab(self.end_vote,  "*/1")
else:
self.console.say("Vote ^1vetoed!")
self._in_progress = False
self._currentVote = None

def end_vote(self):
self.console.say("Vote ended")
self.console.say("^1Yes: %s^7, ^2No: %s" %(self._yes,  self._no))
if self._yes > self._no:
self._currentVote.end_vote_yes(self._yes,  self._no)
else:
self._currentVote.end_vote_no(self._yes,  self._no)
#The vote failed, the caller can't call another vote for a while
self._caller.var(self,  'holding_vote').value = True
temp = self._caller
def let_caller_vote():
self.debug("clearing %s" % temp.exactName)
temp.var(self,  'holding_vote').value = False

self.console.cron + b3.cron.OneTimeCronTab(let_caller_vote,  0, "*/%s" %self._vote_interval)

self._in_progress = False
self._currentVote = None

for c in self.console.clients.getList():
c.var(self,  'voted').value = False

def cmd_voteyes(self, data, client, cmd=None):
if self.vote(client,  cmd):
self._yes += 1
cmd.sayLoudOrPM(client,  "Voted ^1YES")

def cmd_voteno(self, data, client, cmd=None):
if self.vote(client,  cmd):
self._no += 1
cmd.sayLoudOrPM(client,  "Voted ^2NO")

def vote(self,  client,  cmd):
if self._in_progress:
if not client.var(self,  'voted').value:
client.var(self,  'voted').value = True
return True
else:
cmd.sayLoudOrPM(client,  "You already voted!")
else:
cmd.sayLoudOrPM(client,  "No vote in progress")
return False

class KickVote(object):
_adminPlugin = None
console = None
config = None

_victim = None
_caller = None
_reason = None

_modLevel = 20

_tempban_interval = 0
_tempban_percent = 0
_tempban_minvotes = 0

def startup(self,  adminPlugin,  console,  config):
"""\
Initialize plugin settings
"""

self._adminPlugin = adminPlugin
self.console = console
self.config = config

self._modLevel = self._adminPlugin.config.getint("settings","admins_level") 

self._tempban_minvotes = self.config.getint('votekick', 'tempban_minvotes')
self._tempban_interval = self.config.getint('votekick', 'tempban_interval')
self._tempban_percent = self.config.getint('votekick', 'tempban_percent')

def start_vote(self,  data,  client):
m = self._adminPlugin.parseUserCmd(data)
if not m:
client.message('^7Invalid parameters')
return False
if not m[1]:
client.message('^7Invalid parameters, must provide a reason!')
return False
if len(m[1]) < 3:
client.message("^7You should write a better motive")

cid = m[0]
sclient = self._adminPlugin.findClientPrompt(cid, client)
if not sclient:
return False

if sclient.maxLevel >= self._modLevel:
client.message("You can't kick an admin!")
return False

self._caller = client
self._victim = sclient
self._reason = m[1]
return True

def vote_reason(self):
return "against ^3%s because ^3%s" % (self._victim.exactName,  self._reason)

def end_vote_yes(self,  yes,  no):
self.console.say("^1KICKING ^3%s" %self._victim.exactName)
self._victim.kick("by popular vote",  None)
if self._tempban_interval and (yes*100.0 / no) > self._tempban_percent and yes > self._tempban_minvotes:
self._victim.tempban("", "Voted out", self._tempban_interval, None)
self._victim = None

def end_vote_no(self,  yes,  no):
self.console.say("Player is ^2safe!")
self._victim = None


class MapVote:
_adminPlugin = None
console = None
config = None

_mapList = []
_caller = None
_map= None

def startup(self,  adminPlugin,  console,  config):
"""\
Initialize plugin settings
"""

self._adminPlugin = adminPlugin
self.console = console
self.config = config

f = open(self.config.getpath('votemap',  'mapfile'))
for line in f:
self._mapList.append(line.strip())


def start_vote(self,  data,  client):
m = self._adminPlugin.parseUserCmd(data)
if not m:
client.message('^7Invalid parameters')
return False
if not m[0]:
client.message('^7Invalid parameters, must provide a map to vote!')
return False

s = m[0]
matched = False

for map in self._mapList:
if s in map:
self._map  = map
if matched:
client.message('^7More than one map matches the name, be more specific')
return False
matched = True

if not matched:
client.message('^7No map matched that name')
return matched


def vote_reason(self):
return "to change map to ^3%s" % (self._map)

def end_vote_yes(self,  yes,  no):
self.console.say("^1Changing map to ^3%s" %self._map)
self.console.write("map %s" %self._map)

def end_vote_no(self,  yes,  no):
self.console.say("Map ^2stays!")


class NextMapVote:
_adminPlugin = None
console = None
config = None

_mapList = []
_caller = None
_map= None

def startup(self,  adminPlugin,  console,  config):
"""\
Initialize plugin settings
"""

self._adminPlugin = adminPlugin
self.console = console
self.config = config

f = open(self.config.getpath('votemap',  'mapfile'))
for line in f:
self._mapList.append(line.strip())


def start_vote(self,  data,  client):
m = self._adminPlugin.parseUserCmd(data)
if not m:
client.message('^7Invalid parameters')
return False
if not m[0]:
client.message('^7Invalid parameters, must provide a map to vote!')
return False

s = m[0]
matched = False

for map in self._mapList:
if s in map:
self._map  = map
if matched:
client.message('^7More than one map matches the name, be more specific')
return False
matched = True

if not matched:
client.message('^7No map matched that name')
return matched


def vote_reason(self):
return "to change Nextmap to ^3%s" % (self._map)

def end_vote_yes(self,  yes,  no):
self.console.say("^1Changing Nextmap to ^3%s" %self._map)
self.console.write("g_nextmap %s" %self._map)

def end_vote_no(self,  yes,  no):
self.console.say("^2Next map: ^3" + self.console.getNextMap())
   

And the voting.xml:

Code:
<configuration plugin="votekick">
<settings name="settings">
<set name="min_level_vote">0</set>

<set name="vote_times">3</set>
<set name="vote_interval">3</set>
</settings>

<settings name="votekick">
<set name="min_level_kick">20</set>

<set name="tempban_minvotes">3</set>
<set name="tempban_interval">3</set>
<set name="tempban_percent">75</set>
</settings>

<settings name="votemap">
<set name="min_level_map">60</set>
<set name="min_level_nextmap">20</set>
<set name="mapfile">/home/knightork/urbanterror/q3ut4/maps.txt</set>
</settings>

</configuration>
Logged
Full Member
***
OS: Linux
Type: Owner dedicated server(s)
Gameservers: CoD4
Posts: 50
Offline Offline
« Reply #22 on: January 06, 2010, 01:12:59 PM »

Thank you very much, but did you fix also the bug in this plugin? Because when people call a vote, most of the time they get the message:
Quote
A vote is already in progress, wait until it finishes

Besides that I think there is a better way to get the list of maps without using maps.txt file.

...

« Last Edit: January 06, 2010, 01:14:53 PM by danger89 » Logged
Dev. Team
Hero Member
*****
Posts: 1037
Offline Offline
Don't contact me on Xfire! I will just reject you!
« Reply #23 on: January 07, 2010, 05:42:37 AM »

If I'm thinking what you're thinking, not in all games, and if you want to have a 'crossfire/crash/broadcast 24/7 server' where people could only play on those maps it doesn't give you the freedom to choose maps.
Logged

Full Member
***
OS: Linux
Type: Owner dedicated server(s)
Gameservers: CoD4
Posts: 50
Offline Offline
« Reply #24 on: January 07, 2010, 07:50:01 AM »

@Bakes
Ok, you got a point here. I think you can read the maprotation, but this methode gives you more opportunities.

And also, did you finished to "small" bug in this plugin, I mentioned in my post before...?
Logged
Jr. Member
**
Posts: 14
Offline Offline
« Reply #25 on: January 09, 2010, 03:32:14 PM »

I don't use mapcycle because we had some problems with the !maplist.

We made some Changings in Mapcycle like maxplayers, gravity and so on. If you use this File !maplist also lists all that custom changings too.

I will have a look to this bug.

How do you get this Bug? What Game?

I play UrbanTerror 4.1 and everythink is working fine until now.

But we have hard settings... Only Mods can start !votenextmap and only Admins can start a !votemap (But Every Player can use !voteyes and !voteno)
Logged
Full Member
***
OS: Linux
Type: Owner dedicated server(s)
Gameservers: CoD4
Posts: 50
Offline Offline
« Reply #26 on: January 09, 2010, 03:38:00 PM »

@NightOrk
Bakes says the following to me:
Quote
I'm writing my own mapvote plugin at the moment, which works differently. Should be done tonight, I'm writing it around that bug.

But that "tonight" is now atleast 2 weeks ago. I got this bug just almost always. I got also harcore settings but I use B3 for the game 'Call of Duty 4' v1.7.

So if people try to vote, b3 says 9 of 10 times:
Quote
A vote is already in progress, wait until it finishes
If you want to call a vote, for example: !votemap or !votekick. Even if there is no other vote in process or recently.
« Last Edit: January 09, 2010, 03:41:46 PM by danger89 » Logged
Full Member
***
OS: Linux
Type: Owner dedicated server(s)
Gameservers: CoD4
Posts: 50
Offline Offline
« Reply #27 on: January 13, 2010, 10:40:39 AM »

Still nothing Bakes  Huh
Logged
Full Member
***
OS: Linux
Type: Home user
Gameservers: UrT
Posts: 70
Offline Offline
« Reply #28 on: January 14, 2010, 10:59:56 AM »

I can't fix the bug if I can't reproduce it. Please send me your game logs and b3 logs where the lockup occurs and I'll try to fix it.
Logged
Jr. Member
**
Posts: 14
Offline Offline
« Reply #29 on: January 14, 2010, 12:34:01 PM »

My first try to fix it is this for voting.py

Now there should be an Event handeler that reset Votes on Round Start. It should prevent that if a vote is in progress and the Map changes the Vote will be reset. Please be careful I only tested it 1 Day and I am no Developer only stupid PHP Noob ;-)
« Last Edit: January 20, 2010, 12:07:07 AM by KnightOrk » Logged
Tags:
Pages: 1 [2] 3 4   Go Up
  Print  
 
Jump to: