Update bf2 modules to use xml instead of xml. Improve structure a bit. Improve log output. Fix some issues.
This commit is contained in:
146
modules/bf2.py
146
modules/bf2.py
@@ -35,12 +35,10 @@
|
|||||||
# gamestate reported by Mumble positional audio plugins
|
# gamestate reported by Mumble positional audio plugins
|
||||||
#
|
#
|
||||||
|
|
||||||
from mumo_module import (x2bool,
|
from mumo_module import MumoModule
|
||||||
MumoModule)
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from xml.etree import ElementTree
|
import json
|
||||||
from xml.parsers.expat import ExpatError
|
|
||||||
|
|
||||||
class bf2(MumoModule):
|
class bf2(MumoModule):
|
||||||
default_config = {'bf2':(
|
default_config = {'bf2':(
|
||||||
@@ -199,7 +197,7 @@ class bf2(MumoModule):
|
|||||||
channame = "%s_%s_squad" % (npi["team"], self.id_to_squad_name[npi["squad"]])
|
channame = "%s_%s_squad" % (npi["team"], self.id_to_squad_name[npi["squad"]])
|
||||||
newstate.channel = getattr(ngcfg, channame)
|
newstate.channel = getattr(ngcfg, channame)
|
||||||
|
|
||||||
if npi["is_leader"]:
|
if npi["squad_leader"]:
|
||||||
# In case the leader flag is set add to leader group
|
# 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"]])
|
group = "bf2%s_%s_%s_squad_leader" % (ng, npi["team"], self.id_to_squad_name[npi["squad"]])
|
||||||
server.addUserToGroup(ngcfg.base, session, group)
|
server.addUserToGroup(ngcfg.base, session, group)
|
||||||
@@ -210,7 +208,7 @@ class bf2(MumoModule):
|
|||||||
newstate.channel = getattr(ngcfg, channame)
|
newstate.channel = getattr(ngcfg, channame)
|
||||||
|
|
||||||
|
|
||||||
if npi["is_commander"]:
|
if npi["commander"]:
|
||||||
group = "bf2%s_%s_commander" % (ng, npi["team"])
|
group = "bf2%s_%s_commander" % (ng, npi["team"])
|
||||||
server.addUserToGroup(ngcfg.base, session, group)
|
server.addUserToGroup(ngcfg.base, session, group)
|
||||||
log.debug("Added '%s' @ %s to group %s", newstate.name, ng or ngcfgname, group)
|
log.debug("Added '%s' @ %s to group %s", newstate.name, ng or ngcfgname, group)
|
||||||
@@ -232,89 +230,87 @@ class bf2(MumoModule):
|
|||||||
server.setState(newstate)
|
server.setState(newstate)
|
||||||
|
|
||||||
def handle(self, server, state):
|
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()
|
cfg = self.cfg()
|
||||||
log = self.log()
|
log = self.log()
|
||||||
sid = server.id()
|
sid = server.id()
|
||||||
update = False
|
|
||||||
|
# Add defaults for our variables to state
|
||||||
|
state.parsedidentity = {}
|
||||||
|
state.parsedcontext = {}
|
||||||
state.is_linked = False
|
state.is_linked = False
|
||||||
|
|
||||||
if sid not in self.sessions:
|
if sid not in self.sessions: # Make sure there is a dict to store states in
|
||||||
self.sessions[sid] = {}
|
self.sessions[sid] = {}
|
||||||
|
|
||||||
|
update = False
|
||||||
if state.session in self.sessions[sid]:
|
if state.session in self.sessions[sid]:
|
||||||
if state.identity != self.sessions[sid][state.session].identity:
|
if state.identity != self.sessions[sid][state.session].identity or \
|
||||||
update = True
|
state.context != self.sessions[sid][state.session].context:
|
||||||
|
# identity or context changed => update
|
||||||
if state.context != self.sessions[sid][state.session].context:
|
|
||||||
update = True
|
update = True
|
||||||
else:
|
else:
|
||||||
if state.identity or state.context:
|
if state.identity or state.context:
|
||||||
|
# New user with engaged plugin => update
|
||||||
self.sessions[sid][state.session] = None
|
self.sessions[sid][state.session] = None
|
||||||
update = True
|
update = True
|
||||||
else:
|
|
||||||
self.sessions[sid][state.session] = state
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
if update:
|
|
||||||
if state.context.startswith("Battlefield 2\0"):
|
|
||||||
state.is_linked = True
|
|
||||||
|
|
||||||
try:
|
if not update:
|
||||||
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.parsedidentity = {}
|
|
||||||
state.parsedcontext = {}
|
|
||||||
|
|
||||||
|
|
||||||
self.update_state(server, self.sessions[sid][state.session], state)
|
|
||||||
self.sessions[sid][state.session] = state
|
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.is_linked and len(splitcontext) == 2 and state.identity:
|
||||||
|
try:
|
||||||
|
context = json.loads(splitcontext[1])
|
||||||
|
verify(context, "ipport", basestring)
|
||||||
|
|
||||||
|
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(context["ipport"]):
|
||||||
|
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))
|
||||||
|
|
||||||
|
try:
|
||||||
|
identity = json.loads(state.identity)
|
||||||
|
verify(identity, "commander", bool)
|
||||||
|
verify(identity, "squad_leader", bool)
|
||||||
|
verify(identity, "squad", int)
|
||||||
|
if identity["squad"] < 0 or identity["squad"] > 9:
|
||||||
|
raise ValueError("Invalid squad number")
|
||||||
|
verify(identity, "team", basestring)
|
||||||
|
if identity["team"] != "opfor" and identity["team"] != "blufor":
|
||||||
|
raise ValueError("Invalid team identified")
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
# 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
|
||||||
|
Reference in New Issue
Block a user