mirror of https://github.com/Syncplay/syncplay
commit
bbc5ae0b7f
|
@ -783,8 +783,8 @@ info = dict(
|
|||
'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
|
||||
|
|
|
@ -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/'
|
||||
|
|
|
@ -11,8 +11,10 @@ import time
|
|||
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, \
|
||||
|
@ -27,41 +29,14 @@ class SyncClientFactory(ClientFactory):
|
|||
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):
|
||||
|
@ -725,16 +700,47 @@ class SyncplayClient(object):
|
|||
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()
|
||||
|
|
|
@ -16,6 +16,7 @@ de = {
|
|||
"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
|
||||
|
|
|
@ -16,6 +16,7 @@ en = {
|
|||
"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
|
||||
|
|
|
@ -16,6 +16,7 @@ it = {
|
|||
"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
|
||||
|
|
|
@ -16,6 +16,7 @@ ru = {
|
|||
"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
|
||||
|
|
|
@ -313,14 +313,32 @@ class ConfigurationGetter(object):
|
|||
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):
|
||||
|
|
|
@ -556,7 +556,7 @@ class ConfigDialog(QtWidgets.QDialog):
|
|||
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'])
|
||||
|
@ -580,7 +580,7 @@ class ConfigDialog(QtWidgets.QDialog):
|
|||
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)
|
||||
|
@ -634,7 +634,7 @@ class ConfigDialog(QtWidgets.QDialog):
|
|||
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)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding:utf8
|
||||
|
||||
import socket
|
||||
import sys
|
||||
|
||||
# libpath
|
||||
|
@ -12,15 +13,27 @@ except AttributeError:
|
|||
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,
|
||||
|
@ -31,5 +44,7 @@ if __name__ == '__main__':
|
|||
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()
|
||||
|
|
Loading…
Reference in New Issue