diff --git a/syncplay/client.py b/syncplay/client.py index 43f2064..a79e465 100644 --- a/syncplay/client.py +++ b/syncplay/client.py @@ -547,7 +547,11 @@ class SyncplayClient(object): self.userlist.currentUser.room = roomName if resetAutoplay: self.resetAutoPlayState() - + + def sendChat(self,message): + if self._protocol and self._protocol.logged: + self._protocol.sendChatMessage(message) + def sendRoom(self): room = self.userlist.currentUser.room if self._protocol and self._protocol.logged and room: diff --git a/syncplay/constants.py b/syncplay/constants.py index 135ebe4..d5cbb7d 100644 --- a/syncplay/constants.py +++ b/syncplay/constants.py @@ -63,6 +63,7 @@ FILENAME_STRIP_REGEX = u"[-~_\.\[\](): ]" CONTROL_PASSWORD_STRIP_REGEX = u"[^a-zA-Z0-9\-]" ROOM_NAME_STRIP_REGEX = u"^(\+)(?P.*)(:)(\w{12})$" COMMANDS_UNDO = ["u", "undo", "revert"] +COMMANDS_CHAT = ["ch","chat"] COMMANDS_LIST = ["l", "list", "users"] COMMANDS_PAUSE = ["p", "play", "pause"] COMMANDS_ROOM = ["r", "room"] diff --git a/syncplay/messages_de.py b/syncplay/messages_de.py index af15c15..f8f560e 100644 --- a/syncplay/messages_de.py +++ b/syncplay/messages_de.py @@ -85,6 +85,7 @@ de = { "commandlist-notification/toggle" : u"\tt - Bereitschaftsanzeige umschalten", "commandlist-notification/create" : u"\tc [name] - erstelle zentral gesteuerten Raum mit dem aktuellen Raumnamen", "commandlist-notification/auth" : u"\ta [password] - authentifiziere als Raumleiter mit Passwort", + "commandlist-notification/chat" : "\tch [message] - send a chat message in a room", # TODO: Translate "syncplay-version-notification" : u"Syncplay Version: {}", # syncplay.version "more-info-notification" : u"Weitere Informationen auf: {}", # projectURL @@ -374,6 +375,7 @@ de = { "server-salt-argument" : u"zufällige Zeichenkette, die zur Erstellung von Passwörtern verwendet wird", "server-disable-ready-argument" : u"Bereitschaftsfeature deaktivieren", "server-motd-argument": u"Pfad zur Datei, von der die Nachricht des Tages geladen wird", + "server-chat-argument" : "Should chat be enabled?", # TODO: Translate "server-messed-up-motd-unescaped-placeholders": u"Die Nachricht des Tages hat unmaskierte Platzhalter. Alle $-Zeichen sollten verdoppelt werden ($$).", "server-messed-up-motd-too-long": u"Die Nachricht des Tages ist zu lang - Maximal {} Zeichen, aktuell {}.", diff --git a/syncplay/messages_en.py b/syncplay/messages_en.py index e3bd6dc..e31ffb7 100644 --- a/syncplay/messages_en.py +++ b/syncplay/messages_en.py @@ -85,6 +85,7 @@ en = { "commandlist-notification/toggle" : u"\tt - toggles whether you are ready to watch or not", "commandlist-notification/create" : "\tc [name] - create managed room using name of current room", "commandlist-notification/auth" : "\ta [password] - authenticate as room operator with operator password", + "commandlist-notification/chat" : "\tch [message] - send a chat message in a room", "syncplay-version-notification" : "Syncplay version: {}", # syncplay.version "more-info-notification" : "More info available at: {}", # projectURL @@ -375,6 +376,7 @@ en = { "server-salt-argument" : "random string used to generate managed room passwords", "server-disable-ready-argument" : u"disable readiness feature", "server-motd-argument": "path to file from which motd will be fetched", + "server-chat-argument" : "Should chat be enabled?", "server-messed-up-motd-unescaped-placeholders": "Message of the Day has unescaped placeholders. All $ signs should be doubled ($$).", "server-messed-up-motd-too-long": u"Message of the Day is too long - maximum of {} chars, {} given.", diff --git a/syncplay/messages_ru.py b/syncplay/messages_ru.py index 6381543..94804e4 100644 --- a/syncplay/messages_ru.py +++ b/syncplay/messages_ru.py @@ -85,6 +85,7 @@ ru = { "commandlist-notification/toggle" : u"\tt - переключить статус готов/неготов к просмотру", "commandlist-notification/create" : u"\tc [name] - создать управляемую комнату с таким же именем, как у текущей", "commandlist-notification/auth" : u"\ta [password] - авторизоваться как оператор комнаты с помощью пароля", + "commandlist-notification/chat" : "\tch [message] - send a chat message in a room", # TODO: Translate "syncplay-version-notification" : u"Версия Syncplay: {}", # syncplay.version "more-info-notification" : u"Больше информации на {}", # projectURL @@ -374,6 +375,7 @@ ru = { "server-salt-argument" : u"генерировать пароли к управляемым комнатам на основании указанной строки (соли)", "server-disable-ready-argument" : u"отключить статусы готов/не готов", "server-motd-argument" : u"путь к файлу, из которого будет извлекаться MOTD-сообщение", + "server-chat-argument" : "Should chat be enabled?", # TODO: Translate "server-messed-up-motd-unescaped-placeholders" : u"MOTD-сообщение содержит неэкранированные спец.символы. Все знаки $ должны быть продублированы ($$).", "server-messed-up-motd-too-long" : u"MOTD-сообщение слишком длинное: максимальная длина - {} символ(ов), текущая длина - {} символ(ов).", diff --git a/syncplay/protocols.py b/syncplay/protocols.py index 2eeafe8..3c6c17e 100644 --- a/syncplay/protocols.py +++ b/syncplay/protocols.py @@ -22,6 +22,8 @@ class JSONCommandProtocol(LineReceiver): self.handleState(message[1]) elif command == "Error": self.handleError(message[1]) + elif command == "Chat": + self.handleChat(message[1]) else: self.dropWithError(getMessage("unknown-command-server-error").format(message[1])) # TODO: log, not drop @@ -157,7 +159,8 @@ class SyncClientProtocol(JSONCommandProtocol): def sendFileSetting(self, file_): self.sendSet({"file": file_}) self.sendList() - + def sendChatMessage(self,chatMessage): + self.sendMessage({"Chat": chatMessage}) def handleList(self, userList): self._client.userlist.clearList() for room in userList.iteritems(): @@ -242,6 +245,10 @@ class SyncClientProtocol(JSONCommandProtocol): "password": password } }) + def handleChat(self,message): + messageString = '<'+message['username']+'>'+message['message'] + self._client.ui.showMessage(messageString) + #TODO def setReady(self, isReady, manuallyInitiated=True): self.sendSet({ @@ -345,6 +352,9 @@ class SyncServerProtocol(JSONCommandProtocol): self._factory.addWatcher(self, username, roomName) self._logged = True self.sendHello(version) + def handleChat(self,chatMessage): + if self._factory.chat: + self._factory.sendChat(self._watcher,chatMessage) def setWatcher(self, watcher): self._watcher = watcher diff --git a/syncplay/server.py b/syncplay/server.py index c177338..397dd41 100644 --- a/syncplay/server.py +++ b/syncplay/server.py @@ -14,7 +14,7 @@ import argparse from syncplay.utils import RoomPasswordProvider, NotControlledRoom, RandomStringGenerator, meetsMinVersion class SyncFactory(Factory): - def __init__(self, password='', motdFilePath=None, isolateRooms=False, salt=None, disableReady=False): + def __init__(self, password='', motdFilePath=None, isolateRooms=False, salt=None, disableReady=False,chat =False): print getMessage("welcome-server-notification").format(syncplay.version) if password: password = hashlib.md5(password).hexdigest() @@ -25,6 +25,7 @@ class SyncFactory(Factory): self._salt = salt self._motdFilePath = motdFilePath self.disableReady = disableReady + self.chat=chat if not isolateRooms: self._roomManager = RoomManager() else: @@ -133,6 +134,10 @@ class SyncFactory(Factory): except ValueError: self._roomManager.broadcastRoom(watcher, lambda w: w.sendControlledRoomAuthStatus(False, watcher.getName(), room._name)) + def sendChat(self,watcher,message): + messageDict={"message":message,"username" : watcher.getName()} + self._roomManager.broadcastRoom(watcher, lambda w: w.sendChatMessage(messageDict)) + def setReady(self, watcher, isReady, manuallyInitiated=True): watcher.setReady(isReady) self._roomManager.broadcastRoom(watcher, lambda w: w.sendSetReady(watcher.getName(), watcher.isReady(), manuallyInitiated)) @@ -427,6 +432,9 @@ class Watcher(object): def sendControlledRoomAuthStatus(self, success, username, room): self._connector.sendControlledRoomAuthStatus(success, username, room) + def sendChatMessage(self,message): + self._connector.sendMessage({"Chat" : message}) + def sendSetReady(self, username, isReady, manuallyInitiated=True): self._connector.sendSetReady(username, isReady, manuallyInitiated) @@ -507,5 +515,6 @@ class ConfigurationGetter(object): self._argparser.add_argument('--password', metavar='password', type=str, nargs='?', help=getMessage("server-password-argument")) self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("server-isolate-room-argument")) self._argparser.add_argument('--disable-ready', action='store_true', help=getMessage("server-disable-ready-argument")) + self._argparser.add_argument('--chat', action='store_true', help=getMessage("server-chat-argument")) self._argparser.add_argument('--salt', metavar='salt', type=str, nargs='?', help=getMessage("server-salt-argument")) self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("server-motd-argument")) diff --git a/syncplay/ui/consoleUI.py b/syncplay/ui/consoleUI.py index 242482e..7cf6dbe 100644 --- a/syncplay/ui/consoleUI.py +++ b/syncplay/ui/consoleUI.py @@ -143,6 +143,9 @@ class ConsoleUI(threading.Thread): self._syncplayClient.playerPositionBeforeLastSeek = tmp_pos elif command.group('command') in constants.COMMANDS_LIST: self._syncplayClient.getUserList() + elif command.group('command') in constants.COMMANDS_CHAT: + message= command.group('parameter') + self._syncplayClient.sendChat(message) elif command.group('command') in constants.COMMANDS_PAUSE: self._syncplayClient.setPaused(not self._syncplayClient.getPlayerPaused()) elif command.group('command') in constants.COMMANDS_ROOM: @@ -181,6 +184,7 @@ class ConsoleUI(threading.Thread): self.showMessage(getMessage("commandlist-notification/toggle"), True) self.showMessage(getMessage("commandlist-notification/create"), True) self.showMessage(getMessage("commandlist-notification/auth"), True) + self.showMessage(getMessage("commandlist-notification/chat"), True) self.showMessage(getMessage("syncplay-version-notification").format(syncplay.version), True) self.showMessage(getMessage("more-info-notification").format(syncplay.projectURL), True) diff --git a/syncplayServer.py b/syncplayServer.py index b4456d7..aa13653 100755 --- a/syncplayServer.py +++ b/syncplayServer.py @@ -19,6 +19,5 @@ from syncplay.server import SyncFactory, ConfigurationGetter if __name__ == '__main__': argsGetter = ConfigurationGetter() args = argsGetter.getConfiguration() - - reactor.listenTCP(int(args.port), SyncFactory(args.password, args.motd_file, args.isolate_rooms, args.salt, args.disable_ready)) + reactor.listenTCP(int(args.port), SyncFactory(args.password, args.motd_file, args.isolate_rooms, args.salt, args.disable_ready,args.chat)) reactor.run()