Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions buildPy2exe.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,8 +783,8 @@ def run(self):
'py2exe': {
'dist_dir': OUT_DIR,
'packages': 'PySide2',
'includes': 'twisted, sys, encodings, datetime, os, time, math, liburl, ast, unicodedata, _ssl',
'excludes': 'venv, doctest, pdb, unittest, win32clipboard, win32file, win32pdh, win32security, win32trace, win32ui, winxpgui, win32pipe, win32process, Tkinter',
'includes': 'twisted, sys, encodings, datetime, os, time, math, liburl, ast, unicodedata, _ssl, win32pipe, win32file',
'excludes': 'venv, doctest, pdb, unittest, win32clipboard, win32pdh, win32security, win32trace, win32ui, winxpgui, win32process, Tkinter',
'dll_excludes': 'msvcr71.dll, MSVCP90.dll, POWRPROF.dll',
'optimize': 2,
'compressed': 1
Expand Down
6 changes: 3 additions & 3 deletions syncplay/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
version = '1.6.2'
revision = ''
version = '1.6.3'
revision = ' beta'
milestone = 'Yoitsu'
release_number = '71'
release_number = '72'
projectURL = 'https://syncplay.pl/'
70 changes: 38 additions & 32 deletions syncplay/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
from copy import deepcopy
from functools import wraps

from twisted.internet.endpoints import HostnameEndpoint
from twisted.internet.protocol import ClientFactory
from twisted.internet import reactor, task, defer, threads
from twisted.application.internet import ClientService

from syncplay import utils, constants, version
from syncplay.constants import PRIVACY_SENDHASHED_MODE, PRIVACY_DONTSEND_MODE, \
Expand All @@ -27,41 +29,14 @@ def __init__(self, client, retry=constants.RECONNECT_RETRIES):
self._client = client
self.retry = retry
self._timesTried = 0
self.reconnecting = False

def buildProtocol(self, addr):
self._timesTried = 0
return SyncClientProtocol(self._client)

def startedConnecting(self, connector):
destination = connector.getDestination()
message = getMessage("connection-attempt-notification").format(destination.host, destination.port)
self._client.ui.showMessage(message)

def clientConnectionLost(self, connector, reason):
if self._timesTried == 0:
self._client.onDisconnect()
if self._timesTried < self.retry:
self._timesTried += 1
self._client.ui.showMessage(getMessage("reconnection-attempt-notification"))
self.reconnecting = True
reactor.callLater(0.1 * (2 ** min(self._timesTried, 5)), connector.connect)
else:
message = getMessage("disconnection-notification")
self._client.ui.showErrorMessage(message)

def clientConnectionFailed(self, connector, reason):
if not self.reconnecting:
reactor.callLater(0.1, self._client.ui.showErrorMessage, getMessage("connection-failed-notification"), True)
reactor.callLater(0.1, self._client.stop, True)
else:
self.clientConnectionLost(connector, reason)

def resetRetrying(self):
self._timesTried = 0

def stopRetrying(self):
self._timesTried = self.retry
self._client._reconnectingService.stopService()
self._client.ui.showErrorMessage(getMessage("disconnection-notification"))


class SyncplayClient(object):
Expand Down Expand Up @@ -725,16 +700,47 @@ def start(self, host, port):
reactor.callLater(0.1, self._playerClass.run, self, self._config['playerPath'], self._config['file'], self._config['playerArgs'], )
self._playerClass = None
self.protocolFactory = SyncClientFactory(self)
if '[' in host:
host = host.strip('[]')
port = int(port)
reactor.connectTCP(host, port, self.protocolFactory)
self._endpoint = HostnameEndpoint(reactor, host, port)

def retry(retries):
self._lastGlobalUpdate = None
if retries == 0:
self.onDisconnect()
if retries > constants.RECONNECT_RETRIES:
reactor.callLater(0.1, self.ui.showErrorMessage, getMessage("connection-failed-notification"),
True)
reactor.callLater(0.1, self.stop, True)
return None

self.ui.showMessage(getMessage("reconnection-attempt-notification"))
self.reconnecting = True
return(0.1 * (2 ** min(retries, 5)))

self._reconnectingService = ClientService(self._endpoint, self.protocolFactory , retryPolicy=retry)
waitForConnection = self._reconnectingService.whenConnected(failAfterFailures=1)
self._reconnectingService.startService()

def connectedNow(f):
hostIP = connectionHandle.result.transport.addr[0]
self.ui.showMessage(getMessage("handshake-successful-notification").format(host, hostIP))
return

def failed(f):
reactor.callLater(0.1, self.ui.showErrorMessage, getMessage("connection-failed-notification"), True)
reactor.callLater(0.1, self.stop, True)

connectionHandle = waitForConnection.addCallbacks(connectedNow, failed)
message = getMessage("connection-attempt-notification").format(host, port)
self.ui.showMessage(message)
reactor.run()

def stop(self, promptForAction=False):
if not self._running:
return
self._running = False
if self.protocolFactory:
self.protocolFactory.stopRetrying()
self.destroyProtocol()
if self._player:
self._player.drop()
Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_de.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"connection-failed-notification": "Verbindung zum Server fehlgeschlagen",
"connected-successful-notification": "Erfolgreich mit Server verbunden",
"retrying-notification": "%s, versuche erneut in %d Sekunden...", # Seconds
"handshake-successful-notification": "Connection established with {} ({})", # TODO: Translate

"rewind-notification": "Zurückgespult wegen Zeitdifferenz mit {}", # User
"fastforward-notification": "Vorgespult wegen Zeitdifferenz mit {}", # User
Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_en.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"connection-failed-notification": "Connection with server failed",
"connected-successful-notification": "Successfully connected to server",
"retrying-notification": "%s, Retrying in %d seconds...", # Seconds
"handshake-successful-notification": "Connection established with {} ({})",

"rewind-notification": "Rewinded due to time difference with {}", # User
"fastforward-notification": "Fast-forwarded due to time difference with {}", # User
Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_it.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"connection-failed-notification": "Connessione col server fallita",
"connected-successful-notification": "Connessione al server effettuata con successo",
"retrying-notification": "%s, Nuovo tentativo in %d secondi...", # Seconds
"handshake-successful-notification": "Connessione stabilita con {} ({})",

"rewind-notification": "Riavvolgo a causa della differenza temporale con {}", # User
"fastforward-notification": "Avanzamento rapido a causa della differenza temporale con {}", # User
Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_ru.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"connection-failed-notification": "Не удалось подключиться к серверу",
"connected-successful-notification": "Соединение с сервером установлено",
"retrying-notification": "%s, следующая попытка через %d секунд(ы)...", # Seconds
"handshake-successful-notification": "Connection established with {} ({})", # TODO: Translate

"rewind-notification": "Перемотано из-за разницы во времени с {}", # User
"fastforward-notification": "Ускорено из-за разницы во времени с {}", # User
Expand Down
32 changes: 25 additions & 7 deletions syncplay/ui/ConfigurationGetter.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,14 +313,32 @@ def _splitPortAndHost(self, host):
port = constants.DEFAULT_PORT if not self._config["port"] else self._config["port"]
if host:
if ':' in host:
host, port = host.split(':', 1)
try:
port = int(port)
except ValueError:
if host.count(':') == 1:
#IPv4 address or hostname, with port
host, port = host.rsplit(':', 1)
try:
port = port.encode('ascii', 'ignore')
except:
port = ""
port = int(port)
except ValueError:
try:
port = port.encode('ascii', 'ignore')
except:
port = ""
else:
#IPv6 address
if ']' in host:
#IPv6 address in brackets
endBracket = host.index(']')
try:
#port explicitely indicated
port = int(host[endBracket+2:])
except ValueError:
#no port after the bracket
pass
host = host[:endBracket+1]
else:
#IPv6 address with no port and no brackets
#add brackets to correctly store IPv6 addresses in configs
host = '[' + host + ']'
return host, port

def _checkForPortableFile(self):
Expand Down
6 changes: 3 additions & 3 deletions syncplay/ui/GuiConfiguration.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ def addBasicTab(self):
self.error = error
if config['host'] is None:
host = ""
elif ":" in config['host']:
elif ":" in config['host'] and '[' not in config['host']:
host = config['host']
else:
host = config['host'] + ":" + str(config['port'])
Expand All @@ -580,7 +580,7 @@ def addBasicTab(self):
i += 1
self.hostCombobox.setEditable(True)
self.hostCombobox.setEditText(host)
self.hostCombobox.setFixedWidth(165)
self.hostCombobox.setFixedWidth(250)
self.hostLabel = QLabel(getMessage("host-label"), self)
self.findServerButton = QtWidgets.QPushButton(QtGui.QIcon(resourcespath + 'arrow_refresh.png'), getMessage("update-server-list-label"))
self.findServerButton.clicked.connect(self.updateServerList)
Expand Down Expand Up @@ -634,7 +634,7 @@ def addBasicTab(self):
self.executablepathCombobox.setEditable(True)
self.executablepathCombobox.currentIndexChanged.connect(self.updateExecutableIcon)
self.executablepathCombobox.setEditText(self._tryToFillPlayerPath(config['playerPath'], playerpaths))
self.executablepathCombobox.setFixedWidth(250)
self.executablepathCombobox.setFixedWidth(330)
self.executablepathCombobox.editTextChanged.connect(self.updateExecutableIcon)

self.executablepathLabel = QLabel(getMessage("executable-path-label"), self)
Expand Down
23 changes: 19 additions & 4 deletions syncplayServer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
#coding:utf8

import socket
import sys

# libpath
Expand All @@ -12,15 +13,27 @@
import warnings
warnings.warn("You must run Syncplay with Python 3.4 or newer!")

from twisted.internet import reactor
from twisted.internet import reactor, tcp

from syncplay.server import SyncFactory, ConfigurationGetter

class DualStackPort(tcp.Port):

def __init__(self, port, factory, backlog=50, interface='', reactor=None):
tcp.Port.__init__(self, port, factory, backlog, interface, reactor)

def createInternetSocket(self):
s = tcp.Port.createInternetSocket(self)
try:
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
except:
pass
return s

if __name__ == '__main__':
argsGetter = ConfigurationGetter()
args = argsGetter.getConfiguration()
reactor.listenTCP(
int(args.port),
dsp = DualStackPort(int(args.port),
SyncFactory(
args.port,
args.password,
Expand All @@ -31,5 +44,7 @@
args.disable_chat,
args.max_chat_message_length,
args.max_username_length,
args.stats_db_file))
args.stats_db_file),
interface='::')
dsp.startListening()
reactor.run()