plugins room_games, radiocol, libervia: small changes like refactorization to ease the maintenance
This commit is contained in:
parent
4818da04fc
commit
30dfdf1025
4 changed files with 73 additions and 52 deletions
|
|
@ -235,27 +235,19 @@ class Radiocol(object):
|
|||
else:
|
||||
error(_('Unmanaged game element: %s') % elt.name)
|
||||
|
||||
def getSyncData(self, room_jid_s, force_nicks=[]):
|
||||
data = {}
|
||||
def getSyncDataForPlayer(self, room_jid_s, nick):
|
||||
game_data = self.games[room_jid_s]
|
||||
status = game_data['status']
|
||||
nicks = [nick for nick in status if status[nick] == 'desync']
|
||||
for nick in force_nicks:
|
||||
if nick not in nicks:
|
||||
nicks.append(nick)
|
||||
for nick in nicks:
|
||||
elements = []
|
||||
if game_data['playing']:
|
||||
preload = copy.deepcopy(game_data['playing'])
|
||||
preload['filename'] += '#t=%.2f' % (time.time() - game_data['playing_time'])
|
||||
elements.append(preload)
|
||||
play = domish.Element(('', 'play'))
|
||||
play['filename'] = preload['filename']
|
||||
elements.append(play)
|
||||
if len(game_data['queue']) > 0:
|
||||
elements.extend(copy.deepcopy(game_data['queue']))
|
||||
if len(game_data['queue']) == QUEUE_LIMIT:
|
||||
elements.append(domish.Element(('', 'no_upload')))
|
||||
if data:
|
||||
data[nick] = elements
|
||||
return data
|
||||
elements = []
|
||||
if game_data['playing']:
|
||||
preload = copy.deepcopy(game_data['playing'])
|
||||
current_time = game_data['playing_time'] + 1 if self.testing else time.time()
|
||||
preload['filename'] += '#t=%.2f' % (current_time - game_data['playing_time'])
|
||||
elements.append(preload)
|
||||
play = domish.Element(('', 'play'))
|
||||
play['filename'] = preload['filename']
|
||||
elements.append(play)
|
||||
if len(game_data['queue']) > 0:
|
||||
elements.extend(copy.deepcopy(game_data['queue']))
|
||||
if len(game_data['queue']) == QUEUE_LIMIT:
|
||||
elements.append(domish.Element(('', 'no_upload')))
|
||||
return elements
|
||||
|
|
|
|||
|
|
@ -108,14 +108,19 @@ class RoomGame(object):
|
|||
self.join_mode = self.INVITED
|
||||
self.ready_mode = self.FORCE # TODO: asking for confirmation is not implemented
|
||||
|
||||
# this has been added for testing purpose. It is sometimes needed to remove a dependence
|
||||
# while building the synchronization data, for example to replace a call to time.time()
|
||||
# by an arbitrary value. If needed, this attribute would be set to True from the testcase.
|
||||
self.testing = False
|
||||
|
||||
host.trigger.add("MUC user joined", self.userJoinedTrigger)
|
||||
host.trigger.add("MUC user left", self.userLeftTrigger)
|
||||
|
||||
def _createOrInvite(self, room, other_players, profile):
|
||||
"""
|
||||
This is called only when someone explicitly wants to play.
|
||||
The game must not be created if one already exists in the room,
|
||||
and its creation could be postponed until all the expected players
|
||||
The game will not be created if one already exists in the room,
|
||||
also its creation could be postponed until all the expected players
|
||||
join the room (in that case it will be created from userJoinedTrigger).
|
||||
@param room: instance of wokkel.muc.Room
|
||||
@param other_players: list for other players JID userhosts
|
||||
|
|
@ -128,7 +133,7 @@ class RoomGame(object):
|
|||
if not self._checkJoinAuth(room_jid_s, user_jid.userhost(), nick):
|
||||
return
|
||||
nicks.extend(self._invitePlayers(room, other_players, nick, profile))
|
||||
self._updatePlayers(room_jid_s, nicks, profile)
|
||||
self._updatePlayers(room_jid_s, nicks, True, profile)
|
||||
else:
|
||||
self._initGame(room_jid_s, nick)
|
||||
(auth, waiting, missing) = self._checkWaitAuth(room, other_players)
|
||||
|
|
@ -137,7 +142,7 @@ class RoomGame(object):
|
|||
if auth:
|
||||
self.createGame(room_jid_s, nicks, profile)
|
||||
else:
|
||||
self._updatePlayers(room_jid_s, nicks, profile)
|
||||
self._updatePlayers(room_jid_s, nicks, False, profile)
|
||||
|
||||
def _initGame(self, room_jid_s, referee_nick):
|
||||
"""Important: do not add the referee to 'players' yet. For a
|
||||
|
|
@ -191,11 +196,14 @@ class RoomGame(object):
|
|||
debug(_("%s not allowed to join the game %s in %s") % (user_jid_s or nick, self.name, room_jid_s))
|
||||
return auth
|
||||
|
||||
def _updatePlayers(self, room_jid_s, nicks, profile):
|
||||
def _updatePlayers(self, room_jid_s, nicks, sync, profile):
|
||||
"""Update the list of players and signal to the room that some players joined the game.
|
||||
If sync is True, the news players are synchronized with the game data they have missed.
|
||||
Remark: self.games[room_jid_s]['players'] should not be modified outside this method.
|
||||
@param room_jid_s: room userhost
|
||||
@param nicks: list of players nicks in the room (referee included, in first position)
|
||||
@param sync: set to True to send synchronization data to the new players
|
||||
@param profile
|
||||
"""
|
||||
if nicks == []:
|
||||
return
|
||||
|
|
@ -203,12 +211,12 @@ class RoomGame(object):
|
|||
new_nicks = [nick for nick in nicks if nick not in self.games[room_jid_s]['players']]
|
||||
if len(new_nicks) == 0:
|
||||
return
|
||||
sync = self._gameExists(room_jid_s, True) and len(self.games[room_jid_s]['players']) > 0
|
||||
|
||||
def setStatus(status):
|
||||
for nick in new_nicks:
|
||||
self.games[room_jid_s]['status'][nick] = status
|
||||
|
||||
sync = sync and self._gameExists(room_jid_s, True) and len(self.games[room_jid_s]['players']) > 0
|
||||
setStatus('desync' if sync else 'init')
|
||||
self.games[room_jid_s]['players'].extend(new_nicks)
|
||||
self._synchronizeRoom(room_jid_s, [JID(room_jid_s)], profile)
|
||||
|
|
@ -231,7 +239,7 @@ class RoomGame(object):
|
|||
elements = [(element, None, None)]
|
||||
|
||||
sync_args = []
|
||||
sync_data = self.getSyncData(room_jid_s)
|
||||
sync_data = self._getSyncData(room_jid_s)
|
||||
for nick in sync_data:
|
||||
user_jid = JID(room_jid_s + '/' + nick)
|
||||
if user_jid in recipients:
|
||||
|
|
@ -248,16 +256,35 @@ class RoomGame(object):
|
|||
for args, kwargs in sync_args:
|
||||
self._sendElements(*args, **kwargs)
|
||||
|
||||
def getSyncData(self, room_jid_s, force_nicks=[]):
|
||||
"""This method may (and should probably) be overwritten by a child class.
|
||||
The synchronization data are returned for each player who has the state
|
||||
'desync' or if he's been contained by force_nicks.
|
||||
def _getSyncData(self, room_jid_s, force_nicks=[]):
|
||||
"""The synchronization data are returned for each player who
|
||||
has the state 'desync' or if he's been contained by force_nicks.
|
||||
@param room_jid_s: room userhost
|
||||
@param force_nicks: force the synchronization for this list of the nicks
|
||||
@return: a mapping between player nicks and a list of child elements
|
||||
to be sent by self._synchronizeRoom for the game to be synchronized.
|
||||
@return: a mapping between player nicks and a list of elements to
|
||||
be sent by self._synchronizeRoom for the game to be synchronized.
|
||||
"""
|
||||
return {}
|
||||
if not self._gameExists(room_jid_s):
|
||||
return {}
|
||||
data = {}
|
||||
status = self.games[room_jid_s]['status']
|
||||
nicks = [nick for nick in status if status[nick] == 'desync']
|
||||
for nick in force_nicks:
|
||||
if nick not in nicks:
|
||||
nicks.append(nick)
|
||||
for nick in nicks:
|
||||
elements = self.getSyncDataForPlayer(room_jid_s, nick)
|
||||
if elements:
|
||||
data[nick] = elements
|
||||
return data
|
||||
|
||||
def getSyncDataForPlayer(self, room_jid_s, nick):
|
||||
"""This method may (and should probably) be overwritten by a child class.
|
||||
@param room_jid_s: room userhost
|
||||
@param nick: the nick of the player to be synchronized
|
||||
@return: a list of elements to synchronize this player with the game.
|
||||
"""
|
||||
return []
|
||||
|
||||
def _invitePlayers(self, room, other_players, nick, profile):
|
||||
"""Invite players to a room, associated game may exist or not.
|
||||
|
|
@ -424,7 +451,7 @@ class RoomGame(object):
|
|||
self.createGame(room_jid_s, nicks, profile_key=profile)
|
||||
return True
|
||||
# let the room know that a new player joined
|
||||
self._updatePlayers(room_jid_s, [user.nick], profile)
|
||||
self._updatePlayers(room_jid_s, [user.nick], True, profile)
|
||||
return True
|
||||
|
||||
def userLeftTrigger(self, room, user, profile):
|
||||
|
|
@ -442,6 +469,9 @@ class RoomGame(object):
|
|||
self.games[room_jid_s]['players'].remove(user.nick)
|
||||
except ValueError:
|
||||
pass
|
||||
if len(self.games[room_jid_s]['players']) == 0:
|
||||
del self.games[room_jid_s] # finish the game
|
||||
return True
|
||||
if self.wait_mode == self.FOR_ALL:
|
||||
# allow this user to join the game again
|
||||
user_jid_s = user.entity.userhost()
|
||||
|
|
@ -493,11 +523,10 @@ class RoomGame(object):
|
|||
(create, sync) = self._checkCreateGameAndInit(room_jid_s, profile)
|
||||
if not create:
|
||||
if sync:
|
||||
debug(_('Synchronize game %s in %s for %s') % (self.name, room_jid_s, ', '.join(nicks)))
|
||||
self._updatePlayers(room_jid_s, nicks, profile)
|
||||
self._updatePlayers(room_jid_s, nicks, True, profile)
|
||||
return
|
||||
self.games[room_jid_s]['started'] = True
|
||||
self._updatePlayers(room_jid_s, nicks, profile)
|
||||
self._updatePlayers(room_jid_s, nicks, False, profile)
|
||||
if self.player_init:
|
||||
# specific data to each player (score, private data)
|
||||
self.games[room_jid_s].setdefault('players_data', {})
|
||||
|
|
|
|||
|
|
@ -631,5 +631,5 @@ class Tarot(object):
|
|||
else:
|
||||
error(_('Unmanaged card game element: %s') % elt.name)
|
||||
|
||||
def getSyncData(self, room_jid_s):
|
||||
return {}
|
||||
def getSyncDataForPlayer(self, room_jid_s, nick):
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -129,32 +129,32 @@ class RoomGameTest(helpers.SatTestCase):
|
|||
self.init()
|
||||
self.initGame(0, 0)
|
||||
self.assertEqual(self.plugin.games[ROOM_JID_S]['players'], [])
|
||||
self.plugin._updatePlayers(ROOM_JID_S, [], Const.PROFILE[0])
|
||||
self.plugin._updatePlayers(ROOM_JID_S, [], True, Const.PROFILE[0])
|
||||
self.assertEqual(self.plugin.games[ROOM_JID_S]['players'], [])
|
||||
self.plugin._updatePlayers(ROOM_JID_S, ["user1"], Const.PROFILE[0])
|
||||
self.plugin._updatePlayers(ROOM_JID_S, ["user1"], True, Const.PROFILE[0])
|
||||
self.assertEqual(self.plugin.games[ROOM_JID_S]['players'], ["user1"])
|
||||
self.plugin._updatePlayers(ROOM_JID_S, ["user2", "user3"], Const.PROFILE[0])
|
||||
self.plugin._updatePlayers(ROOM_JID_S, ["user2", "user3"], True, Const.PROFILE[0])
|
||||
self.assertEqual(self.plugin.games[ROOM_JID_S]['players'], ["user1", "user2", "user3"])
|
||||
self.plugin._updatePlayers(ROOM_JID_S, ["user2", "user3"], Const.PROFILE[0]) # should not be stored twice
|
||||
self.plugin._updatePlayers(ROOM_JID_S, ["user2", "user3"], True, Const.PROFILE[0]) # should not be stored twice
|
||||
self.assertEqual(self.plugin.games[ROOM_JID_S]['players'], ["user1", "user2", "user3"])
|
||||
|
||||
def test_signalPlayers(self):
|
||||
def test_synchronizeRoom(self):
|
||||
self.init()
|
||||
self.initGame(0, 0)
|
||||
self.plugin._signalPlayers(ROOM_JID_S, [Const.MUC[0]], Const.PROFILE[0])
|
||||
self.plugin._synchronizeRoom(ROOM_JID_S, [Const.MUC[0]], Const.PROFILE[0])
|
||||
self.assertEqual(self.host.getSentMessage(0, 0), self.expectedMessage(ROOM_JID_S, "groupchat", "players", []))
|
||||
self.plugin.games[ROOM_JID_S]['players'].append("test1")
|
||||
self.plugin._signalPlayers(ROOM_JID_S, [Const.MUC[0]], Const.PROFILE[0])
|
||||
self.plugin._synchronizeRoom(ROOM_JID_S, [Const.MUC[0]], Const.PROFILE[0])
|
||||
self.assertEqual(self.host.getSentMessage(1, 0), self.expectedMessage(ROOM_JID_S, "groupchat", "players", ["test1"]))
|
||||
self.plugin.games[ROOM_JID_S]['started'] = True
|
||||
self.plugin.games[ROOM_JID_S]['players'].append("test2")
|
||||
self.plugin._signalPlayers(ROOM_JID_S, [Const.MUC[0]], Const.PROFILE[0])
|
||||
self.plugin._synchronizeRoom(ROOM_JID_S, [Const.MUC[0]], Const.PROFILE[0])
|
||||
self.assertEqual(self.host.getSentMessage(2, 0), self.expectedMessage(ROOM_JID_S, "groupchat", "started", ["test1", "test2"]))
|
||||
self.plugin.games[ROOM_JID_S]['players'].append("test3")
|
||||
self.plugin.games[ROOM_JID_S]['players'].append("test4")
|
||||
user1 = JID(ROOM_JID_S + "/" + Const.JID[0].user)
|
||||
user2 = JID(ROOM_JID_S + "/" + Const.JID[1].user)
|
||||
self.plugin._signalPlayers(ROOM_JID_S, [user1, user2], Const.PROFILE[0])
|
||||
self.plugin._synchronizeRoom(ROOM_JID_S, [user1, user2], Const.PROFILE[0])
|
||||
self.assertEqualXML(self.host.getSentMessage(3, 0), self.expectedMessage(user1.full(), "normal", "started", ["test1", "test2", "test3", "test4"]))
|
||||
self.assertEqualXML(self.host.getSentMessage(4, 0), self.expectedMessage(user2.full(), "normal", "started", ["test1", "test2", "test3", "test4"]))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue