Python3
This commit is contained in:
parent
c42113d712
commit
27d0d313d2
@ -57,7 +57,7 @@ modules-enabled folder.
|
||||
|
||||
## Requirements
|
||||
mumo requires:
|
||||
* python 2.7*
|
||||
* python >=3.2
|
||||
* python-zeroc-ice
|
||||
* murmur >=1.2.3*
|
||||
|
||||
|
52
config.py
52
config.py
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8
|
||||
|
||||
# Copyright (C) 2010 Stefan Hacker <dd0t@users.sourceforge.net>
|
||||
@ -29,40 +29,42 @@
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import ConfigParser
|
||||
import configparser
|
||||
import types
|
||||
|
||||
|
||||
class Config(object):
|
||||
"""
|
||||
Small abstraction for config loading
|
||||
"""
|
||||
|
||||
def __init__(self, filename = None, default = None):
|
||||
def __init__(self, filename=None, default=None):
|
||||
if (filename and not default) or \
|
||||
(not filename and not default): return
|
||||
|
||||
sections = set(default.iterkeys())
|
||||
(not filename and not default): return
|
||||
|
||||
sections = set(default.keys())
|
||||
if filename:
|
||||
cfg = ConfigParser.RawConfigParser()
|
||||
cfg = configparser.RawConfigParser()
|
||||
cfg.optionxform = str
|
||||
with open(filename) as f:
|
||||
cfg.readfp(f)
|
||||
cfg.read_file(f)
|
||||
sections.update(cfg.sections())
|
||||
|
||||
|
||||
for section in sections:
|
||||
if type(section) == types.FunctionType: continue
|
||||
|
||||
if isinstance(section, types.FunctionType):
|
||||
continue
|
||||
|
||||
match = None
|
||||
for default_section in default.iterkeys():
|
||||
for default_section in default.keys():
|
||||
try:
|
||||
if section == default_section or \
|
||||
(type(default_section) == types.FunctionType and default_section(section)):
|
||||
(isinstance(default_section, types.FunctionType) and default_section(section)):
|
||||
match = default_section
|
||||
break
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
if match == None:
|
||||
|
||||
if match is None:
|
||||
continue
|
||||
|
||||
optiondefaults = default[match]
|
||||
@ -74,7 +76,7 @@ class Config(object):
|
||||
else:
|
||||
try:
|
||||
self.__dict__[section] = cfg.items(section)
|
||||
except ConfigParser.NoSectionError:
|
||||
except configparser.NoSectionError:
|
||||
self.__dict__[section] = []
|
||||
else:
|
||||
self.__dict__[section] = Config()
|
||||
@ -84,42 +86,46 @@ class Config(object):
|
||||
else:
|
||||
try:
|
||||
self.__dict__[section].__dict__[name] = conv(cfg.get(section, name))
|
||||
except (ValueError, ConfigParser.NoSectionError, ConfigParser.NoOptionError):
|
||||
except (ValueError, configparser.NoSectionError, configparser.NoOptionError):
|
||||
self.__dict__[section].__dict__[name] = vdefault
|
||||
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.__dict__.__getitem__(key)
|
||||
|
||||
|
||||
def __contains__(self, key):
|
||||
return self.__dict__.__contains__(key)
|
||||
|
||||
|
||||
def x2bool(s):
|
||||
"""
|
||||
Helper function to convert strings from the config to bool
|
||||
"""
|
||||
if isinstance(s, bool):
|
||||
return s
|
||||
elif isinstance(s, basestring):
|
||||
elif isinstance(s, str):
|
||||
return s.strip().lower() in ['1', 'true']
|
||||
raise ValueError()
|
||||
|
||||
|
||||
def commaSeperatedIntegers(s):
|
||||
"""
|
||||
Helper function to convert a string from the config
|
||||
containing comma seperated integers into a list of integers
|
||||
"""
|
||||
return map(int, s.split(','))
|
||||
return list(map(int, s.split(',')))
|
||||
|
||||
|
||||
def commaSeperatedStrings(s):
|
||||
"""
|
||||
Helper function to convert a string from the config
|
||||
containing comma seperated strings into a list of strings
|
||||
"""
|
||||
return map(str.strip, s.split(','))
|
||||
return list(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(','))
|
||||
return list(map(x2bool, s.split(',')))
|
||||
|
112
config_test.py
112
config_test.py
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8
|
||||
|
||||
# Copyright (C) 2010 Stefan Hacker <dd0t@users.sourceforge.net>
|
||||
@ -29,13 +29,15 @@
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import unittest
|
||||
from config import Config, x2bool, commaSeperatedIntegers, commaSeperatedStrings, commaSeperatedBool
|
||||
from tempfile import mkstemp
|
||||
import os
|
||||
import re
|
||||
import unittest
|
||||
from tempfile import mkstemp
|
||||
|
||||
def create_file(content = None):
|
||||
from config import Config, x2bool, commaSeperatedIntegers, commaSeperatedStrings, commaSeperatedBool
|
||||
|
||||
|
||||
def create_file(content=None):
|
||||
"""
|
||||
Creates a temp file filled with 'content' and returns its path.
|
||||
The file has to be manually deleted later on
|
||||
@ -43,11 +45,12 @@ def create_file(content = None):
|
||||
fd, path = mkstemp()
|
||||
f = os.fdopen(fd, "wb")
|
||||
if content:
|
||||
f.write(content)
|
||||
f.write(content.encode())
|
||||
f.flush()
|
||||
f.close()
|
||||
return path
|
||||
|
||||
|
||||
class ConfigTest(unittest.TestCase):
|
||||
cfg_content = """[world]
|
||||
domination = True
|
||||
@ -62,15 +65,15 @@ value = False
|
||||
[Server_2]
|
||||
value = True
|
||||
"""
|
||||
|
||||
cfg_default = {'world':(('domination', x2bool, False),
|
||||
('somestr', str, "fail"),
|
||||
('somenum', int, 0),
|
||||
('somenumtest', int, 1),
|
||||
('blubber', str, "empty"),
|
||||
('serverregex', re.compile, '.*')),
|
||||
(lambda x: re.match("Server_\d+",x)):(('value', x2bool, True),),
|
||||
'somethingelse':(('bla', str, "test"),)}
|
||||
|
||||
cfg_default = {'world': (('domination', x2bool, False),
|
||||
('somestr', str, "fail"),
|
||||
('somenum', int, 0),
|
||||
('somenumtest', int, 1),
|
||||
('blubber', str, "empty"),
|
||||
('serverregex', re.compile, '.*')),
|
||||
(lambda x: re.match("Server_\d+", x)): (('value', x2bool, True),),
|
||||
'somethingelse': (('bla', str, "test"),)}
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
@ -78,76 +81,75 @@ value = True
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
|
||||
def testEmpty(self):
|
||||
path = create_file()
|
||||
try:
|
||||
cfg = Config(path, self.cfg_default)
|
||||
assert(cfg.world.domination == False)
|
||||
assert(cfg.world.somestr == "fail")
|
||||
assert(cfg.world.somenum == 0)
|
||||
assert (cfg.world.domination == False)
|
||||
assert (cfg.world.somestr == "fail")
|
||||
assert (cfg.world.somenum == 0)
|
||||
self.assertRaises(AttributeError, getattr, cfg.world, "testfallbacknum")
|
||||
assert(cfg.somethingelse.bla == "test")
|
||||
assert (cfg.somethingelse.bla == "test")
|
||||
finally:
|
||||
os.remove(path)
|
||||
|
||||
|
||||
def testX2bool(self):
|
||||
assert(x2bool(" true") == True)
|
||||
assert(x2bool("false") == False)
|
||||
assert(x2bool(" TrUe") == True)
|
||||
assert(x2bool("FaLsE ") == False)
|
||||
assert(x2bool("0 ") == False)
|
||||
assert(x2bool("1") == True)
|
||||
assert(x2bool(" 10") == False)
|
||||
assert(x2bool("notabool") == False)
|
||||
|
||||
assert (x2bool(" true") == True)
|
||||
assert (x2bool("false") == False)
|
||||
assert (x2bool(" TrUe") == True)
|
||||
assert (x2bool("FaLsE ") == False)
|
||||
assert (x2bool("0 ") == False)
|
||||
assert (x2bool("1") == True)
|
||||
assert (x2bool(" 10") == False)
|
||||
assert (x2bool("notabool") == False)
|
||||
|
||||
def testCommaSeperatedIntegers(self):
|
||||
assert(commaSeperatedIntegers(" 1,2 , 333 ") == [1,2,333])
|
||||
assert (commaSeperatedIntegers(" 1,2 , 333 ") == [1, 2, 333])
|
||||
self.assertRaises(ValueError, commaSeperatedIntegers, "1,2,a")
|
||||
|
||||
|
||||
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])
|
||||
|
||||
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)
|
||||
try:
|
||||
try:
|
||||
cfg = Config(path, self.cfg_default)
|
||||
except Exception, e:
|
||||
print e
|
||||
assert(cfg.world.domination == True)
|
||||
assert(cfg.world.somestr == "Blabla")
|
||||
assert(cfg.world.somenum == 10)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
assert (cfg.world.domination == True)
|
||||
assert (cfg.world.somestr == "Blabla")
|
||||
assert (cfg.world.somenum == 10)
|
||||
self.assertRaises(AttributeError, getattr, cfg.world, "testfallbacknum")
|
||||
self.assertEqual(cfg.world.blubber, "Things %(doesnotexistsasdefault)s")
|
||||
self.assertEqual(cfg.world.serverregex, re.compile("^\[[\w\d\-\(\):]{1,20}\]$"))
|
||||
assert(cfg.somethingelse.bla == "test")
|
||||
assert(cfg.Server_10.value == False)
|
||||
assert(cfg.Server_2.value == True)
|
||||
assert(cfg.Server_9.value == True)
|
||||
assert (cfg.somethingelse.bla == "test")
|
||||
assert (cfg.Server_10.value == False)
|
||||
assert (cfg.Server_2.value == True)
|
||||
assert (cfg.Server_9.value == True)
|
||||
finally:
|
||||
os.remove(path)
|
||||
|
||||
|
||||
def testLoadDefault(self):
|
||||
cfg = Config(default=self.cfg_default)
|
||||
assert(cfg.world.domination == False)
|
||||
assert(cfg.somethingelse.bla == "test")
|
||||
assert(cfg.world.somenum == 0)
|
||||
|
||||
assert (cfg.world.domination == False)
|
||||
assert (cfg.somethingelse.bla == "test")
|
||||
assert (cfg.world.somenum == 0)
|
||||
|
||||
def testGetItem(self):
|
||||
cfg = Config(default=self.cfg_default)
|
||||
assert(cfg["world"]["domination"] == False)
|
||||
assert("world" in cfg)
|
||||
|
||||
assert (cfg["world"]["domination"] == False)
|
||||
assert ("world" in cfg)
|
||||
|
||||
def invalidaccess(c):
|
||||
c["nointhisconfig"]
|
||||
|
||||
|
||||
self.assertRaises(KeyError, invalidaccess, cfg)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#import sys;sys.argv = ['', 'Test.testName']
|
||||
# import sys;sys.argv = ['', 'Test.testName']
|
||||
unittest.main()
|
||||
|
@ -17,7 +17,7 @@ DESC="Mumo bot for Mumble"
|
||||
WORKDIR=/opt/mumo
|
||||
PIDDIR=$WORKDIR
|
||||
PIDFILE=$PIDDIR/mumo.pid
|
||||
DAEMON=/usr/bin/python
|
||||
DAEMON=/usr/bin/python3
|
||||
USER=mumo
|
||||
GROUP=mumo
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
# No real module, just here to keep pydev and its
|
||||
# test runner happy.
|
||||
# test runner happy.
|
||||
|
314
modules/bf2.py
314
modules/bf2.py
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8
|
||||
|
||||
# Copyright (C) 2010-2011 Stefan Hacker <dd0t@users.sourceforge.net>
|
||||
@ -35,77 +35,75 @@
|
||||
# gamestate reported by Mumble positional audio plugins
|
||||
#
|
||||
|
||||
from mumo_module import (MumoModule,
|
||||
x2bool)
|
||||
|
||||
import json
|
||||
import re
|
||||
try:
|
||||
import json
|
||||
except ImportError: # Fallback for python < 2.6
|
||||
import simplejson as json
|
||||
|
||||
from config import x2bool
|
||||
from mumo_module import MumoModule
|
||||
|
||||
|
||||
class bf2(MumoModule):
|
||||
default_config = {'bf2':(
|
||||
('gamecount', int, 1),
|
||||
),
|
||||
lambda x: re.match('g\d+', x):(
|
||||
('name', str, ''),
|
||||
('mumble_server', int, 1),
|
||||
('ipport_filter_negate', x2bool, False),
|
||||
('ipport_filter', re.compile, re.compile('.*')),
|
||||
|
||||
('base', int, 0),
|
||||
('left', int, -1),
|
||||
|
||||
('blufor', int, -1),
|
||||
('blufor_commander', int, -1),
|
||||
('blufor_no_squad', int, -1),
|
||||
('blufor_first_squad', int, -1),
|
||||
('blufor_first_squad_leader', int, -1),
|
||||
('blufor_second_squad', int, -1),
|
||||
('blufor_second_squad_leader', int, -1),
|
||||
('blufor_third_squad', int, -1),
|
||||
('blufor_third_squad_leader', int, -1),
|
||||
('blufor_fourth_squad', int, -1),
|
||||
('blufor_fourth_squad_leader', int, -1),
|
||||
('blufor_fifth_squad', int, -1),
|
||||
('blufor_fifth_squad_leader', int, -1),
|
||||
('blufor_sixth_squad', int, -1),
|
||||
('blufor_sixth_squad_leader', int, -1),
|
||||
('blufor_seventh_squad', int, -1),
|
||||
('blufor_seventh_squad_leader', int, -1),
|
||||
('blufor_eighth_squad', int, -1),
|
||||
('blufor_eighth_squad_leader', int, -1),
|
||||
('blufor_ninth_squad', int, -1),
|
||||
('blufor_ninth_squad_leader', int, -1),
|
||||
|
||||
('opfor', int, -1),
|
||||
('opfor_commander', int, -1),
|
||||
('opfor_no_squad', int, -1),
|
||||
('opfor_first_squad', int, -1),
|
||||
('opfor_first_squad_leader', int, -1),
|
||||
('opfor_second_squad', int, -1),
|
||||
('opfor_second_squad_leader', int, -1),
|
||||
('opfor_third_squad', int, -1),
|
||||
('opfor_third_squad_leader', int, -1),
|
||||
('opfor_fourth_squad', int, -1),
|
||||
('opfor_fourth_squad_leader', int, -1),
|
||||
('opfor_fifth_squad', int, -1),
|
||||
('opfor_fifth_squad_leader', int, -1),
|
||||
('opfor_sixth_squad', int, -1),
|
||||
('opfor_sixth_squad_leader', int, -1),
|
||||
('opfor_seventh_squad', int, -1),
|
||||
('opfor_seventh_squad_leader', int, -1),
|
||||
('opfor_eighth_squad', int, -1),
|
||||
('opfor_eighth_squad_leader', int, -1),
|
||||
('opfor_ninth_squad', int, -1),
|
||||
('opfor_ninth_squad_leader', int, -1)
|
||||
),
|
||||
}
|
||||
|
||||
default_config = {'bf2': (
|
||||
('gamecount', int, 1),
|
||||
),
|
||||
lambda x: re.match('g\d+', x): (
|
||||
('name', str, ''),
|
||||
('mumble_server', int, 1),
|
||||
('ipport_filter_negate', x2bool, False),
|
||||
('ipport_filter', re.compile, re.compile('.*')),
|
||||
|
||||
('base', int, 0),
|
||||
('left', int, -1),
|
||||
|
||||
('blufor', int, -1),
|
||||
('blufor_commander', int, -1),
|
||||
('blufor_no_squad', int, -1),
|
||||
('blufor_first_squad', int, -1),
|
||||
('blufor_first_squad_leader', int, -1),
|
||||
('blufor_second_squad', int, -1),
|
||||
('blufor_second_squad_leader', int, -1),
|
||||
('blufor_third_squad', int, -1),
|
||||
('blufor_third_squad_leader', int, -1),
|
||||
('blufor_fourth_squad', int, -1),
|
||||
('blufor_fourth_squad_leader', int, -1),
|
||||
('blufor_fifth_squad', int, -1),
|
||||
('blufor_fifth_squad_leader', int, -1),
|
||||
('blufor_sixth_squad', int, -1),
|
||||
('blufor_sixth_squad_leader', int, -1),
|
||||
('blufor_seventh_squad', int, -1),
|
||||
('blufor_seventh_squad_leader', int, -1),
|
||||
('blufor_eighth_squad', int, -1),
|
||||
('blufor_eighth_squad_leader', int, -1),
|
||||
('blufor_ninth_squad', int, -1),
|
||||
('blufor_ninth_squad_leader', int, -1),
|
||||
|
||||
('opfor', int, -1),
|
||||
('opfor_commander', int, -1),
|
||||
('opfor_no_squad', int, -1),
|
||||
('opfor_first_squad', int, -1),
|
||||
('opfor_first_squad_leader', int, -1),
|
||||
('opfor_second_squad', int, -1),
|
||||
('opfor_second_squad_leader', int, -1),
|
||||
('opfor_third_squad', int, -1),
|
||||
('opfor_third_squad_leader', int, -1),
|
||||
('opfor_fourth_squad', int, -1),
|
||||
('opfor_fourth_squad_leader', int, -1),
|
||||
('opfor_fifth_squad', int, -1),
|
||||
('opfor_fifth_squad_leader', int, -1),
|
||||
('opfor_sixth_squad', int, -1),
|
||||
('opfor_sixth_squad_leader', int, -1),
|
||||
('opfor_seventh_squad', int, -1),
|
||||
('opfor_seventh_squad_leader', int, -1),
|
||||
('opfor_eighth_squad', int, -1),
|
||||
('opfor_eighth_squad_leader', int, -1),
|
||||
('opfor_ninth_squad', int, -1),
|
||||
('opfor_ninth_squad_leader', int, -1)
|
||||
),
|
||||
}
|
||||
|
||||
id_to_squad_name = ["no", "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth"]
|
||||
|
||||
def __init__(self, name, manager, configuration = None):
|
||||
|
||||
def __init__(self, name, manager, configuration=None):
|
||||
MumoModule.__init__(self, name, manager, configuration)
|
||||
self.murmur = manager.getMurmurModule()
|
||||
|
||||
@ -114,7 +112,7 @@ class bf2(MumoModule):
|
||||
manager = self.manager()
|
||||
log = self.log()
|
||||
log.debug("Register for Server callbacks")
|
||||
|
||||
|
||||
servers = set()
|
||||
for i in range(cfg.bf2.gamecount):
|
||||
try:
|
||||
@ -122,23 +120,24 @@ class bf2(MumoModule):
|
||||
except KeyError:
|
||||
log.error("Invalid configuration. Game configuration for 'g%d' not found.", i)
|
||||
return
|
||||
|
||||
self.sessions = {} # {serverid:{sessionid:laststate}}
|
||||
|
||||
self.sessions = {} # {serverid:{sessionid:laststate}}
|
||||
manager.subscribeServerCallbacks(self, servers)
|
||||
manager.subscribeMetaCallbacks(self, servers)
|
||||
|
||||
def disconnected(self): pass
|
||||
|
||||
|
||||
def disconnected(self):
|
||||
pass
|
||||
|
||||
#
|
||||
#--- Module specific state handling code
|
||||
# --- Module specific state handling code
|
||||
#
|
||||
def update_state(self, server, oldstate, newstate):
|
||||
log = self.log()
|
||||
sid = server.id()
|
||||
|
||||
|
||||
session = newstate.session
|
||||
newoldchannel = newstate.channel
|
||||
|
||||
|
||||
try:
|
||||
opc = oldstate.parsedcontext
|
||||
ogcfgname = opc["gamename"]
|
||||
@ -147,15 +146,15 @@ class bf2(MumoModule):
|
||||
opi = oldstate.parsedidentity
|
||||
except (AttributeError, KeyError):
|
||||
og = None
|
||||
|
||||
|
||||
opi = {}
|
||||
opc = {}
|
||||
|
||||
|
||||
if oldstate and oldstate.is_linked:
|
||||
oli = True
|
||||
else:
|
||||
oli = False
|
||||
|
||||
|
||||
try:
|
||||
npc = newstate.parsedcontext
|
||||
ngcfgname = npc["gamename"]
|
||||
@ -164,23 +163,25 @@ class bf2(MumoModule):
|
||||
npi = newstate.parsedidentity
|
||||
except (AttributeError, KeyError):
|
||||
ng = None
|
||||
|
||||
|
||||
npi = {}
|
||||
npc = {}
|
||||
nli = False
|
||||
|
||||
|
||||
if newstate and newstate.is_linked:
|
||||
nli = True
|
||||
else:
|
||||
nli = False
|
||||
|
||||
|
||||
if not oli and nli:
|
||||
log.debug("User '%s' (%d|%d) on server %d now linked", newstate.name, newstate.session, newstate.userid, sid)
|
||||
log.debug("User '%s' (%d|%d) on server %d now linked", newstate.name, newstate.session, newstate.userid,
|
||||
sid)
|
||||
server.addUserToGroup(0, session, "bf2_linked")
|
||||
|
||||
|
||||
if opi and opc:
|
||||
squadname = self.id_to_squad_name[opi["squad"]]
|
||||
log.debug("Removing user '%s' (%d|%d) on server %d from groups of game %s / squad %s", newstate.name, newstate.session, newstate.userid, sid, og or ogcfgname, squadname)
|
||||
log.debug("Removing user '%s' (%d|%d) on server %d from groups of game %s / squad %s", newstate.name,
|
||||
newstate.session, newstate.userid, sid, og or ogcfgname, squadname)
|
||||
server.removeUserFromGroup(ogcfg["base"], session, "bf2_%s_game" % (og or ogcfgname))
|
||||
server.removeUserFromGroup(ogcfg[opi["team"]], session, "bf2_commander")
|
||||
server.removeUserFromGroup(ogcfg[opi["team"]], session, "bf2_squad_leader")
|
||||
@ -189,72 +190,74 @@ class bf2(MumoModule):
|
||||
server.removeUserFromGroup(ogcfg[opi["team"]], session, "bf2_team")
|
||||
channame = "left"
|
||||
newstate.channel = ogcfg["left"]
|
||||
|
||||
|
||||
if npc and npi:
|
||||
log.debug("Updating user '%s' (%d|%d) on server %d in game %s: %s", newstate.name, newstate.session, newstate.userid, sid, ng or ngcfgname, str(npi))
|
||||
|
||||
log.debug("Updating user '%s' (%d|%d) on server %d in game %s: %s", newstate.name, newstate.session,
|
||||
newstate.userid, sid, ng or ngcfgname, str(npi))
|
||||
|
||||
squadname = self.id_to_squad_name[npi["squad"]]
|
||||
|
||||
|
||||
# Add to game group
|
||||
location = "base"
|
||||
group = "bf2_%s_game" % (ng or ngcfgname)
|
||||
server.addUserToGroup(ngcfg[location], session, group)
|
||||
log.debug("Added '%s' @ %s to group %s in %s", newstate.name, ng or ngcfgname, group, location)
|
||||
|
||||
|
||||
# Then add to team group
|
||||
location = npi["team"]
|
||||
group = "bf2_team"
|
||||
server.addUserToGroup(ngcfg[location], session, group)
|
||||
log.debug("Added '%s' @ %s to group %s in %s", newstate.name, ng or ngcfgname, group, location)
|
||||
|
||||
|
||||
# Then add to squad group
|
||||
group = "bf2_%s_squad" % squadname
|
||||
server.addUserToGroup(ngcfg[location], session, group)
|
||||
log.debug("Added '%s' @ %s to group %s in %s", newstate.name, ng or ngcfgname, group, location)
|
||||
|
||||
|
||||
channame = "%s_%s_squad" % (npi["team"], self.id_to_squad_name[npi["squad"]])
|
||||
newstate.channel = ngcfg[channame]
|
||||
|
||||
|
||||
if npi["squad_leader"]:
|
||||
# In case the leader flag is set add to leader group
|
||||
group = "bf2_%s_squad_leader" % squadname
|
||||
server.addUserToGroup(ngcfg[location], session, group)
|
||||
log.debug("Added '%s' @ %s to group %s in %s", newstate.name, ng or ngcfgname, group, location)
|
||||
|
||||
|
||||
group = "bf2_squad_leader"
|
||||
server.addUserToGroup(ngcfg[location], session, group)
|
||||
log.debug("Added '%s' @ %s to group %s in %s", newstate.name, ng or ngcfgname, group, location)
|
||||
|
||||
|
||||
# Override previous moves
|
||||
channame = "%s_%s_squad_leader" % (npi["team"], self.id_to_squad_name[npi["squad"]])
|
||||
newstate.channel = ngcfg[channame]
|
||||
|
||||
|
||||
if npi["commander"]:
|
||||
group = "bf2_commander"
|
||||
server.addUserToGroup(ngcfg[location], session, group)
|
||||
log.debug("Added '%s' @ %s to group %s in %s", newstate.name, ng or ngcfgname, group, location)
|
||||
|
||||
|
||||
# Override previous moves
|
||||
channame = "%s_commander" % npi["team"]
|
||||
newstate.channel = ngcfg[channame]
|
||||
|
||||
|
||||
if oli and not nli:
|
||||
log.debug("User '%s' (%d|%d) on server %d no longer linked", newstate.name, newstate.session, newstate.userid, sid)
|
||||
log.debug("User '%s' (%d|%d) on server %d no longer linked", newstate.name, newstate.session,
|
||||
newstate.userid, sid)
|
||||
server.removeUserFromGroup(0, session, "bf2_linked")
|
||||
|
||||
if newstate.channel >= 0 and newoldchannel != newstate.channel:
|
||||
if ng == None:
|
||||
|
||||
if 0 <= newstate.channel != newoldchannel:
|
||||
if ng is None:
|
||||
log.debug("Moving '%s' leaving %s to channel %s", newstate.name, og or ogcfgname, channame)
|
||||
else:
|
||||
log.debug("Moving '%s' @ %s to channel %s", newstate.name, ng or ngcfgname, channame)
|
||||
|
||||
|
||||
server.setState(newstate)
|
||||
|
||||
|
||||
def handle(self, server, state):
|
||||
def verify(mdict, key, vtype):
|
||||
if not isinstance(mdict[key], vtype):
|
||||
raise ValueError("'%s' of invalid type" % key)
|
||||
|
||||
|
||||
cfg = self.cfg()
|
||||
log = self.log()
|
||||
sid = server.id()
|
||||
@ -263,17 +266,17 @@ class bf2(MumoModule):
|
||||
state.parsedidentity = {}
|
||||
state.parsedcontext = {}
|
||||
state.is_linked = False
|
||||
|
||||
if sid not in self.sessions: # Make sure there is a dict to store states in
|
||||
|
||||
if sid not in self.sessions: # Make sure there is a dict to store states in
|
||||
self.sessions[sid] = {}
|
||||
|
||||
|
||||
update = False
|
||||
if state.session in self.sessions[sid]:
|
||||
if state.identity != self.sessions[sid][state.session].identity or \
|
||||
state.context != self.sessions[sid][state.session].context:
|
||||
state.context != self.sessions[sid][state.session].context:
|
||||
# identity or context changed => update
|
||||
update = True
|
||||
else: # id and context didn't change hence the old data must still be valid
|
||||
else: # id and context didn't change hence the old data must still be valid
|
||||
state.is_linked = self.sessions[sid][state.session].is_linked
|
||||
state.parsedcontext = self.sessions[sid][state.session].parsedcontext
|
||||
state.parsedidentity = self.sessions[sid][state.session].parsedidentity
|
||||
@ -282,46 +285,48 @@ class bf2(MumoModule):
|
||||
# New user with engaged plugin => update
|
||||
self.sessions[sid][state.session] = None
|
||||
update = True
|
||||
|
||||
|
||||
if not update:
|
||||
self.sessions[sid][state.session] = state
|
||||
return
|
||||
|
||||
|
||||
# The plugin will always prefix "Battlefield 2\0" to the context for the bf2 PA plugin
|
||||
# don't bother analyzing anything if it isn't there
|
||||
splitcontext = state.context.split('\0', 1)
|
||||
if splitcontext[0] == "Battlefield 2":
|
||||
state.is_linked = True
|
||||
if state.identity and len(splitcontext) == 1:
|
||||
#LEGACY: Assume broken Ice 3.2 which doesn't transmit context after \0
|
||||
splitcontext.append('{"ipport":""}') # Obviously this doesn't give full functionality but it doesn't crash either ;-)
|
||||
# LEGACY: Assume broken Ice 3.2 which doesn't transmit context after \0
|
||||
splitcontext.append(
|
||||
'{"ipport":""}') # Obviously this doesn't give full functionality but it doesn't crash either ;-)
|
||||
|
||||
if state.is_linked and len(splitcontext) == 2 and state.identity:
|
||||
if state.is_linked and len(splitcontext) == 2 and state.identity:
|
||||
try:
|
||||
context = json.loads(splitcontext[1])
|
||||
verify(context, "ipport", basestring)
|
||||
|
||||
verify(context, "ipport", str)
|
||||
|
||||
for i in range(cfg.bf2.gamecount):
|
||||
# Try to find a matching game
|
||||
gamename = "g%d" % i
|
||||
gamecfg = getattr(cfg, gamename)
|
||||
|
||||
|
||||
if gamecfg.mumble_server == server.id():
|
||||
not_matched = (gamecfg.ipport_filter.match(context["ipport"]) == None)
|
||||
not_matched = (gamecfg.ipport_filter.match(context["ipport"]) is None)
|
||||
if not_matched == gamecfg.ipport_filter_negate:
|
||||
break
|
||||
gamename = None
|
||||
|
||||
|
||||
if not gamename:
|
||||
raise ValueError("No matching game found")
|
||||
|
||||
|
||||
context["gamecfg"] = gamecfg
|
||||
context["gamename"] = gamename
|
||||
state.parsedcontext = context
|
||||
|
||||
except (ValueError, KeyError, AttributeError), e:
|
||||
log.debug("Invalid context for %s (%d|%d) on server %d: %s", state.name, state.session, state.userid, sid, repr(e))
|
||||
|
||||
except (ValueError, KeyError, AttributeError) as e:
|
||||
log.debug("Invalid context for %s (%d|%d) on server %d: %s", state.name, state.session, state.userid,
|
||||
sid, repr(e))
|
||||
|
||||
try:
|
||||
identity = json.loads(state.identity)
|
||||
verify(identity, "commander", bool)
|
||||
@ -329,48 +334,57 @@ class bf2(MumoModule):
|
||||
verify(identity, "squad", int)
|
||||
if identity["squad"] < 0 or identity["squad"] > 9:
|
||||
raise ValueError("Invalid squad number")
|
||||
verify(identity, "team", basestring)
|
||||
verify(identity, "team", str)
|
||||
if identity["team"] != "opfor" and identity["team"] != "blufor":
|
||||
raise ValueError("Invalid team identified")
|
||||
#LEGACY: Ice 3.2 cannot handle unicode strings
|
||||
# LEGACY: Ice 3.2 cannot handle unicode strings
|
||||
identity["team"] = str(identity["team"])
|
||||
|
||||
|
||||
state.parsedidentity = identity
|
||||
|
||||
except (KeyError, ValueError), e:
|
||||
log.debug("Invalid identity for %s (%d|%d) on server %d: %s", state.name, state.session, state.userid, sid, repr(e))
|
||||
|
||||
except (KeyError, ValueError) as e:
|
||||
log.debug("Invalid identity for %s (%d|%d) on server %d: %s", state.name, state.session, state.userid,
|
||||
sid, repr(e))
|
||||
|
||||
# Update state and remember it
|
||||
self.update_state(server, self.sessions[sid][state.session], state)
|
||||
self.sessions[sid][state.session] = state
|
||||
|
||||
|
||||
#
|
||||
#--- Server callback functions
|
||||
# --- Server callback functions
|
||||
#
|
||||
|
||||
def userDisconnected(self, server, state, context = None):
|
||||
|
||||
def userDisconnected(self, server, state, context=None):
|
||||
try:
|
||||
sid = server.id()
|
||||
del self.sessions[sid][state.session]
|
||||
except KeyError: pass
|
||||
|
||||
def userStateChanged(self, server, state, context = None):
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def userStateChanged(self, server, state, context=None):
|
||||
self.handle(server, state)
|
||||
|
||||
def userConnected(self, server, state, context = None):
|
||||
|
||||
def userConnected(self, server, state, context=None):
|
||||
self.handle(server, state)
|
||||
|
||||
def userTextMessage(self, server, user, message, current=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
|
||||
|
||||
|
||||
def userTextMessage(self, server, user, message, current=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
|
||||
|
||||
#
|
||||
#--- Meta callback functions
|
||||
# --- Meta callback functions
|
||||
#
|
||||
|
||||
def started(self, server, context = None):
|
||||
def started(self, server, context=None):
|
||||
self.sessions[server.id()] = {}
|
||||
|
||||
def stopped(self, server, context = None):
|
||||
|
||||
def stopped(self, server, context=None):
|
||||
self.sessions[server.id()] = {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8
|
||||
|
||||
# Copyright (C) 2010-2011 Stefan Hacker <dd0t@users.sourceforge.net>
|
||||
@ -37,45 +37,41 @@
|
||||
# once they become active again
|
||||
#
|
||||
|
||||
from mumo_module import (commaSeperatedIntegers,
|
||||
commaSeperatedBool,
|
||||
commaSeperatedStrings,
|
||||
MumoModule)
|
||||
|
||||
from threading import Timer
|
||||
import re
|
||||
from threading import Timer
|
||||
|
||||
|
||||
from config import commaSeperatedIntegers, commaSeperatedBool, commaSeperatedStrings
|
||||
from mumo_module import MumoModule
|
||||
|
||||
|
||||
class idlemove(MumoModule):
|
||||
default_config = {'idlemove':(
|
||||
('interval', float, 0.1),
|
||||
('servers', commaSeperatedIntegers, []),
|
||||
),
|
||||
lambda x: re.match('(all)|(server_\d+)', x):(
|
||||
('threshold', commaSeperatedIntegers, [3600]),
|
||||
('mute', commaSeperatedBool, [True]),
|
||||
('deafen', commaSeperatedBool, [False]),
|
||||
('channel', commaSeperatedIntegers, [1]),
|
||||
('source_channel', commaSeperatedIntegers, [-1]),
|
||||
('whitelist', commaSeperatedStrings, []),
|
||||
('channel_whitelist', commaSeperatedIntegers, [])
|
||||
),
|
||||
}
|
||||
|
||||
default_config = {'idlemove': (
|
||||
('interval', float, 0.1),
|
||||
('servers', commaSeperatedIntegers, []),
|
||||
),
|
||||
lambda x: re.match('(all)|(server_\d+)', x): (
|
||||
['threshold', commaSeperatedIntegers, [3600]],
|
||||
('mute', commaSeperatedBool, [True]),
|
||||
('deafen', commaSeperatedBool, [False]),
|
||||
('channel', commaSeperatedIntegers, [1]),
|
||||
('source_channel', commaSeperatedIntegers, [-1]),
|
||||
('whitelist', commaSeperatedStrings, []),
|
||||
('channel_whitelist', commaSeperatedIntegers, [])
|
||||
),
|
||||
}
|
||||
|
||||
def __init__(self, name, manager, configuration=None):
|
||||
MumoModule.__init__(self, name, manager, configuration)
|
||||
self.murmur = manager.getMurmurModule()
|
||||
self.watchdog = None
|
||||
|
||||
def connected(self):
|
||||
self.affectedusers = {} # {serverid:set(sessionids,...)}
|
||||
self.affectedusers = {} # {serverid:set(sessionids,...)}
|
||||
|
||||
manager = self.manager()
|
||||
log = self.log()
|
||||
log.debug("Register for Meta & Server callbacks")
|
||||
|
||||
|
||||
cfg = self.cfg()
|
||||
servers = cfg.idlemove.servers
|
||||
if not servers:
|
||||
@ -83,11 +79,11 @@ class idlemove(MumoModule):
|
||||
|
||||
manager.subscribeServerCallbacks(self, servers)
|
||||
manager.subscribeMetaCallbacks(self, servers)
|
||||
|
||||
|
||||
if not self.watchdog:
|
||||
self.watchdog = Timer(cfg.idlemove.interval, self.handleIdleMove)
|
||||
self.watchdog.start()
|
||||
|
||||
|
||||
def disconnected(self):
|
||||
self.affectedusers = {}
|
||||
if self.watchdog:
|
||||
@ -98,58 +94,55 @@ class idlemove(MumoModule):
|
||||
cfg = self.cfg()
|
||||
try:
|
||||
meta = self.manager().getMeta()
|
||||
|
||||
|
||||
if not cfg.idlemove.servers:
|
||||
servers = meta.getBootedServers()
|
||||
else:
|
||||
servers = [meta.getServer(server) for server in cfg.idlemove.servers]
|
||||
|
||||
|
||||
for server in servers:
|
||||
if not server: continue
|
||||
|
||||
if server:
|
||||
for user in server.getUsers().itervalues():
|
||||
self.UpdateUserAutoAway(server, user)
|
||||
for user in server.getUsers().values():
|
||||
self.UpdateUserAutoAway(server, user)
|
||||
finally:
|
||||
# Renew the timer
|
||||
self.watchdog = Timer(cfg.idlemove.interval, self.handleIdleMove)
|
||||
self.watchdog.start()
|
||||
|
||||
|
||||
def UpdateUserAutoAway(self, server, user):
|
||||
log = self.log()
|
||||
sid = server.id()
|
||||
|
||||
|
||||
try:
|
||||
scfg = getattr(self.cfg(), 'server_%d' % sid)
|
||||
except AttributeError:
|
||||
scfg = self.cfg().all
|
||||
|
||||
|
||||
try:
|
||||
index = self.affectedusers[sid]
|
||||
except KeyError:
|
||||
self.affectedusers[sid] = set()
|
||||
index = self.affectedusers[sid]
|
||||
|
||||
|
||||
# Check if the user is whitelisted
|
||||
if user.name in scfg.whitelist:
|
||||
return
|
||||
|
||||
# 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]
|
||||
@ -159,28 +152,27 @@ class idlemove(MumoModule):
|
||||
log.warning("Incomplete configuration for stage %d of server %i, ignored", i, server.id())
|
||||
continue
|
||||
|
||||
if user.idlesecs > threshold and\
|
||||
user.channel not in scfg.channel_whitelist and\
|
||||
(source_channel == -1 or\
|
||||
user.channel == source_channel or\
|
||||
user.channel == channel):
|
||||
|
||||
if user.idlesecs > threshold and user.channel not in scfg.channel_whitelist 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:
|
||||
if 0 <= channel != user.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())
|
||||
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
|
||||
@ -188,15 +180,15 @@ class idlemove(MumoModule):
|
||||
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
|
||||
# --- Server callback functions
|
||||
#
|
||||
def userDisconnected(self, server, state, context=None):
|
||||
try:
|
||||
@ -205,27 +197,35 @@ class idlemove(MumoModule):
|
||||
index.remove(state.session)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
def userStateChanged(self, server, state, context=None):
|
||||
self.UpdateUserAutoAway(server, state)
|
||||
|
||||
def userConnected(self, server, state, context=None): pass # Unused callbacks
|
||||
def userTextMessage(self, server, user, message, current=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
|
||||
|
||||
def userConnected(self, server, state, context=None):
|
||||
pass # Unused callbacks
|
||||
|
||||
def userTextMessage(self, server, user, message, current=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
|
||||
|
||||
#
|
||||
#--- Meta callback functions
|
||||
# --- Meta callback functions
|
||||
#
|
||||
|
||||
def started(self, server, context = None):
|
||||
|
||||
def started(self, server, context=None):
|
||||
sid = server.id()
|
||||
self.affectedusers[sid] = set()
|
||||
self.log().debug('Handling server %d', sid)
|
||||
|
||||
def stopped(self, server, context = None):
|
||||
|
||||
def stopped(self, server, context=None):
|
||||
sid = server.id()
|
||||
self.affectedusers[sid] = set()
|
||||
self.log().debug('Server %d gone', sid)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8
|
||||
|
||||
# Copyright (C) 2010-2011 Stefan Hacker <dd0t@users.sourceforge.net>
|
||||
@ -35,24 +35,25 @@
|
||||
# they connect regardless of which channel they were in when they left.
|
||||
#
|
||||
|
||||
from mumo_module import (commaSeperatedIntegers,
|
||||
MumoModule)
|
||||
import re
|
||||
|
||||
from config import commaSeperatedIntegers
|
||||
from mumo_module import MumoModule
|
||||
|
||||
|
||||
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):
|
||||
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()
|
||||
|
||||
@ -60,39 +61,53 @@ class onjoin(MumoModule):
|
||||
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
|
||||
|
||||
|
||||
def disconnected(self):
|
||||
pass
|
||||
|
||||
#
|
||||
#--- Server callback functions
|
||||
# --- Server callback functions
|
||||
#
|
||||
|
||||
def userConnected(self, server, state, context = None):
|
||||
|
||||
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)
|
||||
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 userTextMessage(self, server, user, message, current=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
|
||||
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 userTextMessage(self, server, user, message, current=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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8
|
||||
|
||||
# Copyright (C) 2015 Stefan Hacker <dd0t@users.sourceforge.net>
|
||||
@ -35,17 +35,19 @@
|
||||
# entries to a user's context menu.
|
||||
#
|
||||
|
||||
from mumo_module import (commaSeperatedIntegers,
|
||||
MumoModule)
|
||||
import cgi
|
||||
|
||||
from config import commaSeperatedIntegers
|
||||
from mumo_module import MumoModule
|
||||
|
||||
|
||||
class samplecontext(MumoModule):
|
||||
default_config = {'samplecontext':(
|
||||
('servers', commaSeperatedIntegers, []),
|
||||
),
|
||||
}
|
||||
|
||||
def __init__(self, name, manager, configuration = None):
|
||||
default_config = {'samplecontext': (
|
||||
('servers', commaSeperatedIntegers, []),
|
||||
),
|
||||
}
|
||||
|
||||
def __init__(self, name, manager, configuration=None):
|
||||
MumoModule.__init__(self, name, manager, configuration)
|
||||
self.murmur = manager.getMurmurModule()
|
||||
self.action_poke_user = manager.getUniqueAction()
|
||||
@ -56,19 +58,19 @@ class samplecontext(MumoModule):
|
||||
manager = self.manager()
|
||||
log = self.log()
|
||||
log.debug("Register for Server callbacks")
|
||||
|
||||
|
||||
servers = self.cfg().samplecontext.servers
|
||||
if not servers:
|
||||
servers = manager.SERVERS_ALL
|
||||
|
||||
|
||||
manager.subscribeServerCallbacks(self, servers)
|
||||
|
||||
|
||||
def disconnected(self): pass
|
||||
|
||||
#
|
||||
#--- Server callback functions
|
||||
# --- Server callback functions
|
||||
#
|
||||
|
||||
|
||||
def __on_poke_user(self, server, action, user, target):
|
||||
assert action == self.action_poke_user
|
||||
self.log().info(user.name + " poked " + target.name)
|
||||
@ -78,7 +80,7 @@ class samplecontext(MumoModule):
|
||||
assert action == self.action_info
|
||||
self.log().info(user.name + " wants info on " + str(target));
|
||||
server.sendMessage(user.session,
|
||||
"<small><pre>" + cgi.escape(str(target)) + "</pre></small>")
|
||||
"<small><pre>" + cgi.escape(str(target)) + "</pre></small>")
|
||||
|
||||
def __on_remove_this(self, server, action, user, target):
|
||||
# This will remove the entry identified by "action" from
|
||||
@ -86,7 +88,7 @@ class samplecontext(MumoModule):
|
||||
self.log().info(user.name + " triggered removal")
|
||||
self. |