diff --git a/src/client/_clientwindow.py b/src/client/_clientwindow.py index e219f2554..1750a0ef1 100644 --- a/src/client/_clientwindow.py +++ b/src/client/_clientwindow.py @@ -191,7 +191,7 @@ def __init__(self, *args, **kwargs): fa.instance.finished.connect(self.finishedFA) fa.instance.error.connect(self.errorFA) - # Local Replay Server (and relay) + # Local Replay Server self.replayServer = fa.replayserver.ReplayServer(self) # GameSession @@ -200,17 +200,8 @@ def __init__(self, *args, **kwargs): # ConnectivityTest self.connectivity = None # type: ConnectivityHelper - # Local Relay Server - self.relayServer = fa.relayserver.RelayServer(self) - - # Local proxy servers - self.proxyServer = fa.proxies.proxies(self) self.localIP = None - if not self.proxyServer and not config.no_dialogs: - QtGui.QMessageBox.warning(self.client, "Cannot use proxy server", - "FAF is unable to bind the port 12000 to 12011 on TCP.
Please check your firewall settings.
You may experience connections problems until it's fixed.") - # stat server self.statsServer = secondaryServer.SecondaryServer("Statistic", 11002, self) @@ -598,12 +589,6 @@ def cleanup(self): self.replayServer.close() self.replayServer = None - # Terminate local ReplayServer - if self.relayServer: - self.progress.setLabelText("Terminating local relay server") - self.relayServer.close() - self.relayServer = None - # Clean up Chat if self.chat: self.progress.setLabelText("Disconnecting from IRC") @@ -809,9 +794,6 @@ def doConnect(self): if not self.replayServer.doListen(LOCAL_REPLAY_PORT): return False - if not self.relayServer.doListen(): - return False - # Begin connecting. self.socket.connected.connect(self.on_connected) self.socket.setSocketOption(QtNetwork.QTcpSocket.KeepAliveOption, 1) @@ -1259,7 +1241,7 @@ def handle_game_launch(self, message): arguments.append(str(self.players[self.id]["ladder_rating_deviation"])) # Launch the auto lobby - self.relayServer.init_mode = 1 + self.game_session.init_mode = 1 else: # Player global rating @@ -1272,7 +1254,7 @@ def handle_game_launch(self, message): arguments.append(self.me.country) # Launch the normal lobby - self.relayServer.init_mode = 0 + self.game_session.init_mode = 0 if self.me.clan is not None: arguments.append('/clan') diff --git a/src/fa/__init__.py b/src/fa/__init__.py index 503604980..d0b65dc9d 100644 --- a/src/fa/__init__.py +++ b/src/fa/__init__.py @@ -20,8 +20,6 @@ import check import maps import replayserver -import relayserver -import proxies import updater import upnp import factions diff --git a/src/fa/proxies.py b/src/fa/proxies.py deleted file mode 100644 index fa3e4d4a4..000000000 --- a/src/fa/proxies.py +++ /dev/null @@ -1,235 +0,0 @@ - - - -from PyQt4 import QtCore, QtGui, QtNetwork - -import functools - -import logging - -import config -from config import Settings - -FAF_PROXY_HOST = Settings.get('proxy/host') -FAF_PROXY_PORT = Settings.get('proxy/port') - -UNIT16 = 8 - - -class proxies(QtCore.QObject): - __logger = logging.getLogger(__name__) - - def __init__(self, parent=None): - super(proxies, self).__init__(parent) - - self.client = parent - - self.proxies = {} - self.proxiesDestination = {} - port = 12000 - errored = False - for i in range(11) : - port = port + 1 - self.proxies[i] = QtNetwork.QUdpSocket(self) - if not self.proxies[i].bind(QtNetwork.QHostAddress.LocalHost, port) : - self.__logger.warn("Can't bind socket %i" % i) - errored = True - else : - self.__logger.info("binding socket %i on port %i" % (i, self.proxies[i].localPort())) - self.proxies[i].readyRead.connect(functools.partial(self.processPendingDatagrams, i)) - self.proxiesDestination[i] = None - if errored: - return None - - self.proxySocket = QtNetwork.QTcpSocket(self) - self.proxySocket.connected.connect(self.connectedProxy) - self.proxySocket.readyRead.connect(self.readData) - self.proxySocket.disconnected.connect(self.disconnectedFromProxy) - - self.blockSize = 0 - self.uid = None - self.canClose = False - self.testedPortsAmount = {} - self.testedPorts = [] - self.testedLoopbackAmount = {} - self.testedLoopback = [] - self.testing = False - - def testingProxy(self): - self.testing = True - self.testedPortsAmount = {} - self.testedPorts = [] - self.testedLoopbackAmount = {} - self.testedLoopback = [] - - def stopTesting(self): - self.testing = False - self.testedPortsAmount = {} - self.testedPorts = [] - self.testedLoopbackAmount = {} - self.testedLoopback = [] - - def setUid(self, uid): - self.uid = uid - - def connectedProxy(self): - ''' Setting the socket option correctly''' - # we want the low delay for performance. - self.__logger.debug("Setting low delay on socket.") - self.proxySocket.setSocketOption(QtNetwork.QAbstractSocket.LowDelayOption, 1) - - def connectToProxy(self): - self.proxySocket.connectToHost(FAF_PROXY_HOST, FAF_PROXY_PORT) - if self.proxySocket.waitForConnected(10000): - self.__logger.info("Connected to proxy server " + self.proxySocket.peerName() + ":" + str(self.proxySocket.peerPort())) - - self.canClose = False - self.testedPorts = [] - self.testedLoopback = [] - self.sendUid() - - def bindSocket(self, port, uid): - self.proxiesDestination[port] = uid - self.__logger.debug("Binding socket "+ str(port) +" (local port : "+ str(self.proxies[port].localPort()) +") for uid "+ str(uid)) - if not self.proxySocket.state() == QtNetwork.QAbstractSocket.ConnectedState : - self.connectToProxy() - return self.proxies[port].localPort() - - def releaseSocket(self, port): - self.proxiesDestination[port] = None - - def tranfertToUdp(self, port, packet): - if self.testing: - if not port in self.testedLoopbackAmount: - self.testedLoopbackAmount[port] = 0 - if self.testedLoopbackAmount[port] < 10: - self.testedLoopbackAmount[port] = self.testedLoopbackAmount[port] + 1 - else: - if not port in self.testedLoopback: - self.__logger.info("Testing proxy : Received data from proxy on port %i" % self.proxies[port].localPort()) - self.testedLoopback.append(port) - - if len(self.testedLoopback) == len(self.proxies): - self.__logger.info("Testing proxy : All ports received data correctly") - self.client.stopTesting(success=True) - self.testing = False - else: - if not port in self.testedPorts: - self.testedPorts.append(port) - self.__logger.debug("Received data from proxy on port %i, forwarding to FA" % self.proxies[port].localPort()) - - self.proxies[port].writeDatagram(packet, QtNetwork.QHostAddress.LocalHost, self.client.gamePort) - - def readData(self): - if self.proxySocket.isValid() : - if self.proxySocket.bytesAvailable() == 0 : - return - ins = QtCore.QDataStream(self.proxySocket) - ins.setVersion(QtCore.QDataStream.Qt_4_2) - while ins.atEnd() == False : - if self.proxySocket.isValid() : - if self.blockSize == 0: - if self.proxySocket.isValid() : - if self.proxySocket.bytesAvailable() < 4: - return - - self.blockSize = ins.readUInt32() - else : - return - - if self.proxySocket.isValid() : - if self.proxySocket.bytesAvailable() < self.blockSize: - return - - else : - return - port = ins.readUInt16() - packet = ins.readQVariant() - - self.tranfertToUdp(port, packet) - - self.blockSize = 0 - - else : - return - return - - def sendUid(self, *args, **kwargs) : - if self.uid: - self.__logger.warn("sending our uid (%i) to the server" % self.uid) - reply = QtCore.QByteArray() - stream = QtCore.QDataStream(reply, QtCore.QIODevice.WriteOnly) - stream.setVersion(QtCore.QDataStream.Qt_4_2) - stream.writeUInt32(0) - - stream.writeUInt16(self.uid) - stream.device().seek(0) - - stream.writeUInt32(reply.size() - 4) - - if self.proxySocket.write(reply) == -1 : - self.__logger.warn("error writing to proxy server !") - - def sendReply(self, port, uid, packet, *args, **kwargs) : - reply = QtCore.QByteArray() - stream = QtCore.QDataStream(reply, QtCore.QIODevice.WriteOnly) - stream.setVersion(QtCore.QDataStream.Qt_4_2) - stream.writeUInt32(0) - - stream.writeUInt16(port) - stream.writeUInt16(uid) - stream.writeQVariant(packet) - stream.device().seek(0) - - stream.writeUInt32(reply.size() - 4) - - if self.proxySocket.write(reply) == -1 : - self.__logger.warn("error writing to proxy server !") - - def closeSocket(self): - if self.proxySocket.state() == QtNetwork.QAbstractSocket.ConnectedState : - self.canClose = True - self.__logger.info("disconnecting from proxy server") - self.proxySocket.disconnectFromHost() - for port in self.proxies: - self.releaseSocket(port) - - def processPendingDatagrams(self, i): - udpSocket = self.proxies[i] - while udpSocket.hasPendingDatagrams(): - datagram, _, _ = udpSocket.readDatagram(udpSocket.pendingDatagramSize()) - if self.testing: - if not i in self.testedPortsAmount: - self.testedPortsAmount[i] = 0 - - if self.testedPortsAmount[i] < 10: - self.testedPortsAmount[i] = self.testedPortsAmount[i] + 1 - else: - if not i in self.testedPorts: - self.__logger.info("Testing proxy : Received data from FA on port %i" % self.proxies[i].localPort()) - self.testedPorts.append(i) - - if len(self.testedPorts) == len(self.proxies): - self.__logger.info("Testing proxy : All ports triggered correctly") - self.sendReply(i, 1, QtCore.QByteArray(datagram)) - - else: - if not i in self.testedLoopback: - self.__logger.debug("Received data from FA on port %i" % self.proxies[i].localPort()) - if self.proxiesDestination[i] != None: - if not i in self.testedLoopback: - self.testedLoopback.append(i) - self.__logger.debug("Forwarding packet to proxy.") - self.sendReply(i, self.proxiesDestination[i], QtCore.QByteArray(datagram)) - else: - self.__logger.warn("Unknown destination for forwarding.") - - def disconnectedFromProxy(self): - '''Disconnection''' - self.testedPorts = [] - self.testedLoopback = [] - self.__logger.info("disconnected from proxy server") - if self.canClose == False: - self.__logger.info("reconnecting to proxy server") - self.connectToProxy() - diff --git a/src/fa/relayserver.py b/src/fa/relayserver.py deleted file mode 100644 index 06ed9fdd5..000000000 --- a/src/fa/relayserver.py +++ /dev/null @@ -1,423 +0,0 @@ - -from PyQt4 import QtCore, QtNetwork, QtGui - -import logging -import json -from config import Settings - -import struct - -FAF_SERVER_HOST = Settings.get('relay_server/host') -FAF_SERVER_PORT = Settings.get('relay_server/port') - - -class Packet(): - def __init__(self, header=None , data=None, *values, **kwvalues): - - self._data = data - self._values = kwvalues - self._header = header - - def Pack(self): - - data = "" - - headerSize = len(str(self._header)) - headerField = str(self._header).replace("\t","/t").replace("\n","/n") - chunkSize = len(self._data) - headerPackStr = " 100 : - self.__logger.info("Big error reading FA data !") - self.inputSocket.readAll() - self.fieldSize = 0 - self.blockSize = 0 - self.chunkSize = 0 - self.noSocket = True - return - - for _ in range(len(self.chunks), self.chunkSize): - if self.fieldTypeRead == False : - if self.inputSocket.bytesAvailable() < 1 : - return - - self.fieldType = ins.readBool() - self.fieldTypeRead = True - - if not self.fieldType : - - if self.inputSocket.bytesAvailable() < 4 : - return - number = ins.readInt32() - self.chunks.append(number) - self.fieldTypeRead = False - - else : - if self.fieldSizeRead == False : - if self.inputSocket.bytesAvailable() < 4 : - return - - self.fieldSize = ins.readInt32() - self.fieldSizeRead = True - - if self.inputSocket.bytesAvailable() < self.fieldSize : - return - - datatring = ins.readRawData(self.fieldSize) - fixedStr = datatring.replace("/t","\t").replace("/n","\n") - self.chunks.append(fixedStr) - self.fieldTypeRead = False - self.fieldSizeRead = False - - if not self.testing: - self.handle_incoming_local(self.action, self.chunks) - else: - self.sendToLocal(self.action, self.chunks) - self.action = None - self.chunks = [] - self.headerSizeRead = False - self.headerRead = False - self.chunkSizeRead = False - self.fieldTypeRead = False - self.fieldSizeRead = False - - def handle_incoming_local(self, action, chunks): - if self.action == 'GameState': - if chunks[0] == 'Idle': - args = [self.init_mode, int(self.client.gamePort), - self.client.login, self.client.id, 1] - self.__logger.info("Telling game to create lobby: {}". - format(args)) - reply = Packet("CreateLobby", args) - self.inputSocket.write(reply.Pack()) - self.sendToServer(action, chunks) - - def ping(self): - self.sendToServer("ping", []) - - def sendToLocal(self, action, chunks): - if action == 'GameState': - if chunks[0] == 'Idle': - self.client.proxyServer.setUid(1) - reply = Packet("CreateLobby", [0, 0, "FAF Local Mode", 0, 1]) - self.inputSocket.write(reply.Pack()) - - elif chunks[0] == 'Lobby': - reply = Packet("HostGame", ["SCMP_007"]) - self.inputSocket.write(reply.Pack()) - if self.testing == True: - self.client.proxyServer.testingProxy() - for i in range(len(self.client.proxyServer.proxies)): - udpport = self.client.proxyServer.bindSocket(i, 1) - self.__logger.info("Asking to send data on proxy port %i" % udpport) - acts = [("127.0.0.1:%i" % udpport), "port %i" % udpport, udpport] - reply = Packet("ConnectToPeer", acts) - self.inputSocket.write(reply.Pack()) - else: - self.client.proxyServer.stopTesting() - - - def sendToServer(self, action, chunks): - data = json.dumps(dict(action=action, chunks=chunks)) - # Relay to faforever.com - if self.relaySocket.isOpen(): - if action != "ping" and action != "pong" : - self.__logger.info("Command transmitted from FA to server : " + data) - - block = QtCore.QByteArray() - out = QtCore.QDataStream(block, QtCore.QIODevice.ReadWrite) - out.setVersion(QtCore.QDataStream.Qt_4_2) - out.writeUInt32(0) - out.writeQString(data) - out.device().seek(0) - out.writeUInt32(block.size() - 4) - self.bytesToSend = block.size() - 4 - self.relaySocket.writeData(block) - else : - self.__logger.warn("Error transmitting data to server : " + data) - - def handleAction(self, commands): - key = commands["key"] - acts = commands["commands"] - - if key == "ping" : - self.sendToServer("pong", []) - - elif key == "SendNatPacket" : - reply = Packet(key, acts) - self.inputSocket.write(reply.PackUdp()) - - elif key == "CreateLobby": - uid = int(acts[3]) - self.client.proxyServer.setUid(uid) - self.__logger.info("Setting uid : " + str(uid)) - - elif key == "ConnectToProxy" : - port = acts[0] - login = acts[2] - uid = acts[3] - udpport = self.client.proxyServer.bindSocket(port, uid) - - newActs = [("127.0.0.1:%i" % udpport), login, uid] - - reply = Packet("ConnectToPeer", newActs) - self.inputSocket.write(reply.Pack()) - - elif key == "JoinProxy" : - port = acts[0] - login = acts[2] - uid = acts[3] - udpport = self.client.proxyServer.bindSocket(port, uid) - - newActs = [("127.0.0.1:%i" % udpport), login, uid] - - reply = Packet("JoinGame", newActs) - self.inputSocket.write(reply.Pack()) - - else : - reply = Packet(key, acts) - self.inputSocket.write(reply.Pack()) - - - def done(self): - self.__logger.info("remove relay") - self.parent.removeRelay(self) - - - @QtCore.pyqtSlot() - def inputDisconnected(self): - self.__logger.info("FA disconnected locally.") - self.client.proxyServer.closeSocket() - self.relaySocket.disconnectFromHost() - if self.pingTimer : - self.pingTimer.stop() - self.done() - - - - - -class RelayServer(QtNetwork.QTcpServer): - ''' - This is a local listening server that FA can send its data to. - It will instantiate a fresh ReplayRecorder for each FA instance that launches. - ''' - __logger = logging.getLogger(__name__) - - def __init__(self, client, *args, **kwargs): - QtNetwork.QTcpServer.__init__(self, *args, **kwargs) - self.relayers = [] - self.client = client - self.local = False - self.testing = False - # Use normal lobby by default - self.init_mode = 1 - - self.__logger.debug("initializing...") - self.newConnection.connect(self.acceptConnection) - - def stopTesting(self): - self.local = False - self.testing = False - for relay in self.relayers: - relay.testing = False - - - def testingProxy(self): - ''' this method is to test that everything is fine''' - self.local = True - self.testing = True - for relay in self.relayers: - relay.testing = True - - - def doListen(self): - while not self.isListening(): - self.listen(QtNetwork.QHostAddress.LocalHost, 0) - if (self.isListening()): - self.__logger.info("relay listening on address " + self.serverAddress().toString() + ":" + str(self.serverPort())) - else: - self.__logger.error("cannot listen, port probably used by another application: " + str(self.serverPort())) - answer = QtGui.QMessageBox.warning(None, "Port Occupied", "FAF couldn't start its local relay server, which is needed to play Forged Alliance online. Possible reasons:".format(port=str(self.serverPort())), QtGui.QMessageBox.Retry, QtGui.QMessageBox.Abort) - if answer == QtGui.QMessageBox.Abort: - return False - return True - - def removeRelay(self, relay): - self.relayers.remove(relay) - - - @QtCore.pyqtSlot() - def acceptConnection(self): - socket = self.nextPendingConnection() - self.__logger.debug("incoming connection to relay server...") - self.relayers.append(Relayer(self, self.client, socket, self.testing, init_mode=self.init_mode)) -