Added onjoin module for moving players on join as the first mumo plugin. Numerous fixes/changes in the underlying stuff. Moved sample configuration files from modules-enabled to modules-available.
This commit is contained in:
20
modules-available/onjoin.ini
Normal file
20
modules-available/onjoin.ini
Normal file
@ -0,0 +1,20 @@
|
||||
;
|
||||
; This module allows moving players into a specific channel once
|
||||
; they connect regardless of which channel they were in when they left.
|
||||
;
|
||||
|
||||
[onjoin]
|
||||
; Comma seperated list of servers to operate on, leave empty for all
|
||||
servers =
|
||||
|
||||
[all]
|
||||
; Id of the channel to move users into once they join.
|
||||
channel = 2
|
||||
|
||||
; For every server you want to override the [all] section for create
|
||||
; a [server_<serverid>] section. For example:
|
||||
|
||||
; Overriding [all] for server with the id 1 would look like this
|
||||
;[server_1]
|
||||
;channel = 4
|
||||
|
14
modules-available/test.ini
Normal file
14
modules-available/test.ini
Normal file
@ -0,0 +1,14 @@
|
||||
; This file is a dummy configuration file for the
|
||||
; test module. The test module has heavy debug output
|
||||
; and is solely meant for testing the basic framework
|
||||
; as well as debugging purposes. Usually you don't want
|
||||
; to enable it.
|
||||
[testing]
|
||||
tvar = 1
|
||||
tvar2 = Bernd
|
||||
tvar3 = -1
|
||||
tvar4 = True
|
||||
|
||||
[blub]
|
||||
Bernd = asdad
|
||||
asdasd = dasdw
|
@ -1,9 +0,0 @@
|
||||
[testing]
|
||||
tvar = 1
|
||||
tvar2 = Bernd
|
||||
tvar3 = -1
|
||||
tvar4 = True
|
||||
|
||||
[blub]
|
||||
Bernd = asdad
|
||||
asdasd = dasdw
|
93
modules/onjoin.py
Normal file
93
modules/onjoin.py
Normal file
@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8
|
||||
|
||||
# Copyright (C) 2010 Stefan Hacker <dd0t@users.sourceforge.net>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
|
||||
# - Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# - Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# - Neither the name of the Mumble Developers nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from mumo_module import (x2bool,
|
||||
commaSeperatedIntegers,
|
||||
MumoModule,
|
||||
Config)
|
||||
import re
|
||||
|
||||
|
||||
class onjoin(MumoModule):
|
||||
default_config = {'onjoin':(
|
||||
('servers', commaSeperatedIntegers, []),
|
||||
),
|
||||
'all':(
|
||||
('channel', int, 1),
|
||||
),
|
||||
lambda x: re.match('server_\d+', x):(
|
||||
('channel', int, 1),
|
||||
)
|
||||
}
|
||||
|
||||
def __init__(self, name, manager, configuration = None):
|
||||
MumoModule.__init__(self, name, manager, configuration)
|
||||
self.murmur = manager.getMurmurModule()
|
||||
|
||||
def connected(self):
|
||||
manager = self.manager()
|
||||
log = self.log()
|
||||
log.debug("Register for Server callbacks")
|
||||
|
||||
servers = self.cfg().onjoin.servers
|
||||
if not servers:
|
||||
servers = manager.SERVERS_ALL
|
||||
|
||||
manager.subscribeServerCallbacks(self, servers)
|
||||
|
||||
def disconnected(self): pass
|
||||
|
||||
#
|
||||
#--- Server callback functions
|
||||
#
|
||||
|
||||
def userConnected(self, server, state, context = None):
|
||||
log = self.log()
|
||||
sid = server.id()
|
||||
try:
|
||||
scfg = getattr(self.cfg(), 'server_%d' % sid)
|
||||
except AttributeError:
|
||||
scfg = self.cfg().all
|
||||
|
||||
if state.channel != scfg.channel:
|
||||
log.debug("Moving user '%s' from channel %d to %d on server %d", state.name, state.channel, scfg.channel, sid)
|
||||
state.channel = scfg.channel
|
||||
|
||||
try:
|
||||
server.setState(state)
|
||||
except self.murmur.InvalidChannelException:
|
||||
log.error("Moving user '%s' failed, target channel %d does not exist on server %d", state.name, scfg.channel, sid)
|
||||
|
||||
def userDisconnected(self, server, state, context = None): pass
|
||||
def userStateChanged(self, server, state, context = None): pass
|
||||
def channelCreated(self, server, state, context = None): pass
|
||||
def channelRemoved(self, server, state, context = None): pass
|
||||
def channelStateChanged(self, server, state, context = None): pass
|
@ -72,32 +72,32 @@ class test(MumoModule):
|
||||
#--- Server callback functions
|
||||
#
|
||||
@logModFu
|
||||
def userConnected(self, state, context = None):
|
||||
def userConnected(self, server, state, context = None):
|
||||
pass
|
||||
|
||||
@logModFu
|
||||
def userDisconnected(self, state, context = None):
|
||||
def userDisconnected(self, server, state, context = None):
|
||||
pass
|
||||
|
||||
@logModFu
|
||||
def userStateChanged(self, state, context = None):
|
||||
def userStateChanged(self, server, state, context = None):
|
||||
pass
|
||||
|
||||
@logModFu
|
||||
def channelCreated(self, state, context = None):
|
||||
def channelCreated(self, server, state, context = None):
|
||||
pass
|
||||
|
||||
@logModFu
|
||||
def channelRemoved(self, state, context = None):
|
||||
def channelRemoved(self, server, state, context = None):
|
||||
pass
|
||||
|
||||
@logModFu
|
||||
def channelStateChanged(self, state, context = None):
|
||||
def channelStateChanged(self, server, state, context = None):
|
||||
pass
|
||||
|
||||
#
|
||||
#--- Server context callback functions
|
||||
#
|
||||
@logModFu
|
||||
def contextAction(self, action, user, session, channelid, context = None):
|
||||
def contextAction(self, server, action, user, session, channelid, context = None):
|
||||
pass
|
32
mumo.ini
32
mumo.ini
@ -7,39 +7,39 @@
|
||||
; Host and port of the Ice interface on
|
||||
; the target Murmur server.
|
||||
|
||||
;host = 127.0.0.1
|
||||
;port = 6502
|
||||
host = 127.0.0.1
|
||||
port = 6502
|
||||
|
||||
; If you do not define a slicefile here MuMo
|
||||
; will try to automatically retrieve it from
|
||||
; the server. This forces need_on_startup to
|
||||
; True
|
||||
; Slicefile to use
|
||||
|
||||
;slice =
|
||||
slice = Murmur.ice
|
||||
|
||||
; Shared secret between the MuMo and the Murmur
|
||||
; server. For security reason you should always
|
||||
; use a shared secret.
|
||||
|
||||
;secret =
|
||||
secret =
|
||||
|
||||
;Check Ice connection every x seconds
|
||||
|
||||
;watchdog = 15
|
||||
watchdog = 15
|
||||
|
||||
[modules]
|
||||
;mod_dir = modules/
|
||||
;cfg_dir = modules-enabled/
|
||||
;timeout = 2
|
||||
mod_dir = modules/
|
||||
cfg_dir = modules-enabled/
|
||||
timeout = 2
|
||||
|
||||
[system]
|
||||
|
||||
;pidfile = muauth.pid
|
||||
pidfile = muauth.pid
|
||||
|
||||
|
||||
; Logging configuration
|
||||
[log]
|
||||
; Available loglevels: 10 = DEBUG (default) | 20 = INFO | 30 = WARNING | 40 = ERROR
|
||||
|
||||
;level = 10
|
||||
;file = mumo.log
|
||||
level =
|
||||
file = mumo.log
|
||||
|
||||
|
||||
[iceraw]
|
||||
Ice.ThreadPool.Server.Size = 5
|
30
mumo.py
30
mumo.py
@ -136,7 +136,7 @@ def do_main_program():
|
||||
sid = server.id()
|
||||
if not cfg.murmur.servers or sid in cfg.murmur.servers:
|
||||
info('Setting callbacks for virtual server %d', sid)
|
||||
servercbprx = self.adapter.addWithUUID(serverCallback(self.manager, sid))
|
||||
servercbprx = self.adapter.addWithUUID(serverCallback(self.manager, server, sid))
|
||||
servercb = Murmur.ServerCallbackPrx.uncheckedCast(servercbprx)
|
||||
server.addCallback(servercb)
|
||||
|
||||
@ -159,7 +159,7 @@ def do_main_program():
|
||||
return False
|
||||
|
||||
self.connected = True
|
||||
self.manager.announceConnected()
|
||||
self.manager.announceConnected(self.meta)
|
||||
return True
|
||||
|
||||
def checkConnection(self):
|
||||
@ -256,7 +256,7 @@ def do_main_program():
|
||||
if not cfg.murmur.servers or sid in cfg.murmur.servers:
|
||||
info('Setting authenticator for virtual server %d', server.id())
|
||||
try:
|
||||
servercbprx = self.app.adapter.addWithUUID(serverCallback(self.app.manager, sid))
|
||||
servercbprx = self.app.adapter.addWithUUID(serverCallback(self.app.manager, server, sid))
|
||||
servercb = Murmur.ServerCallbackPrx.uncheckedCast(servercbprx)
|
||||
server.addCallback(servercb)
|
||||
|
||||
@ -301,45 +301,53 @@ def do_main_program():
|
||||
|
||||
|
||||
def forwardServer(fu):
|
||||
def new_fu(*args, **kwargs):
|
||||
self = args[0]
|
||||
self.manager.announceServer([self.sid], fu.__name__, *args, **kwargs)
|
||||
def new_fu(self, *args, **kwargs):
|
||||
self.manager.announceServer(self.sid, fu.__name__, self.server, *args, **kwargs)
|
||||
return new_fu
|
||||
|
||||
class serverCallback(Murmur.ServerCallback):
|
||||
def __init__(self, manager, sid):
|
||||
def __init__(self, manager, server, sid):
|
||||
Murmur.ServerCallback.__init__(self)
|
||||
self.manager = manager
|
||||
self.sid = sid
|
||||
|
||||
self.server = server
|
||||
|
||||
@checkSecret
|
||||
@forwardServer
|
||||
def userStateChanged(self, u, current=None): pass
|
||||
@checkSecret
|
||||
@forwardServer
|
||||
def userDisconnected(self, u, current=None): pass
|
||||
@checkSecret
|
||||
@forwardServer
|
||||
def userConnected(self, u, current=None): pass
|
||||
@checkSecret
|
||||
@forwardServer
|
||||
def channelCreated(self, c, current=None): pass
|
||||
@checkSecret
|
||||
@forwardServer
|
||||
def channelRemoved(self, c, current=None): pass
|
||||
@checkSecret
|
||||
@forwardServer
|
||||
def channelStateChanged(self, c, current=None): pass
|
||||
|
||||
class contextCallback(Murmur.ServerContextCallback):
|
||||
def __init__(self, manager, sid):
|
||||
def __init__(self, manager, server, sid):
|
||||
Murmur.ServerContextCallback.__init__(self)
|
||||
self.manager = manager
|
||||
self.server = server
|
||||
self.sid = sid
|
||||
|
||||
@checkSecret
|
||||
def contextAction(self, action, p, session, chanid, current=None):
|
||||
self.manager.announceContext([self.sid], "contextAction", action, p, session, chanid, current)
|
||||
self.manager.announceContext(self.sid, "contextAction", self.server, action, p, session, chanid, current)
|
||||
|
||||
#
|
||||
#--- Start of moderator
|
||||
#
|
||||
info('Starting mumble moderator')
|
||||
debug('Initializing manager')
|
||||
manager = MumoManager()
|
||||
manager = MumoManager(Murmur)
|
||||
manager.start()
|
||||
manager.loadModules()
|
||||
manager.startModules()
|
||||
|
@ -47,7 +47,7 @@ class FailedLoadModuleImportException(FailedLoadModuleException):
|
||||
class FailedLoadModuleInitializationException(FailedLoadModuleException):
|
||||
pass
|
||||
|
||||
def debug_log(fu, enable = True):
|
||||
def debug_log(enable = True):
|
||||
def new_dec(fu):
|
||||
def new_fu(*args, **kwargs):
|
||||
self = args[0]
|
||||
@ -163,6 +163,17 @@ class MumoManagerRemote(object):
|
||||
"""
|
||||
return self.__master.unsubscribeContextCallbacks(self.__queue, handler, servers)
|
||||
|
||||
def getMurmurModule(self):
|
||||
"""
|
||||
Returns the Murmur module generated from the slice file
|
||||
"""
|
||||
return self.__master.getMurmurModule()
|
||||
|
||||
def getMeta(self):
|
||||
"""
|
||||
Returns the connected servers meta module or None if it is not available
|
||||
"""
|
||||
return self.__master.getMeta()
|
||||
|
||||
|
||||
class MumoManager(Worker):
|
||||
@ -172,13 +183,16 @@ class MumoManager(Worker):
|
||||
('cfg_dir', str, "modules-enabled/"),
|
||||
('timeout', int, 2))}
|
||||
|
||||
def __init__(self, cfg = Config(default = cfg_default)):
|
||||
def __init__(self, murmur, cfg = Config(default = cfg_default)):
|
||||
Worker.__init__(self, "MumoManager")
|
||||
self.queues = {} # {queue:module}
|
||||
self.modules = {} # {name:module}
|
||||
self.imports = {} # {name:import}
|
||||
self.cfg = cfg
|
||||
|
||||
self.murmur = murmur
|
||||
self.meta = None
|
||||
|
||||
self.metaCallbacks = {} # {sid:{queue:[handler]}}
|
||||
self.serverCallbacks = {}
|
||||
self.contextCallbacks = {}
|
||||
@ -201,38 +215,37 @@ class MumoManager(Worker):
|
||||
except KeyError, ValueError:
|
||||
pass
|
||||
|
||||
def __announce_to_dict(self, mdict, servers, function, *args, **kwargs):
|
||||
def __announce_to_dict(self, mdict, server, function, *args, **kwargs):
|
||||
"""
|
||||
Call function on handlers for specific servers in one of our handler
|
||||
dictionaries.
|
||||
|
||||
@param mdict Dictionary to announce to
|
||||
@param servers: Servers to announce to, ALL is always implied
|
||||
@param function: Function the handler should call
|
||||
@param args: Arguments for the function
|
||||
@param kwargs: Keyword arguments for the function
|
||||
"""
|
||||
# Announce to all handlers registered to all events
|
||||
try:
|
||||
for queue, handlers in mdict[self.MAGIC_ALL].iteritems():
|
||||
for handler in handlers:
|
||||
self.__call_remote(queue, handler, function, args, kwargs)
|
||||
except KeyError:
|
||||
# No handler registered for MAGIC_ALL
|
||||
pass
|
||||
|
||||
@param server Server to announce to, ALL is always implied
|
||||
@param function Function the handler should call
|
||||
@param args Arguments for the function
|
||||
@param kwargs Keyword arguments for the function
|
||||
"""
|
||||
|
||||
# Announce to all handlers of the given serverlist
|
||||
if server == self.MAGIC_ALL:
|
||||
servers = mdict.iterkeys()
|
||||
else:
|
||||
servers = [self.MAGIC_ALL, server]
|
||||
|
||||
for server in servers:
|
||||
try:
|
||||
for queue, handler in mdict[server].iteritems():
|
||||
self.__call_remote(queue, handler, function, args, kwargs)
|
||||
for queue, handlers in mdict[server].iteritems():
|
||||
for handler in handlers:
|
||||
self.__call_remote(queue, handler, function, *args, **kwargs)
|
||||
except KeyError:
|
||||
# No handler registered for that server
|
||||
pass
|
||||
|
||||
|
||||
def __call_remote(self, queue, handler, function, *args, **kwargs):
|
||||
try:
|
||||
func = getattr(handler, function) # Find out what to call on target
|
||||
queue.put((None, func, args, kwargs))
|
||||
except AttributeError, e:
|
||||
mod = self.queues.get(queue, None)
|
||||
myname = ""
|
||||
@ -240,20 +253,21 @@ class MumoManager(Worker):
|
||||
if mod == mymod:
|
||||
myname = name
|
||||
if myname:
|
||||
self.log.error("Handler class registered by module '%s' does not handle function '%s'. Call failed.", myname, function)
|
||||
self.log().error("Handler class registered by module '%s' does not handle function '%s'. Call failed.", myname, function)
|
||||
else:
|
||||
self.log().exception(e)
|
||||
queue.put((None, func, args, kwargs))
|
||||
|
||||
|
||||
#
|
||||
#-- Module multiplexing functionality
|
||||
#
|
||||
|
||||
@local_thread
|
||||
def announceConnected(self):
|
||||
def announceConnected(self, meta = None):
|
||||
"""
|
||||
Call connected handler on all handlers
|
||||
"""
|
||||
self.meta = meta
|
||||
for queue, module in self.queues.iteritems():
|
||||
self.__call_remote(queue, module, "connected")
|
||||
|
||||
@ -266,40 +280,40 @@ class MumoManager(Worker):
|
||||
self.__call_remote(queue, module, "disconnected")
|
||||
|
||||
@local_thread
|
||||
def announceMeta(self, servers, function, *args, **kwargs):
|
||||
def announceMeta(self, server, function, *args, **kwargs):
|
||||
"""
|
||||
Call a function on the meta handlers
|
||||
|
||||
@param servers Servers to announce to
|
||||
@param server Servers to announce to
|
||||
@param function Name of the function to call on the handler
|
||||
@param args List of arguments
|
||||
@param kwargs List of keyword arguments
|
||||
"""
|
||||
self.__announce_to_dict(self.metaCallbacks, servers, function, *args, **kwargs)
|
||||
self.__announce_to_dict(self.metaCallbacks, server, function, *args, **kwargs)
|
||||
|
||||
@local_thread
|
||||
def announceServer(self, servers, function, *args, **kwargs):
|
||||
def announceServer(self, server, function, *args, **kwargs):
|
||||
"""
|
||||
Call a function on the server handlers
|
||||
|
||||
@param servers Servers to announce to
|
||||
@param server Server to announce to
|
||||
@param function Name of the function to call on the handler
|
||||
@param args List of arguments
|
||||
@param kwargs List of keyword arguments
|
||||
"""
|
||||
self.__announce_to_dict(self.serverCallbacks, servers, function, *args, **kwargs)
|
||||
self.__announce_to_dict(self.serverCallbacks, server, function, *args, **kwargs)
|
||||
|
||||
@local_thread
|
||||
def announceContext(self, servers, function, *args, **kwargs):
|
||||
def announceContext(self, server, function, *args, **kwargs):
|
||||
"""
|
||||
Call a function on the context handlers
|
||||
|
||||
@param servers Servers to announce to
|
||||
@param server Server to announce to
|
||||
@param function Name of the function to call on the handler
|
||||
@param args List of arguments
|
||||
@param kwargs List of keyword arguments
|
||||
"""
|
||||
self.__announce_to_dict(self.serverCallbacks, servers, function, *args, **kwargs)
|
||||
self.__announce_to_dict(self.serverCallbacks, server, function, *args, **kwargs)
|
||||
#
|
||||
#--- Module self management functionality
|
||||
#
|
||||
@ -351,8 +365,19 @@ class MumoManager(Worker):
|
||||
@see MumoManagerRemote
|
||||
"""
|
||||
return self.__rem_from_dict(self.contextCallbacks, queue, handler, servers)
|
||||
|
||||
def getMurmurModule(self):
|
||||
"""
|
||||
Returns the Murmur module generated from the slice file
|
||||
"""
|
||||
return self.murmur
|
||||
|
||||
def getMeta(self):
|
||||
"""
|
||||
Returns the connected servers meta module or None if it is not available
|
||||
"""
|
||||
return self.meta
|
||||
|
||||
#
|
||||
#--- Module load/start/stop/unload functionality
|
||||
#
|
||||
@local_thread_blocking
|
||||
|
@ -75,11 +75,11 @@ class MumoManagerTest(unittest.TestCase):
|
||||
if arg1 == "arg1" and arg2 == "arg2":
|
||||
self.emeta.set()
|
||||
|
||||
def contextCallMe(self, arg1, arg2):
|
||||
def contextCallMe(self, server, arg1, arg2):
|
||||
if arg1 == "arg1" and arg2 == "arg2":
|
||||
self.econtext.set()
|
||||
|
||||
def serverCallMe(self, arg1, arg2):
|
||||
def serverCallMe(self, server, arg1, arg2):
|
||||
if arg1 == "arg1" and arg2 == "arg2":
|
||||
self.eserver.set()
|
||||
|
||||
@ -95,7 +95,7 @@ class MumoManagerTest(unittest.TestCase):
|
||||
#--- Helpers for independent test env creation
|
||||
#
|
||||
def up(self):
|
||||
man = MumoManager()
|
||||
man = MumoManager(None)
|
||||
man.start()
|
||||
|
||||
mod = man.loadModuleCls("MyModule", self.mymod, self.cfg)
|
||||
@ -144,21 +144,33 @@ class MumoManagerTest(unittest.TestCase):
|
||||
def testMetaCallback(self):
|
||||
man, mod = self.up()
|
||||
man.announceConnected()
|
||||
man.announceMeta([], "metaCallMe", ["arg1"], {"arg2":"arg2"})
|
||||
mod.econnected.wait(timeout=1)
|
||||
assert(mod.econnected.is_set())
|
||||
man.announceMeta(man.MAGIC_ALL, "metaCallMe", "arg1", arg2 = "arg2")
|
||||
mod.emeta.wait(timeout=1)
|
||||
assert(mod.emeta.is_set())
|
||||
man.announceDisconnected()
|
||||
self.down(man, mod)
|
||||
|
||||
def testContextCallback(self):
|
||||
man, mod = self.up()
|
||||
man.announceConnected()
|
||||
man.announceContext([], "contextCallMe", ["arg1"], {"arg2":"arg2"})
|
||||
mod.econnected.wait(timeout=1)
|
||||
assert(mod.econnected.is_set())
|
||||
man.announceContext(man.MAGIC_ALL, "contextCallMe", "server", "arg1", arg2 = "arg2")
|
||||
mod.econtext.wait(timeout=1)
|
||||
assert(mod.econtext.is_set())
|
||||
man.announceDisconnected()
|
||||
self.down(man, mod)
|
||||
|
||||
def testServerCallback(self):
|
||||
man, mod = self.up()
|
||||
man.announceConnected()
|
||||
man.announceServer([], "serverCallMe", ["arg1"], {"arg2":"arg2"})
|
||||
mod.econnected.wait(timeout=1)
|
||||
assert(mod.econnected.is_set())
|
||||
man.announceServer(man.MAGIC_ALL, "serverCallMe", "server", "arg1", arg2 = "arg2")
|
||||
mod.eserver.wait(timeout=1)
|
||||
assert(mod.eserver.is_set())
|
||||
man.announceDisconnected()
|
||||
self.down(man, mod)
|
||||
|
||||
|
@ -91,10 +91,10 @@ class MumoModule(Worker):
|
||||
|
||||
|
||||
def logModFu(fu):
|
||||
def newfu(self, *args, **kwargs):
|
||||
def new_fu(self, *args, **kwargs):
|
||||
log = self.log()
|
||||
argss = '' if len(args)==0 else ',' + ','.join(['"%s"' % str(arg) for arg in args])
|
||||
kwargss = '' if len(kwargs)==0 else ','.join('%s="%s"' % (kw, str(arg)) for kw, arg in kwargs.iteritems())
|
||||
log.debug("%s(%s%s%s)", fu.__name__, str(self), argss, kwargss)
|
||||
return fu(self, *args, **kwargs)
|
||||
return newfu
|
||||
return new_fu
|
Reference in New Issue
Block a user