Modify idlemove module to be able to chain thresholds for moving and add source channel filters

This commit is contained in:
Stefan Hacker
2010-12-27 02:42:23 +01:00
parent bf006394da
commit b25b446f84
6 changed files with 96 additions and 58 deletions

View File

@@ -93,7 +93,7 @@ def x2bool(s):
if isinstance(s, bool): if isinstance(s, bool):
return s return s
elif isinstance(s, basestring): elif isinstance(s, basestring):
return s.lower() in ['1', 'true'] return s.strip().lower() in ['1', 'true']
raise ValueError() raise ValueError()
def commaSeperatedIntegers(s): def commaSeperatedIntegers(s):
@@ -109,3 +109,10 @@ def commaSeperatedStrings(s):
containing comma seperated strings into a list of strings containing comma seperated strings into a list of strings
""" """
return map(str.strip, s.split(',')) return map(str.strip, s.split(','))
def commaSeperatedBool(s):
"""
Helper function to convert a string from the config
containing comma seperated strings into a list of booleans
"""
return map(x2bool, s.split(','))

View File

@@ -30,7 +30,7 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import unittest import unittest
from config import Config, x2bool, commaSeperatedIntegers, commaSeperatedStrings from config import Config, x2bool, commaSeperatedIntegers, commaSeperatedStrings, commaSeperatedBool
from tempfile import mkstemp from tempfile import mkstemp
import os import os
import re import re
@@ -88,13 +88,13 @@ value = True
os.remove(path) os.remove(path)
def testX2bool(self): def testX2bool(self):
assert(x2bool("true") == True) assert(x2bool(" true") == True)
assert(x2bool("false") == False) assert(x2bool("false") == False)
assert(x2bool("TrUe") == True) assert(x2bool(" TrUe") == True)
assert(x2bool("FaLsE") == False) assert(x2bool("FaLsE ") == False)
assert(x2bool("0") == False) assert(x2bool("0 ") == False)
assert(x2bool("1") == True) assert(x2bool("1") == True)
assert(x2bool("10") == False) assert(x2bool(" 10") == False)
assert(x2bool("notabool") == False) assert(x2bool("notabool") == False)
def testCommaSeperatedIntegers(self): def testCommaSeperatedIntegers(self):
@@ -104,6 +104,9 @@ value = True
def testCommaSeperatedStrings(self): def testCommaSeperatedStrings(self):
assert(commaSeperatedStrings("Bernd, the, bred !") == ["Bernd", "the", "bred !"]) assert(commaSeperatedStrings("Bernd, the, bred !") == ["Bernd", "the", "bred !"])
def testCommaSeperatedBool(self):
assert(commaSeperatedBool("tRue ,false, 0, 0, 1,1, test") == [True, False, False, False, True, True, False])
def testConfig(self): def testConfig(self):
path = create_file(self.cfg_content) path = create_file(self.cfg_content)
try: try:

View File

@@ -13,6 +13,9 @@ interval = 10
servers = servers =
[all] [all]
; All parameters in here also take a comma seperated list of values.
; You can use this to chain idle thresholds.
; Time in seconds after which to consider a player idle ; Time in seconds after which to consider a player idle
threshold = 3600 threshold = 3600
; Mute the player idle ; Mute the player idle
@@ -21,6 +24,8 @@ mute = True
deafen = False deafen = False
; Id of the channel to move the player to when idle ; Id of the channel to move the player to when idle
channel = 0 channel = 0
; Channel the player has to be in for this treshold rule to affect him (-1 == Any)
;source_channel = -1
; For every server you want to override the [all] section for create ; For every server you want to override the [all] section for create
; a [server_<serverid>] section. For example: ; a [server_<serverid>] section. For example:

View File

@@ -33,12 +33,13 @@
# idlemove.py # idlemove.py
# #
# Module for moving/muting/deafening idle players after # Module for moving/muting/deafening idle players after
# a certain amount of time and moving them back once # a certain amount of time and unmuting/undeafening them
# they interact again. # once they become active again
# #
from mumo_module import (x2bool, from mumo_module import (x2bool,
commaSeperatedIntegers, commaSeperatedIntegers,
commaSeperatedBool,
MumoModule, MumoModule,
Config) Config)
@@ -53,18 +54,12 @@ class idlemove(MumoModule):
('interval', float, 0.1), ('interval', float, 0.1),
('servers', commaSeperatedIntegers, []), ('servers', commaSeperatedIntegers, []),
), ),
'all':( lambda x: re.match('(all)|(server_\d+)', x):(
('threshold', int, 3600), ('threshold', commaSeperatedIntegers, [3600]),
('mute', x2bool, True), ('mute', commaSeperatedBool, [True]),
('deafen', x2bool, False), ('deafen', commaSeperatedBool, [False]),
('channel', int, 1) ('channel', commaSeperatedIntegers, [1]),
), ('source_channel', commaSeperatedIntegers, [-1])
lambda x: re.match('server_\d+', x):(
('threshold', int, 3600),
('mute', x2bool, True),
('deafen', x2bool, False),
('channel', int, 1),
('restore', x2bool, True)
), ),
} }
@@ -134,41 +129,66 @@ class idlemove(MumoModule):
self.affectedusers[sid] = set() self.affectedusers[sid] = set()
index = self.affectedusers[sid] index = self.affectedusers[sid]
# Remember values so we can see changes later
threshold = None
mute = user.mute
deafen = user.deaf
channel = user.channel
update = False update = False
if not user in index and user.idlesecs > scfg.threshold: over_threshold = False
if scfg.deafen \
and not (user.suppress or user.selfMute or user.mute) \
and not (user.selfDeaf or user.deaf):
log.info('Mute and deafen user %s (%d / %d) on server %d', user.name, user.session, user.userid, sid)
user.deaf = True
update = True
elif scfg.mute and not (user.suppress or user.selfMute or user.mute):
log.info('Mute user %s (%d / %d) on server %d', user.name, user.session, user.userid, sid)
user.mute = True
update = True
if scfg.channel >= 0 and user.channel != scfg.channel: # Search all our stages top down for a violated treshold and pick the first
log.info('Move user %s (%d / %d) on server %d', user.name, user.session, user.userid, sid) for i in range(len(scfg.threshold) - 1, -1, -1):
user.channel = scfg.channel try:
update = True source_channel = scfg.source_channel[i]
except IndexError:
source_channel = -1
if update: try:
index.add(user.session) threshold = scfg.threshold[i]
mute = scfg.mute[i]
deafen = scfg.deafen[i]
channel = scfg.channel[i]
except IndexError:
log.warning("Incomplete configuration for stage %d of server %i, ignored", i, server.id())
continue
elif user.session in index and user.idlesecs < scfg.threshold: if user.idlesecs > threshold and\
(source_channel == -1 or\
user.channel == source_channel or\
user.channel == channel):
over_threshold = True
# Update if state changes needed
if user.deaf != deafen:
update = True
if user.mute != mute:
update = True
if channel >= 0 and user.channel != channel:
update = True
if update:
index.add(user.session)
log.info('%ds > %ds: State transition for user %s (%d/%d) from mute %s -> %s / deaf %s -> %s | channel %d -> %d on server %d',
user.idlesecs, threshold, user.name, user.session, user.userid, user.mute, mute, user.deaf, deafen,
user.channel, channel, server.id())
break
if not over_threshold and user.session in self.affectedusers[sid]:
deafen = False
mute = False
channel = user.channel
index.remove(user.session) index.remove(user.session)
if scfg.deafen: log.info("Restore user %s (%d/%d) on server %d", user.name, user.session, user.userid, server.id())
log.info('Unmute and undeafen user %s (%d / %d) on server %d', user.name, user.session, user.userid, sid) update = True
user.mute = False
user.deaf = False
update = True
elif scfg.mute:
log.info('Unmute user %s (%d / %d) on server %d', user.name, user.session, user.userid, sid)
user.mute = False
update = True
if update: if update:
user.deaf = deafen
user.mute = mute
user.channel = channel
server.setState(user) server.setState(user)
# #
#--- Server callback functions #--- Server callback functions
# #

View File

@@ -374,11 +374,12 @@ def do_main_program():
manager.stopModules() manager.stopModules()
manager.stop() manager.stop()
info('Shutdown complete') info('Shutdown complete')
return state
class CustomLogger(Ice.Logger): class CustomLogger(Ice.Logger):
""" """
Logger implementation to pipe Ice log messages into Logger implementation to pipe Ice log messages into
out own log our own log
""" """
def __init__(self): def __init__(self):
@@ -459,12 +460,13 @@ if __name__ == '__main__':
print >> sys.stderr, 'Fatal error, could not daemonize process due to missing "daemon" library, ' \ print >> sys.stderr, 'Fatal error, could not daemonize process due to missing "daemon" library, ' \
'please install the missing dependency and restart the authenticator' 'please install the missing dependency and restart the authenticator'
sys.exit(1) sys.exit(1)
do_main_program() ret = do_main_program()
else: else:
context = daemon.DaemonContext(working_directory=sys.path[0], context = daemon.DaemonContext(working_directory=sys.path[0],
stderr=logfile) stderr=logfile)
context.__enter__() context.__enter__()
try: try:
do_main_program() ret = do_main_program()
finally: finally:
context.__exit__(None, None, None) context.__exit__(None, None, None)
sys.exit(ret)

View File

@@ -32,7 +32,8 @@
from config import (Config, from config import (Config,
x2bool, x2bool,
commaSeperatedIntegers, commaSeperatedIntegers,
commaSeperatedStrings) commaSeperatedStrings,
commaSeperatedBool)
from worker import Worker from worker import Worker