Add capability to delete unused channels to source plugin

This commit is contained in:
Stefan Hacker
2013-02-26 10:57:35 +01:00
parent deb9aba022
commit e09ba4fb93
5 changed files with 210 additions and 35 deletions

View File

@@ -54,7 +54,7 @@ class source(MumoModule):
('restrict', x2bool, True),
('serverregex', re.compile, re.compile("^\[[\w\d\-\(\):]{1,20}\]$")),
('createifmissing', x2bool, True),
('deleteifunused', x2bool, False)
('deleteifunused', x2bool, True)
)
default_config = {'source':(
@@ -127,11 +127,11 @@ class source(MumoModule):
def disconnected(self): pass
def userTransition(self, server, old, new):
sid = server.id()
def userTransition(self, mumble_server, old, new):
sid = mumble_server.id()
assert(not old or old.valid())
relevant = old or (new and new.valid())
if not relevant:
return
@@ -148,17 +148,29 @@ class source(MumoModule):
if not user_gone:
#TODO: Establish new group memberships
self.moveUser(server,
new.state,
new.game,
new.server,
new.identity["team"])
moved = self.moveUser(mumble_server, new)
else:
# User gone
assert(old)
self.users.remove(sid, old.state.session)
moved = True
if not new:
self.dlog(sid, old.state, "User gone")
else:
# Move user out of our channel structure
self.moveUserToCid(mumble_server, new.state, self.cfg().source.basechannelid)
self.dlog(sid, old.state, "User stopped playing")
if moved and old:
# If moved from a valid game state perform channel use check
chan = self.db.channelForCid(sid, old.state.channel)
if chan:
_, _, game, _, _ = chan
if self.gameCfg(game, "deleteifunused"):
self.deleteIfUnused(mumble_server, old.state.channel)
def getGameName(self, game):
@@ -230,16 +242,67 @@ class source(MumoModule):
state.channel = cid
server.setState(state)
def moveUser(self, mumble_server, state, game, server, team):
def moveUser(self, mumble_server, user):
state = user.state
game = user.game
server = user.server
team = user.identity["team"]
sid = mumble_server.id()
source_cid = state.channel
target_cid = self.getOrCreateChannelFor(mumble_server, game, server, team)
if source_cid != target_cid:
self.moveUserToCid(mumble_server, state, target_cid)
# TODO: Source channel deletion if unused
user.state.channel = target_cid
self.users.addOrUpdate(sid, state.session, user)
return True
return False
def deleteIfUnused(self, mumble_server, cid):
"""
Takes the cid of a server or team channel and checks if all
related channels (siblings and server) are unused. If true
the channel is unused and will be deleted.
Note: Assumes tree structure
"""
sid = mumble_server.id()
log = self.log()
result = self.db.channelForCid(sid, cid)
if not result:
return False
_, _, cur_game, cur_server, cur_team = result
assert(cur_game)
if not cur_server:
# Don't handle game channels
log.debug("(%d) Delete if unused on game channel %d, ignoring", sid, cid)
return False
server_channel_cid = None
relevant = self.db.channelsFor(sid, cur_game, cur_server)
for _, cur_cid, _, _, cur_team in relevant:
if cur_team == None:
server_channel_cid = cur_cid
if self.users.usingChannel(sid, cur_cid):
log.debug("(%d) Delete if unused: Channel %d in use", sid, cur_cid)
return False # Used
assert(server_channel_cid != None)
# Unused. Delete server and children
log.debug("(%s) Channel %d unused. Will be deleted.", sid, server_channel_cid)
mumble_server.removeChannel(server_channel_cid)
return True
def validGameType(self, game):
return self.cfg().source.gameregex.match(game) != None
@@ -301,7 +364,6 @@ class source(MumoModule):
self.log().debug("(%d) (%d|%d) " + what, sid, state.session, state.userid, *argc)
def handle(self, server, new_state):
log = self.log()
sid = server.id()
session = new_state.session
@@ -317,22 +379,15 @@ class source(MumoModule):
game, game_server = self.parseSourceContext(new_state.context)
identity = self.parseSourceIdentity(new_state.identity)
self.dlog(sid, new_state, "Context: '%s' -> '%s'", game, game_server)
self.dlog(sid, new_state, "Identity: '%s'", identity)
self.dlog(sid, new_state, "Context: %s -> '%s' / '%s'", repr(new_state.context), game, game_server)
self.dlog(sid, new_state, "Identity: %s -> '%s'", repr(new_state.identity), identity)
updated_user = User(new_state, identity, game, game_server)
self.dlog(sid, new_state, "Starting transition")
self.userTransition(server, old_user, updated_user)
if updated_user.valid():
self.users.addOrUpdate(sid, session, updated_user)
self.dlog(sid, new_state, "Transition completed")
else:
# User isn't relevant for this plugin
self.users.remove(sid, session)
self.dlog(sid, new_state, "User not of concern for plugin")
self.dlog(sid, new_state, "Transition complete")
#
#--- Server callback functions
#