#!/usr/bin/env python # -*- coding: utf-8 # Copyright (C) 2010 Stefan Hacker # 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. # # mbf2man.py # This small programm is for creating a possible channel/acl structure for # the mumo bf2 module as well as the corresponding bf2.ini configuration file. import os import sys import tempfile from optparse import OptionParser # Default settings import Ice import IcePy if __name__ == "__main__": parser = OptionParser() parser.add_option('-t', '--target', help = 'Host to connect to', default = "127.0.0.1") parser.add_option('-p', '--port', help = 'Port to connect to', default = "6502") parser.add_option('-b', '--base', help = 'Channel id of the base channel', default = '0') parser.add_option('-v', '--vserver', help = 'Virtual server id', default = '1') parser.add_option('-i', '--ice', help = 'Path to slice file', default = 'Murmur.ice') parser.add_option('-s', '--secret', help = 'Ice secret', default = '') parser.add_option('-n', '--name', help = 'Treename', default = 'BF2') parser.add_option('-o', '--out', default = 'bf2.ini', help = 'File to output configuration to') parser.add_option('-d', '--slicedir', help = 'System slice directory used when getSliceDir is not available', default = '/usr/share/slice') (option, args) = parser.parse_args() host = option.target slicedir = option.slicedir try: port = int(option.port) except ValueError: print "Port value '%s' is invalid" % option.port sys.exit(1) try: basechan = int(option.base) if basechan < 0: raise ValueError except ValueError: print "Base channel value '%s' invalid" % option.base sys.exit(1) try: sid = int(option.vserver) if sid < 1: raise ValueError except ValueError: print "Virtual server id value '%s' invalid" % option.vserver sys.exit(1) name = option.name prxstr = "Meta:tcp -h %s -p %d -t 1000" % (host, port) secret = option.secret props = Ice.createProperties(sys.argv) props.setProperty("Ice.ImplicitContext", "Shared") idata = Ice.InitializationData() idata.properties = props ice = Ice.initialize(idata) prx = ice.stringToProxy(prxstr) print "Done" def lslice(slf): if not hasattr(Ice, "getSliceDir"): Ice.loadSlice('-I%s %s' % (slicedir, slf)) else: Ice.loadSlice('', ['-I' + Ice.getSliceDir(), slf]) try: print "Trying to retrieve slice dynamically from server...", op = IcePy.Operation('getSlice', Ice.OperationMode.Idempotent, Ice.OperationMode.Idempotent, True, (), (), (), IcePy._t_string, ()) if hasattr(Ice, "getSliceDir"): slice = op.invoke(prx, ((), None)) else: slice = op.invoke(prx, (), None) (dynslicefiledesc, dynslicefilepath) = tempfile.mkstemp(suffix = '.ice') dynslicefile = os.fdopen(dynslicefiledesc, 'w') dynslicefile.write(slice) dynslicefile.flush() lslice(dynslicefilepath) dynslicefile.close() os.remove(dynslicefilepath) print "Success" except Exception, e: print "Failed" print str(e) slicefile = option.ice print "Load slice (%s)..." % slicefile, lslice(slicefile) print "Done" print "Import dynamically compiled murmur class...", import Murmur print "Done" print "Establish ice connection...", if secret: print "[protected]...", ice.getImplicitContext().put("secret", secret) murmur = Murmur.MetaPrx.checkedCast(prx) print "Done" print "Get server...", server = murmur.getServer(sid) print "Done (%d)" % sid ini = {} ini['mumble_server'] = sid ini['name'] = name ini['ipport_filter'] = '.*' print "Creating channel structure:" ACL = Murmur.ACL EAT = Murmur.PermissionEnter | Murmur.PermissionTraverse W = Murmur.PermissionWhisper S = Murmur.PermissionSpeak print name ini['left'] = basechan gamechan = server.addChannel(name, basechan) # mice.Murmur.ACL(self, applyHere=False, applySubs=False, # inherited=False, userid=0, group='', allow=0, deny=0) # mice.s.setACL(self, channelid, acls, groups, inherit, _ctx=None) server.setACL(gamechan, [ACL(applyHere = True, applySubs = True, userid = -1, group = 'all', deny = EAT | W | S), ACL(applyHere = True, applySubs = True, userid = -1, group = '~bf2_%s_game' % name, allow = S), ACL(applyHere = True, applySubs = False, userid = -1, group = '~bf2_%s_game' % name, allow = EAT | W)], [], True) gamechanstate = server.getChannelState(gamechan) teams = ["blufor", "opfor"] id_to_squad_name = ["no", "alpha", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india"] for team in teams: print name + "/" + team cid = server.addChannel(team, gamechan) gamechanstate.links.append(cid) ini[team] = cid server.setACL(ini[team], [ACL(applyHere = True, applySubs = False, userid = -1, group = '~bf2_team', allow = EAT | W)], [], True) print name + "/" + team + "_commander" cid = server.addChannel("commander", ini[team]) gamechanstate.links.append(cid) ini[team + "_commander"] = cid server.setACL(ini[team + "_commander"], [ACL(applyHere = True, applySubs = False, userid = -1, group = '~bf2_commander', allow = EAT | W), ACL(applyHere = True, applySubs = False, userid = -1, group = '~bf2_squad_leader', allow = W)], [], True) state = server.getChannelState(ini[team+"_commander"]) state.position = -1 server.setChannelState(state) for squad in id_to_squad_name: print name + "/" + team + "/" + squad cid = server.addChannel(squad, ini[team]) gamechanstate.links.append(cid) ini[team + "_" + squad + "_squad"] = cid ini[team + "_" + squad + "_squad_leader"] = ini[team + "_" + squad + "_squad"] server.setACL(ini[team + "_" + squad + "_squad"], [ACL(applyHere = True, applySubs = False, userid = -1, group = '~bf2_%s_squad' % squad, allow = EAT | W), ACL(applyHere = True, applySubs = False, userid = -1, group = '~bf2_commander', allow = EAT | W), ACL(applyHere = True, applySubs = False, userid = -1, group = '~bf2_squad_leader', allow = W)], [], True) server.setChannelState(gamechanstate) print "Channel structure created" print "Writing configuration to output file '%s'..." % option.out, f = open(option.out, "w") print>>f, "; Configuration created by mbf2man\n" print>>f, "[bf2]\ngamecount = 1\n" print>>f, "[g0]" for key in sorted(ini): value = ini[key] print>>f, "%s = %s" % (key, value) f.close() print "Done"