Add utmost uberhakish bf2.py module for some testing. Needs lots and lots of cleanup later ;-)
This commit is contained in:
57
modules-available/bf2.ini
Normal file
57
modules-available/bf2.ini
Normal file
@@ -0,0 +1,57 @@
|
||||
;
|
||||
; This is a sample configuration file for the mumo bf2 module.
|
||||
; The bf2 module manages ACL/channel movements based on battlefield 2
|
||||
; gamestate reported by Mumble positional audio plugins
|
||||
;
|
||||
|
||||
[bf2]
|
||||
gamecount = 1
|
||||
|
||||
[g0]
|
||||
name =
|
||||
mumble_server = 1
|
||||
ipport_filter = .*
|
||||
|
||||
left = -1
|
||||
|
||||
blufor_commander = -1
|
||||
blufor_no_squad = -1
|
||||
blufor_alpha_squad = -1
|
||||
blufor_alpha_squad_leader = -1
|
||||
blufor_bravo_squad = -1
|
||||
blufor_bravo_squad_leader = -1
|
||||
blufor_charlie_squad = -1
|
||||
blufor_charlie_squad_leader = -1
|
||||
blufor_delta_squad = -1
|
||||
blufor_delta_squad_leader = -1
|
||||
blufor_echo_squad = -1
|
||||
blufor_echo_squad_leader = -1
|
||||
blufor_foxtrot_squad = -1
|
||||
blufor_foxtrot_squad_leader = -1
|
||||
blufor_gold_squad = -1
|
||||
blufor_gold_squad_leader = -1
|
||||
blufor_hotel_squad = -1
|
||||
blufor_hotel_squad_leader = -1
|
||||
blufor_india_squad = -1
|
||||
blufor_india_squad_leader = -1
|
||||
|
||||
opfor_commander = -1
|
||||
opfor_no_squad = -1
|
||||
opfor_alpha_squad = -1
|
||||
opfor_alpha_squad_leader = -1
|
||||
opfor_bravo_squad = -1
|
||||
opfor_bravo_squad_leader = -1
|
||||
opfor_charlie_squad = -1
|
||||
opfor_charlie_squad_leader = -1
|
||||
opfor_delta_squad = -1
|
||||
opfor_delta_squad_leader = -1
|
||||
opfor_echo_squad = -1
|
||||
opfor_echo_squad_leader = -1
|
||||
opfor_foxtrot_squad = -1
|
||||
opfor_foxtrot_squad_leader = -1
|
||||
opfor_gold_squad = -1
|
||||
opfor_gold_squad_leader = -1
|
||||
opfor_hotel_squad = -1
|
||||
opfor_hotel_squad_leader = -1
|
||||
opfor_india_squad = -1
|
||||
opfor_india_squad_leader = -1
|
330
modules/bf2.py
Normal file
330
modules/bf2.py
Normal file
@@ -0,0 +1,330 @@
|
||||
#!/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.
|
||||
|
||||
#
|
||||
# bf2.py
|
||||
# This module manages ACL/channel movements based on battlefield 2
|
||||
# gamestate reported by Mumble positional audio plugins
|
||||
#
|
||||
|
||||
from mumo_module import (x2bool,
|
||||
MumoModule)
|
||||
|
||||
import re
|
||||
from xml.etree import ElementTree
|
||||
from xml.parsers.expat import ExpatError
|
||||
|
||||
class bf2(MumoModule):
|
||||
default_config = {'bf2':(
|
||||
('gamecount', int, 1),
|
||||
),
|
||||
lambda x: re.match('g\d+', x):(
|
||||
('name', str, ''),
|
||||
('mumble_server', int, 1),
|
||||
('ipport_filter', re.compile, re.compile('.*')),
|
||||
|
||||
('left', int, -1),
|
||||
|
||||
('blufor_commander', int, -1),
|
||||
('blufor_no_squad', int, -1),
|
||||
('blufor_alpha_squad', int, -1),
|
||||
('blufor_alpha_squad_leader', int, -1),
|
||||
('blufor_bravo_squad', int, -1),
|
||||
('blufor_bravo_squad_leader', int, -1),
|
||||
('blufor_charlie_squad', int, -1),
|
||||
('blufor_charlie_squad_leader', int, -1),
|
||||
('blufor_delta_squad', int, -1),
|
||||
('blufor_delta_squad_leader', int, -1),
|
||||
('blufor_echo_squad', int, -1),
|
||||
('blufor_echo_squad_leader', int, -1),
|
||||
('blufor_foxtrot_squad', int, -1),
|
||||
('blufor_foxtrot_squad_leader', int, -1),
|
||||
('blufor_gold_squad', int, -1),
|
||||
('blufor_gold_squad_leader', int, -1),
|
||||
('blufor_hotel_squad', int, -1),
|
||||
('blufor_hotel_squad_leader', int, -1),
|
||||
('blufor_india_squad', int, -1),
|
||||
('blufor_india_squad_leader', int, -1),
|
||||
|
||||
('opfor_commander', int, -1),
|
||||
('opfor_no_squad', int, -1),
|
||||
('opfor_alpha_squad', int, -1),
|
||||
('opfor_alpha_squad_leader', int, -1),
|
||||
('opfor_bravo_squad', int, -1),
|
||||
('opfor_bravo_squad_leader', int, -1),
|
||||
('opfor_charlie_squad', int, -1),
|
||||
('opfor_charlie_squad_leader', int, -1),
|
||||
('opfor_delta_squad', int, -1),
|
||||
('opfor_delta_squad_leader', int, -1),
|
||||
('opfor_echo_squad', int, -1),
|
||||
('opfor_echo_squad_leader', int, -1),
|
||||
('opfor_foxtrot_squad', int, -1),
|
||||
('opfor_foxtrot_squad_leader', int, -1),
|
||||
('opfor_gold_squad', int, -1),
|
||||
('opfor_gold_squad_leader', int, -1),
|
||||
('opfor_hotel_squad', int, -1),
|
||||
('opfor_hotel_squad_leader', int, -1),
|
||||
('opfor_india_squad', int, -1),
|
||||
('opfor_india_squad_leader', int, -1)
|
||||
),
|
||||
}
|
||||
|
||||
id_to_squad_name = ["no", "alpha", "bravo", "charlie", "delta", "echo", "foxtrot", "gold", "hotel", "india"]
|
||||
|
||||
def __init__(self, name, manager, configuration = None):
|
||||
MumoModule.__init__(self, name, manager, configuration)
|
||||
self.murmur = manager.getMurmurModule()
|
||||
|
||||
def connected(self):
|
||||
cfg = self.cfg()
|
||||
manager = self.manager()
|
||||
log = self.log()
|
||||
log.debug("Register for Server callbacks")
|
||||
|
||||
servers = set()
|
||||
for i in range(cfg.bf2.gamecount):
|
||||
try:
|
||||
servers.add(getattr(cfg, "g%d" % i).mumble_server)
|
||||
except AttributeError:
|
||||
log.error("Invalid configuration. Game configuration for 'g%d' not found.", i)
|
||||
return
|
||||
|
||||
self.sessions = {} # {sid:laststae}
|
||||
manager.subscribeServerCallbacks(self, servers)
|
||||
manager.subscribeMetaCallbacks(self, servers)
|
||||
|
||||
def disconnected(self): pass
|
||||
|
||||
#
|
||||
#--- Server callback functions
|
||||
#
|
||||
|
||||
def update_state(self, server, oldstate, newstate):
|
||||
log = self.log()
|
||||
sid = server.id()
|
||||
|
||||
session = newstate.session
|
||||
newoldchannel = newstate.channel
|
||||
|
||||
try:
|
||||
oli = oldstate.is_linked
|
||||
opc = oldstate.parsedcontext
|
||||
ogcfgname = opc["gamename"]
|
||||
ogcfg = opc["gamecfg"]
|
||||
og = ogcfg.name
|
||||
opi = oldstate.parsedidentity
|
||||
except (AttributeError, KeyError):
|
||||
og = None
|
||||
|
||||
opi = {}
|
||||
opc = {}
|
||||
oli = False
|
||||
|
||||
try:
|
||||
nli = newstate.is_linked
|
||||
npc = newstate.parsedcontext
|
||||
ngcfgname = npc["gamename"]
|
||||
ngcfg = npc["gamecfg"]
|
||||
ng = ngcfg.name
|
||||
npi = newstate.parsedidentity
|
||||
except (AttributeError, KeyError):
|
||||
ng = None
|
||||
|
||||
npi = {}
|
||||
npc = {}
|
||||
nli = False
|
||||
|
||||
# print opc
|
||||
# print npc
|
||||
# print opi
|
||||
# print npi
|
||||
|
||||
if not oli and nli:
|
||||
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 != npi or opc != opi) and opi and opc:
|
||||
log.debug("Removing user '%s' (%d|%d) on server %d from groups of game %s", newstate.name, newstate.session, newstate.userid, sid, og or ogcfgname)
|
||||
server.removeUserFromGroup(0, session, "bf2%s_%s_commander" % (og, opi["team"]))
|
||||
server.removeUserFromGroup(0, session, "bf2%s_%s_%s_squad_leader" % (og, opi["team"], self.id_to_squad_name[opi["squad"]]))
|
||||
server.removeUserFromGroup(0, session, "bf2%s_%s_%s_squad" % (og, opi["team"], self.id_to_squad_name[opi["squad"]]))
|
||||
server.removeUserFromGroup(0, session, "bf2%s_%s" % (og, opi["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))
|
||||
|
||||
# First add to team group
|
||||
group = "bf2%s_%s" % (ng, npi["team"])
|
||||
server.addUserToGroup(0, session, group)
|
||||
log.debug("Added '%s' @ %s to group %s", newstate.name, ng or ngcfgname, group)
|
||||
|
||||
# Then add to squad group
|
||||
group = "bf2%s_%s_%s_squad" % (ng, npi["team"], self.id_to_squad_name[npi["squad"]])
|
||||
server.addUserToGroup(0, session, group)
|
||||
log.debug("Added '%s' @ %s to group %s", newstate.name, ng or ngcfgname, group)
|
||||
|
||||
channame = "%s_%s_squad" % (npi["team"], self.id_to_squad_name[npi["squad"]])
|
||||
newstate.channel = getattr(ngcfg, channame)
|
||||
|
||||
if npi["is_leader"]:
|
||||
# In case the leader flag is set add to leader group
|
||||
group = "bf2%s_%s_%s_squad_leader" % (ng, npi["team"], self.id_to_squad_name[npi["squad"]])
|
||||
server.addUserToGroup(0, session, group)
|
||||
log.debug("Added '%s' @ %s to group %s", newstate.name, ng or ngcfgname, group)
|
||||
|
||||
# Override previous moves
|
||||
channame = "%s_%s_squad_leader" % (npi["team"], self.id_to_squad_name[npi["squad"]])
|
||||
newstate.channel = getattr(ngcfg, channame)
|
||||
|
||||
|
||||
if npi["is_commander"]:
|
||||
group = "bf2%s_%s_commander" % (ng, npi["team"])
|
||||
server.addUserToGroup(0, session, group)
|
||||
log.debug("Added '%s' @ %s to group %s", newstate.name, ng or ngcfgname, group)
|
||||
|
||||
# Override previous moves
|
||||
channame = "%s_commander" % npi["team"]
|
||||
newstate.channel = getattr(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)
|
||||
server.removeUserFromGroup(0, session, "bf2_linked")
|
||||
|
||||
if newstate.channel > 0 and newoldchannel != newstate.channel:
|
||||
if ng == 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):
|
||||
cfg = self.cfg()
|
||||
log = self.log()
|
||||
update = False
|
||||
if state.session in self.sessions:
|
||||
if state.identity != self.sessions[state.session].identity:
|
||||
update = True
|
||||
|
||||
if state.context != self.sessions[state.session].context:
|
||||
update = True
|
||||
else:
|
||||
if state.identity or state.context:
|
||||
self.sessions[state.session] = None
|
||||
update = True
|
||||
else:
|
||||
self.sessions[state.session] = state
|
||||
return
|
||||
|
||||
if update:
|
||||
if state.context.startswith("Battlefield 2\0"):
|
||||
state.is_linked = True
|
||||
|
||||
try:
|
||||
context = ElementTree.fromstring(state.context.split('\0', 1)[1])
|
||||
|
||||
ipport = context.find("ipport").text
|
||||
if ipport == None:
|
||||
ipport = ''
|
||||
|
||||
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() and \
|
||||
gamecfg.ipport_filter.match(ipport):
|
||||
break
|
||||
gamename = None
|
||||
|
||||
if not gamename:
|
||||
raise ValueError("No matching game found")
|
||||
|
||||
state.parsedcontext = {'ipport' : ipport,
|
||||
'gamecfg' : gamecfg,
|
||||
'gamename' : gamename}
|
||||
|
||||
except (ExpatError, AttributeError, ValueError):
|
||||
state.parsedcontext = {}
|
||||
|
||||
try:
|
||||
identity = ElementTree.fromstring(state.identity)
|
||||
|
||||
is_commander = x2bool(identity.find("commander").text)
|
||||
is_leader = x2bool(identity.find("squad_leader").text)
|
||||
team = identity.find("team").text
|
||||
if team != "opfor" and team != "blufor":
|
||||
raise ValueError("Invalid team value '%s'" % team)
|
||||
|
||||
squad = int(identity.find("squad").text)
|
||||
if squad < 0 or squad > 9:
|
||||
raise ValueError("Invalid squad value '%s'" % squad)
|
||||
|
||||
state.parsedidentity = {'team' : team,
|
||||
'squad' : squad,
|
||||
'is_leader' : is_leader,
|
||||
'is_commander' : is_commander}
|
||||
|
||||
except (ExpatError, AttributeError, ValueError):
|
||||
state.parsedidentity = {}
|
||||
|
||||
else:
|
||||
state.is_linked = False
|
||||
state.parsedidentity = {}
|
||||
state.parsedcontext = {}
|
||||
|
||||
|
||||
self.update_state(server, self.sessions[state.session], state)
|
||||
self.sessions[state.session] = state
|
||||
|
||||
def userDisconnected(self, server, state, context = None):
|
||||
try:
|
||||
del self.sessions[state.session]
|
||||
except KeyError: pass
|
||||
|
||||
def userStateChanged(self, server, state, context = None):
|
||||
self.handle(server, state)
|
||||
|
||||
def userConnected(self, server, state, context = None):
|
||||
self.handle(server, state)
|
||||
|
||||
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
|
||||
#
|
||||
|
||||
def started(self, server, context = None): pass
|
||||
def stopped(self, server, context = None): pass
|
@@ -29,6 +29,14 @@
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# idlemove.py
|
||||
#
|
||||
# Module for moving/muting/deafening idle players after
|
||||
# a certain amount of time and moving them back once
|
||||
# they interact again.
|
||||
#
|
||||
|
||||
from mumo_module import (x2bool,
|
||||
commaSeperatedIntegers,
|
||||
MumoModule,
|
||||
|
@@ -29,6 +29,12 @@
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# onjoin.py
|
||||
# This module allows moving players into a specific channel once
|
||||
# they connect regardless of which channel they were in when they left.
|
||||
#
|
||||
|
||||
from mumo_module import (x2bool,
|
||||
commaSeperatedIntegers,
|
||||
MumoModule,
|
||||
|
@@ -29,6 +29,14 @@
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# test.py
|
||||
# The test module has heavy debug output was solely
|
||||
# written for testing the basic framework as well as
|
||||
# debugging purposes. Usually you don't want
|
||||
# to use this.
|
||||
#
|
||||
|
||||
from mumo_module import (x2bool,
|
||||
MumoModule,
|
||||
logModFu)
|
||||
|
Reference in New Issue
Block a user