Completed "backend" for controlled rooms
This commit is contained in:
parent
ec74daf963
commit
51e2e42293
@ -225,7 +225,7 @@ class SyncplayClient(object):
|
|||||||
|
|
||||||
def _changePlayerStateAccordingToGlobalState(self, position, paused, doSeek, setBy):
|
def _changePlayerStateAccordingToGlobalState(self, position, paused, doSeek, setBy):
|
||||||
madeChangeOnPlayer = False
|
madeChangeOnPlayer = False
|
||||||
pauseChanged = paused != self.getGlobalPaused()
|
pauseChanged = paused != self.getGlobalPaused() or paused != self.getPlayerPaused()
|
||||||
diff = self.getPlayerPosition() - position
|
diff = self.getPlayerPosition() - position
|
||||||
if self._lastGlobalUpdate is None:
|
if self._lastGlobalUpdate is None:
|
||||||
madeChangeOnPlayer = self._initPlayerState(position, paused)
|
madeChangeOnPlayer = self._initPlayerState(position, paused)
|
||||||
|
|||||||
@ -386,7 +386,7 @@ class SyncServerProtocol(JSONCommandProtocol):
|
|||||||
"position": position if position else 0,
|
"position": position if position else 0,
|
||||||
"paused": paused,
|
"paused": paused,
|
||||||
"doSeek": doSeek,
|
"doSeek": doSeek,
|
||||||
"setBy": setBy.getName()
|
"setBy": setBy.getName() if setBy else None
|
||||||
}
|
}
|
||||||
ping = {
|
ping = {
|
||||||
"latencyCalculation": self._pingService.newTimestamp(),
|
"latencyCalculation": self._pingService.newTimestamp(),
|
||||||
|
|||||||
@ -13,10 +13,6 @@ import os
|
|||||||
from string import Template
|
from string import Template
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
# TODO: Check if room should have status of "Controlled room"
|
|
||||||
# TODO: Make only controllers able to control a room
|
|
||||||
# TODO: Send list of controllers
|
|
||||||
# TODO: Broadcast information about controller auth
|
|
||||||
class SyncFactory(Factory):
|
class SyncFactory(Factory):
|
||||||
def __init__(self, password='', motdFilePath=None, isolateRooms=False):
|
def __init__(self, password='', motdFilePath=None, isolateRooms=False):
|
||||||
print getMessage("welcome-server-notification").format(syncplay.version)
|
print getMessage("welcome-server-notification").format(syncplay.version)
|
||||||
@ -73,6 +69,9 @@ class SyncFactory(Factory):
|
|||||||
self.sendJoinMessage(watcher)
|
self.sendJoinMessage(watcher)
|
||||||
else:
|
else:
|
||||||
self.sendRoomSwitchMessage(watcher)
|
self.sendRoomSwitchMessage(watcher)
|
||||||
|
if RoomPasswordProvider.isControlledRoom(roomName):
|
||||||
|
for controller in watcher.getRoom().getControllers():
|
||||||
|
watcher.sendControlledRoomAuthStatus(True, controller)
|
||||||
|
|
||||||
def sendRoomSwitchMessage(self, watcher):
|
def sendRoomSwitchMessage(self, watcher):
|
||||||
l = lambda w: w.sendSetting(watcher.getName(), watcher.getRoom(), None, None)
|
l = lambda w: w.sendSetting(watcher.getName(), watcher.getRoom(), None, None)
|
||||||
@ -97,11 +96,14 @@ class SyncFactory(Factory):
|
|||||||
|
|
||||||
def forcePositionUpdate(self, watcher, doSeek):
|
def forcePositionUpdate(self, watcher, doSeek):
|
||||||
room = watcher.getRoom()
|
room = watcher.getRoom()
|
||||||
paused, position = room.isPaused(), watcher.getPosition()
|
if room.canControl(watcher):
|
||||||
setBy = watcher
|
paused, position = room.isPaused(), watcher.getPosition()
|
||||||
room.setPosition(watcher.getPosition(), setBy)
|
setBy = watcher
|
||||||
l = lambda w: w.sendState(position, paused, doSeek, setBy, True)
|
l = lambda w: w.sendState(position, paused, doSeek, setBy, True)
|
||||||
self._roomManager.broadcastRoom(watcher, l)
|
room.setPosition(watcher.getPosition(), setBy)
|
||||||
|
self._roomManager.broadcastRoom(watcher, l)
|
||||||
|
else:
|
||||||
|
watcher.sendState(room.getPosition(), room.isPaused(), doSeek, room.getSetBy(), True)
|
||||||
|
|
||||||
def getAllWatchersForUser(self, forUser):
|
def getAllWatchersForUser(self, forUser):
|
||||||
return self._roomManager.getAllWatchersForUser(forUser)
|
return self._roomManager.getAllWatchersForUser(forUser)
|
||||||
@ -110,6 +112,8 @@ class SyncFactory(Factory):
|
|||||||
room = watcher.getRoom()
|
room = watcher.getRoom()
|
||||||
try:
|
try:
|
||||||
success = RoomPasswordProvider.check(room.getName(), password, self._salt)
|
success = RoomPasswordProvider.check(room.getName(), password, self._salt)
|
||||||
|
if success:
|
||||||
|
watcher.getRoom().addController(watcher)
|
||||||
self._roomManager.broadcastRoom(watcher, lambda w: w.sendControlledRoomAuthStatus(success, watcher.getName()))
|
self._roomManager.broadcastRoom(watcher, lambda w: w.sendControlledRoomAuthStatus(success, watcher.getName()))
|
||||||
except NotControlledRoom:
|
except NotControlledRoom:
|
||||||
newName = RoomPasswordProvider.getControlledRoomName(room.getName(), password, self._salt)
|
newName = RoomPasswordProvider.getControlledRoomName(room.getName(), password, self._salt)
|
||||||
@ -155,7 +159,10 @@ class RoomManager(object):
|
|||||||
if roomName in self._rooms:
|
if roomName in self._rooms:
|
||||||
return self._rooms[roomName]
|
return self._rooms[roomName]
|
||||||
else:
|
else:
|
||||||
room = Room(roomName)
|
if RoomPasswordProvider.isControlledRoom(roomName):
|
||||||
|
room = ControlledRoom(roomName)
|
||||||
|
else:
|
||||||
|
room = Room(roomName)
|
||||||
self._rooms[roomName] = room
|
self._rooms[roomName] = room
|
||||||
return room
|
return room
|
||||||
|
|
||||||
@ -248,6 +255,44 @@ class Room(object):
|
|||||||
def getSetBy(self):
|
def getSetBy(self):
|
||||||
return self._setBy
|
return self._setBy
|
||||||
|
|
||||||
|
def canControl(self, watcher):
|
||||||
|
return True
|
||||||
|
|
||||||
|
class ControlledRoom(Room):
|
||||||
|
def __init__(self, name):
|
||||||
|
Room.__init__(self, name)
|
||||||
|
self._controllers = {}
|
||||||
|
|
||||||
|
def getPosition(self):
|
||||||
|
if self._controllers:
|
||||||
|
watcher = min(self._controllers.values())
|
||||||
|
self._setBy = watcher
|
||||||
|
return watcher.getPosition()
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def addController(self, watcher):
|
||||||
|
self._controllers[watcher.getName()] = watcher
|
||||||
|
|
||||||
|
def removeWatcher(self, watcher):
|
||||||
|
Room.removeWatcher(self, watcher)
|
||||||
|
if watcher.getName() in self._controllers:
|
||||||
|
del self._controllers[watcher.getName()]
|
||||||
|
|
||||||
|
def setPaused(self, paused=Room.STATE_PAUSED, setBy=None):
|
||||||
|
if self.canControl(setBy):
|
||||||
|
Room.setPaused(self, paused, setBy)
|
||||||
|
|
||||||
|
def setPosition(self, position, setBy=None):
|
||||||
|
if self.canControl(setBy):
|
||||||
|
Room.setPosition(self, position, setBy)
|
||||||
|
|
||||||
|
def canControl(self, watcher):
|
||||||
|
return watcher.getName() in self._controllers
|
||||||
|
|
||||||
|
def getControllers(self):
|
||||||
|
return self._controllers
|
||||||
|
|
||||||
class Watcher(object):
|
class Watcher(object):
|
||||||
def __init__(self, server, connector, name):
|
def __init__(self, server, connector, name):
|
||||||
self._server = server
|
self._server = server
|
||||||
@ -339,14 +384,18 @@ class Watcher(object):
|
|||||||
return False
|
return False
|
||||||
return self._room.isPaused() and not paused or not self._room.isPaused() and paused
|
return self._room.isPaused() and not paused or not self._room.isPaused() and paused
|
||||||
|
|
||||||
|
def _updatePositionByAge(self, messageAge, paused, position):
|
||||||
|
if not paused:
|
||||||
|
position += messageAge
|
||||||
|
return position
|
||||||
|
|
||||||
def updateState(self, position, paused, doSeek, messageAge):
|
def updateState(self, position, paused, doSeek, messageAge):
|
||||||
pauseChanged = self.__hasPauseChanged(paused)
|
pauseChanged = self.__hasPauseChanged(paused)
|
||||||
self._lastUpdatedOn = time.time()
|
self._lastUpdatedOn = time.time()
|
||||||
if pauseChanged:
|
if pauseChanged:
|
||||||
self.getRoom().setPaused(Room.STATE_PAUSED if paused else Room.STATE_PLAYING, self)
|
self.getRoom().setPaused(Room.STATE_PAUSED if paused else Room.STATE_PLAYING, self)
|
||||||
if position is not None:
|
if position is not None:
|
||||||
if not paused:
|
position = self._updatePositionByAge(messageAge, paused, position)
|
||||||
position += messageAge
|
|
||||||
self.setPosition(position)
|
self.setPosition(position)
|
||||||
if doSeek or pauseChanged:
|
if doSeek or pauseChanged:
|
||||||
self._server.forcePositionUpdate(self, doSeek)
|
self._server.forcePositionUpdate(self, doSeek)
|
||||||
@ -368,11 +417,14 @@ class ConfigurationGetter(object):
|
|||||||
self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("server-isolate-room-argument"))
|
self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("server-isolate-room-argument"))
|
||||||
self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("server-motd-argument"))
|
self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("server-motd-argument"))
|
||||||
|
|
||||||
|
|
||||||
class RoomPasswordProvider(object):
|
class RoomPasswordProvider(object):
|
||||||
CONTROLLED_ROOM_REGEX = re.compile("^\+(.*):(\w{12})$")
|
CONTROLLED_ROOM_REGEX = re.compile("^\+(.*):(\w{12})$")
|
||||||
PASSWORD_REGEX = re.compile("[A-Z]{2}-\d{3}-\d{3}")
|
PASSWORD_REGEX = re.compile("[A-Z]{2}-\d{3}-\d{3}")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def isControlledRoom(roomName):
|
||||||
|
return bool(re.match(RoomPasswordProvider.CONTROLLED_ROOM_REGEX, roomName))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check(roomName, password, salt):
|
def check(roomName, password, salt):
|
||||||
if not re.match(RoomPasswordProvider.PASSWORD_REGEX, password):
|
if not re.match(RoomPasswordProvider.PASSWORD_REGEX, password):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user