From b25b446f842f4dcfd9387134c58a2c2bf23e8c09 Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Mon, 27 Dec 2010 02:42:23 +0100 Subject: [PATCH] Modify idlemove module to be able to chain thresholds for moving and add source channel filters --- config.py | 9 ++- config_test.py | 15 +++-- modules-available/idlemove.ini | 5 ++ modules/idlemove.py | 114 +++++++++++++++++++-------------- mumo.py | 8 ++- mumo_module.py | 3 +- 6 files changed, 96 insertions(+), 58 deletions(-) diff --git a/config.py b/config.py index 4459014..bbd6d30 100644 --- a/config.py +++ b/config.py @@ -93,7 +93,7 @@ def x2bool(s): if isinstance(s, bool): return s elif isinstance(s, basestring): - return s.lower() in ['1', 'true'] + return s.strip().lower() in ['1', 'true'] raise ValueError() def commaSeperatedIntegers(s): @@ -109,3 +109,10 @@ def commaSeperatedStrings(s): containing comma seperated strings into a list of strings """ 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(',')) diff --git a/config_test.py b/config_test.py index 0c181c4..9f7eff3 100644 --- a/config_test.py +++ b/config_test.py @@ -30,7 +30,7 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import unittest -from config import Config, x2bool, commaSeperatedIntegers, commaSeperatedStrings +from config import Config, x2bool, commaSeperatedIntegers, commaSeperatedStrings, commaSeperatedBool from tempfile import mkstemp import os import re @@ -88,13 +88,13 @@ value = True os.remove(path) def testX2bool(self): - assert(x2bool("true") == True) + assert(x2bool(" true") == True) assert(x2bool("false") == False) - assert(x2bool("TrUe") == True) - assert(x2bool("FaLsE") == False) - assert(x2bool("0") == False) + assert(x2bool(" TrUe") == True) + assert(x2bool("FaLsE ") == False) + assert(x2bool("0 ") == False) assert(x2bool("1") == True) - assert(x2bool("10") == False) + assert(x2bool(" 10") == False) assert(x2bool("notabool") == False) def testCommaSeperatedIntegers(self): @@ -103,6 +103,9 @@ value = True def testCommaSeperatedStrings(self): 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): path = create_file(self.cfg_content) diff --git a/modules-available/idlemove.ini b/modules-available/idlemove.ini index 2d89d1f..8cdafb7 100644 --- a/modules-available/idlemove.ini +++ b/modules-available/idlemove.ini @@ -13,6 +13,9 @@ interval = 10 servers = [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 threshold = 3600 ; Mute the player idle @@ -21,6 +24,8 @@ mute = True deafen = False ; Id of the channel to move the player to when idle 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 ; a [server_] section. For example: diff --git a/modules/idlemove.py b/modules/idlemove.py index 0da1ebc..ad94e0f 100644 --- a/modules/idlemove.py +++ b/modules/idlemove.py @@ -33,12 +33,13 @@ # idlemove.py # # Module for moving/muting/deafening idle players after -# a certain amount of time and moving them back once -# they interact again. +# a certain amount of time and unmuting/undeafening them +# once they become active again # from mumo_module import (x2bool, commaSeperatedIntegers, + commaSeperatedBool, MumoModule, Config) @@ -53,18 +54,12 @@ class idlemove(MumoModule): ('interval', float, 0.1), ('servers', commaSeperatedIntegers, []), ), - 'all':( - ('threshold', int, 3600), - ('mute', x2bool, True), - ('deafen', x2bool, False), - ('channel', int, 1) - ), - lambda x: re.match('server_\d+', x):( - ('threshold', int, 3600), - ('mute', x2bool, True), - ('deafen', x2bool, False), - ('channel', int, 1), - ('restore', x2bool, True) + lambda x: re.match('(all)|(server_\d+)', x):( + ('threshold', commaSeperatedIntegers, [3600]), + ('mute', commaSeperatedBool, [True]), + ('deafen', commaSeperatedBool, [False]), + ('channel', commaSeperatedIntegers, [1]), + ('source_channel', commaSeperatedIntegers, [-1]) ), } @@ -133,42 +128,67 @@ class idlemove(MumoModule): except KeyError: self.affectedusers[sid] = set() index = self.affectedusers[sid] - - update = False - if not user in index and user.idlesecs > scfg.threshold: - 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: - log.info('Move user %s (%d / %d) on server %d', user.name, user.session, user.userid, sid) - user.channel = scfg.channel - update = True - - if update: - index.add(user.session) - - elif user.session in index and user.idlesecs < scfg.threshold: - index.remove(user.session) - if scfg.deafen: - log.info('Unmute and undeafen user %s (%d / %d) on server %d', user.name, user.session, user.userid, sid) - 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 + # Remember values so we can see changes later + threshold = None + mute = user.mute + deafen = user.deaf + channel = user.channel + + update = False + over_threshold = False + + # Search all our stages top down for a violated treshold and pick the first + for i in range(len(scfg.threshold) - 1, -1, -1): + try: + source_channel = scfg.source_channel[i] + except IndexError: + source_channel = -1 + + try: + 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 + + 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) + log.info("Restore user %s (%d/%d) on server %d", user.name, user.session, user.userid, server.id()) + update = True + if update: + user.deaf = deafen + user.mute = mute + user.channel = channel server.setState(user) + # #--- Server callback functions # diff --git a/mumo.py b/mumo.py index 7ee4c83..f411004 100644 --- a/mumo.py +++ b/mumo.py @@ -374,11 +374,12 @@ def do_main_program(): manager.stopModules() manager.stop() info('Shutdown complete') + return state class CustomLogger(Ice.Logger): """ Logger implementation to pipe Ice log messages into - out own log + our own log """ def __init__(self): @@ -459,12 +460,13 @@ if __name__ == '__main__': print >> sys.stderr, 'Fatal error, could not daemonize process due to missing "daemon" library, ' \ 'please install the missing dependency and restart the authenticator' sys.exit(1) - do_main_program() + ret = do_main_program() else: context = daemon.DaemonContext(working_directory=sys.path[0], stderr=logfile) context.__enter__() try: - do_main_program() + ret = do_main_program() finally: context.__exit__(None, None, None) + sys.exit(ret) \ No newline at end of file diff --git a/mumo_module.py b/mumo_module.py index b71d432..5815ed4 100644 --- a/mumo_module.py +++ b/mumo_module.py @@ -32,7 +32,8 @@ from config import (Config, x2bool, commaSeperatedIntegers, - commaSeperatedStrings) + commaSeperatedStrings, + commaSeperatedBool) from worker import Worker