Exemplo n.º 1
0
 def loadSettings(self):
     self.popup = Settings.get(self._settings_key + '/popup',
                               True,
                               type=bool)
     self.sound = Settings.get(self._settings_key + '/sound',
                               True,
                               type=bool)
Exemplo n.º 2
0
def setActiveMods(mods,
                  keepuimods=True,
                  temporary=True):  # uimods works the same as in getActiveMods
    """
    keepuimods:
        None: Replace all active mods with 'mods'
        True: Keep the UI mods already activated activated
        False: Keep only the non-UI mods that were activated activated
        So set it True if you want to set gameplay mods, and False if you want to set UI mods.
    temporary:
        Set this when mods are activated due to joining a game.
    """
    if keepuimods is not None:
        keepTheseMods = getActiveMods(
            keepuimods
        )  # returns the active UI mods if True, the active non-ui mods if False
    else:
        keepTheseMods = []
    allmods = keepTheseMods + mods
    logger.debug('setting active Mods: {}'.format([mod.uid
                                                   for mod in allmods]))
    s = "active_mods = {\n"
    for mod in allmods:
        s += "['%s'] = true,\n" % str(mod.uid)
    s += "}"

    if not temporary:
        global selectedMods
        logger.debug('selectedMods was: {}'.format(Settings.get('play/mods')))
        selectedMods = [str(mod.uid) for mod in allmods]
        logger.debug('Writing selectedMods: {}'.format(selectedMods))
        Settings.set('play/mods', selectedMods)
        logger.debug('selectedMods written: {}'.format(
            Settings.get('play/mods')))

    try:
        f = open(PREFSFILENAME, 'r')
        data = f.read()
    except:
        logger.info("Couldn't read the game.prefs file")
        return False
    else:
        f.close()

    if re.search("active_mods\s*=\s*{.*?}", data, re.S):
        data = re.sub("active_mods\s*=\s*{.*?}", s, data, 1, re.S)
    else:
        data += "\n" + s

    try:
        f = open(PREFSFILENAME, 'w')
        f.write(data)
    except:
        logger.info("Cound't write to the game.prefs file")
        return False
    else:
        f.close()

    return True
Exemplo n.º 3
0
    def update(self, message, client):
        """
        Updates this item from the message dictionary supplied
        """

        self.client = client
        self.tutorial = message['tutorial']
        self.description = message['description']
        self.url = "{}/faf/tutorials/{}".format(Settings.get('content/host'),
                                                message['url'])

        # Map preview code
        if self.mapname != message['mapname']:
            self.mapname = message['mapname']
            self.mapdisplayname = maps.getDisplayName(self.mapname)

            icon = maps.preview(self.mapname)
            if not icon:
                icon = util.THEME.icon("games/unknown_map.png")
                self.client.map_downloader.download_preview(
                    self.mapname, self._map_dl_request)

            self.setIcon(icon)

        self.setText(
            self.FORMATTER_TUTORIAL.format(mapdisplayname=self.mapdisplayname,
                                           title=self.tutorial,
                                           description=self.description))
Exemplo n.º 4
0
def build_argument_list(game_info, port, arguments=None):
    """
    Compiles an argument list to run the game with POpen style process invocation methods.
    Extends a potentially pre-existing argument list to allow for injection of special parameters
    """
    import client
    arguments = arguments or []

    if '/init' in arguments:
        raise ValueError("Custom init scripts no longer supported.")

    # Init file
    arguments.append('/init')
    arguments.append('init_{}.lua'.format(game_info.get('featured_mod',
                                                        'faf')))

    arguments.append('/numgames {}'.format(client.instance.me.number_of_games))

    # log file
    if Settings.get("game/logs", False, type=bool):
        arguments.append("/log")
        arguments.append('"' + util.LOG_FILE_GAME + '"')

    # Disable defunct bug reporter
    arguments.append('/nobugreport')

    # live replay
    arguments.append('/savereplay')
    arguments.append('"gpgnet://localhost/' + str(game_info['uid']) + "/" +
                     str(game_info['recorder']) + '.SCFAreplay"')

    # gpg server emulation
    arguments.append('/gpgnet 127.0.0.1:' + str(port))

    return arguments
Exemplo n.º 5
0
def build_argument_list(game_info, port, arguments=None):
    """
    Compiles an argument list to run the game with POpen style process invocation methods.
    Extends a potentially pre-existing argument list to allow for injection of special parameters
    """
    import client
    arguments = arguments or []

    if '/init' in arguments:
        raise ValueError("Custom init scripts no longer supported.")

    # Init file
    arguments.append('/init')
    arguments.append('init_{}.lua'.format(game_info.get('featured_mod', 'faf')))

    arguments.append('/numgames {}'.format(client.instance.me.number_of_games))

    # log file
    if Settings.get("game/logs", False, type=bool):
        arguments.append("/log")
        arguments.append('"' + util.LOG_FILE_GAME + '"')

    # Disable defunct bug reporter
    arguments.append('/nobugreport')

    # live replay
    arguments.append('/savereplay')
    arguments.append('"gpgnet://localhost/' + str(game_info['uid']) + "/" + str(game_info['recorder']) + '.SCFAreplay"')

    # gpg server emulation
    arguments.append('/gpgnet 127.0.0.1:' + str(port))

    return arguments
Exemplo n.º 6
0
    def on_join(self, c, e):
        channel = e.target()

        # If we're joining, we need to open the channel for us first.
        if channel not in self.channels:
            newch = Channel(self, channel, self._chatters, self._me)
            if channel.lower() in self.crucialChannels:
                self.add_channel(
                    channel, newch,
                    1)  # CAVEAT: This is assumes a server tab exists.
                self.client.localBroadcast.connect(newch.print_raw)
                newch.print_announcement("Welcome to Forged Alliance Forever!",
                                         "red", "+3")
                wiki_link = Settings.get("WIKI_URL")
                wiki_msg = "Check out the wiki: {} for help with common issues.".format(
                    wiki_link)
                newch.print_announcement(wiki_msg, "white", "+1")
                newch.print_announcement("", "black", "+1")
                newch.print_announcement("", "black", "+1")
            else:
                self.add_channel(channel, newch)

            if channel.lower(
            ) in self.crucialChannels:  # Make the crucial channels not closeable, and make the last one the active one
                self.setCurrentWidget(self.channels[channel])
                self.tabBar().setTabButton(self.currentIndex(),
                                           QtWidgets.QTabBar.RightSide, None)

        name, _id, elevation, hostname = parse_irc_source(e.source())
        self._add_chatter(name, hostname)
        self._add_chatter_channel(self._chatters[name], elevation, channel,
                                  True)
Exemplo n.º 7
0
    def loadSettings(self):
        self.mode = Settings.get(self._settings_key+'/mode', 'friends')

        if self.mode == 'friends':
            self.radioButtonFriends.setChecked(True)
        else:
            self.radioButtonAll.setChecked(True)
        self.parent.mode = self.mode
Exemplo n.º 8
0
    def loadSettings(self):
        self.mode = Settings.get(self._settings_key + '/mode', 'friends')

        if self.mode == 'friends':
            self.radioButtonFriends.setChecked(True)
        else:
            self.radioButtonAll.setChecked(True)
        self.parent.mode = self.mode
Exemplo n.º 9
0
    def loadSettings(self):
        self.enabled = Settings.get('notifications/enabled', True, type=bool)
        self.popup_lifetime = Settings.get('notifications/popup_lifetime',
                                           5,
                                           type=int)
        self.popup_position = NotificationPosition(
            Settings.get('notifications/popup_position',
                         NotificationPosition.BOTTOM_RIGHT.value,
                         type=int))
        self.ingame_notifications = IngameNotification(
            Settings.get('notifications/ingame',
                         IngameNotification.ENABLE,
                         type=int))

        self.nsEnabled.setChecked(self.enabled)
        self.nsPopLifetime.setValue(self.popup_lifetime)
        self.nsPositionComboBox.setCurrentIndex(self.popup_position.value)
        self.nsIngameComboBox.setCurrentIndex(self.ingame_notifications.value)
Exemplo n.º 10
0
def AdminUserErrorDialog():
    from config import Settings
    ignore_admin = Settings.get("client/ignore_admin", False, bool)
    if not ignore_admin:
        box = QtWidgets.QMessageBox()
        box.setText(
            "FAF should not be run as an administrator!<br><br>This probably means you need "
            "to fix the file permissions in C:\\ProgramData.<br>Proceed at your own risk."
        )
        box.setStandardButtons(QtWidgets.QMessageBox.Ignore
                               | QtWidgets.QMessageBox.Close)
        box.setIcon(QtWidgets.QMessageBox.Critical)
        box.setWindowTitle("FAF privilege error")
        if box.exec_() == QtWidgets.QMessageBox.Ignore:
            Settings.set("client/ignore_admin", True)
Exemplo n.º 11
0
    def reloadView(self):
        if self.loaded:
            return
        self.loaded = True

        self.ui.setVisible(False)

#       If a local theme CSS exists, skin the WebView with it
        if util.THEME.themeurl("vault/style.css"):
            injectWebviewCSS(self.ui.page(),
                             util.THEME.readstylesheet("vault/style.css"))

        ROOT = Settings.get('content/host')

        url = QtCore.QUrl(ROOT)
        url.setPath("/faf/vault/maps_qt5.php")
        query = QtCore.QUrlQuery(url.query())
        query.addQueryItem('username', self.client.login)
        query.addQueryItem('pwdhash', self.client.password)
        url.setQuery(query)

        self.ui.setUrl(url)
Exemplo n.º 12
0
    def busy_entered(self):
        # Don't display things when we're not logged in
        # FIXME - one day we'll have more obvious points of entry
        if self.client.state != client.ClientState.LOGGED_IN:
            return

        if self.selected_player is None:
            self.selected_player = self.client.players[self.client.login]
        if self.selected_player.league is not None:
            self.leagues.setCurrentIndex(self.selected_player.league - 1)
        else:
            self.leagues.setCurrentIndex(5)  # -> 5 = direct to Ladder Ratings

        if self.selected_player_loaded:
            return

        self.webview.setVisible(False)
        self.webview.setUrl(
            QtCore.QUrl(
                "{}/faf/leaderboards/read-leader.php?board=1v1&username={}".
                format(Settings.get('content/host'),
                       self.selected_player.login)))
        self.selected_player_loaded = True
Exemplo n.º 13
0
class Updater(QtCore.QObject):
    """
    This is the class that does the actual installation work.
    """
    # Network configuration
    SOCKET = 9001
    HOST = Settings.get('lobby/host')
    TIMEOUT = 20  #seconds

    # Return codes to expect from run()
    RESULT_SUCCESS = 0  #Update successful
    RESULT_NONE = -1  #Update operation is still ongoing
    RESULT_FAILURE = 1  #An error occured during updating
    RESULT_CANCEL = 2  #User cancelled the download process
    RESULT_ILLEGAL = 3  #User has the wrong version of FA
    RESULT_BUSY = 4  #Server is currently busy
    RESULT_PASS = 5  #User refuses to update by canceling the wizard

    def __init__(self,
                 featured_mod,
                 version=None,
                 modversions=None,
                 sim=False,
                 silent=False,
                 *args,
                 **kwargs):
        """
        Constructor
        """
        QtCore.QObject.__init__(self, *args, **kwargs)

        self.filesToUpdate = []

        self.lastData = time.time()

        self.featured_mod = featured_mod
        self.version = version
        self.modversions = modversions

        self.sim = sim
        self.modpath = None

        self.blockSize = 0
        self.updateSocket = QtNetwork.QTcpSocket()
        self.updateSocket.setSocketOption(QtNetwork.QTcpSocket.KeepAliveOption,
                                          1)
        self.updateSocket.setSocketOption(QtNetwork.QTcpSocket.LowDelayOption,
                                          1)

        self.result = self.RESULT_NONE

        self.destination = None

        self.silent = silent
        self.progress = QtGui.QProgressDialog()
        if self.silent:
            self.progress.setCancelButton(None)
        else:
            self.progress.setCancelButtonText("Cancel")
        self.progress.setWindowFlags(QtCore.Qt.CustomizeWindowHint
                                     | QtCore.Qt.WindowTitleHint)
        self.progress.setAutoClose(False)
        self.progress.setAutoReset(False)
        self.progress.setModal(1)
        self.progress.setWindowTitle("Updating %s" %
                                     str(self.featured_mod).upper())

        self.bytesToSend = 0

    def run(self, *args, **kwargs):
        clearLog()
        log("Update started at " + timestamp())
        log("Using appdata: " + util.APPDATA_DIR)

        self.progress.show()
        QtGui.QApplication.processEvents()

        #Actual network code adapted from previous version
        self.progress.setLabelText("Connecting to update server...")
        self.updateSocket.error.connect(self.handleServerError)
        self.updateSocket.readyRead.connect(self.readDataFromServer)
        self.updateSocket.disconnected.connect(self.disconnected)
        self.updateSocket.error.connect(self.errored)

        self.updateSocket.connectToHost(self.HOST, self.SOCKET)

        while not (self.updateSocket.state() == QtNetwork.QAbstractSocket.
                   ConnectedState) and self.progress.isVisible():
            QtGui.QApplication.processEvents()

        if not self.progress.wasCanceled():
            log("Connected to update server at " + timestamp())

            self.doUpdate()

            self.progress.setLabelText("Cleaning up.")
            self.updateSocket.close()
            self.progress.close()
        else:
            log("Cancelled connecting to server.")
            self.result = self.RESULT_CANCEL

        log("Update finished at " + timestamp())
        return self.result

    def fetchFile(self, url, toFile):
        try:
            progress = QtGui.QProgressDialog()
            progress.setCancelButtonText("Cancel")
            progress.setWindowFlags(QtCore.Qt.CustomizeWindowHint
                                    | QtCore.Qt.WindowTitleHint)
            progress.setAutoClose(True)
            progress.setAutoReset(False)

            req = urllib2.Request(url, headers={'User-Agent': "FAF Client"})
            downloadedfile = urllib2.urlopen(req)
            meta = downloadedfile.info()

            #Fix for #241, sometimes the server sends an error and no content-length.
            file_size = int(meta.getheaders("Content-Length")[0])
            progress.setMinimum(0)
            progress.setMaximum(file_size)
            progress.setModal(1)
            progress.setWindowTitle("Downloading Update")
            label = QtGui.QLabel()
            label.setOpenExternalLinks(True)
            progress.setLabel(label)
            progress.setLabelText('Downloading FA file : <a href="' + url +
                                  '">' + url + '</a><br/>File size: ' +
                                  str(int(file_size / 1024 / 1024)) + ' MiB')
            progress.show()

            #Download the file as a series of up to 4 KiB chunks, then uncompress it.

            output = tempfile.NamedTemporaryFile(mode='w+b', delete=False)

            file_size_dl = 0
            block_sz = 4096

            while progress.isVisible():
                QtGui.QApplication.processEvents()
                read_buffer = downloadedfile.read(block_sz)
                if not read_buffer:
                    break
                file_size_dl += len(read_buffer)
                output.write(read_buffer)
                progress.setValue(file_size_dl)

            output.flush()
            os.fsync(output.fileno())
            output.close()

            shutil.move(output.name, toFile)

            if (progress.value() == file_size) or progress.value() == -1:
                logger.debug("File downloaded successfully.")
                return True
            else:
                QtGui.QMessageBox.information(None, "Aborted",
                                              "Download not complete.")
                logger.warn("File download not complete.")
                return False
        except:
            logger.error("Updater error: ", exc_info=sys.exc_info())
            QtGui.QMessageBox.information(
                None, "Download Failed",
                "The file wasn't properly sent by the server. <br/><b>Try again later.</b>"
            )
            return False

    def updateFiles(self, destination, filegroup):
        """
        Updates the files in a given file group, in the destination subdirectory of the Forged Alliance path.
        If existing=True, the existing contents of the directory will be added to the current self.filesToUpdate
        list. 
        """
        QtGui.QApplication.processEvents()

        self.progress.setLabelText("Updating files: " + filegroup)
        self.destination = destination

        self.writeToServer("GET_FILES_TO_UPDATE", filegroup)
        self.waitForFileList()

        #Ensure our list is unique
        self.filesToUpdate = list(set(self.filesToUpdate))

        targetdir = os.path.join(util.APPDATA_DIR, destination)
        if not os.path.exists(targetdir):
            os.makedirs(targetdir)

        for fileToUpdate in self.filesToUpdate:
            md5File = util.md5(
                os.path.join(util.APPDATA_DIR, destination, fileToUpdate))
            if md5File == None:
                if self.version:
                    if self.featured_mod == "faf" or self.featured_mod == "ladder1v1" or filegroup == "FAF" or filegroup == "FAFGAMEDATA":
                        self.writeToServer("REQUEST_VERSION", destination,
                                           fileToUpdate, str(self.version))
                    else:
                        self.writeToServer("REQUEST_MOD_VERSION", destination,
                                           fileToUpdate,
                                           json.dumps(self.modversions))
                else:

                    self.writeToServer("REQUEST_PATH", destination,
                                       fileToUpdate)
            else:
                if self.version:
                    if self.featured_mod == "faf" or self.featured_mod == "ladder1v1" or filegroup == "FAF" or filegroup == "FAFGAMEDATA":
                        self.writeToServer("PATCH_TO", destination,
                                           fileToUpdate, md5File,
                                           str(self.version))
                    else:

                        self.writeToServer("MOD_PATCH_TO", destination,
                                           fileToUpdate, md5File,
                                           json.dumps(self.modversions))
                else:
                    self.writeToServer("UPDATE", destination, fileToUpdate,
                                       md5File)

        self.waitUntilFilesAreUpdated()

    def waitForSimModPath(self):
        """
        A simple loop that waits until the server has transmitted a sim mod path.
        """
        self.lastData = time.time()

        self.progress.setValue(0)
        self.progress.setMinimum(0)
        self.progress.setMaximum(0)

        while self.modpath == None:
            if self.progress.wasCanceled():
                raise UpdaterCancellation(
                    "Operation aborted while waiting for sim mod path.")

            if self.result != self.RESULT_NONE:
                raise UpdaterFailure(
                    "Operation failed while waiting for sim mod path.")

            if time.time() - self.lastData > self.TIMEOUT:
                raise UpdaterTimeout(
                    "Operation timed out while waiting for sim mod path.")

            QtGui.QApplication.processEvents()

    def waitForFileList(self):
        """
        A simple loop that waits until the server has transmitted a file list.
        """
        self.lastData = time.time()

        self.progress.setValue(0)
        self.progress.setMinimum(0)
        self.progress.setMaximum(0)

        while len(self.filesToUpdate) == 0:
            if self.progress.wasCanceled():
                raise UpdaterCancellation(
                    "Operation aborted while waiting for file list.")

            if self.result != self.RESULT_NONE:
                raise UpdaterFailure(
                    "Operation failed while waiting for file list.")

            if time.time() - self.lastData > self.TIMEOUT:
                raise UpdaterTimeout(
                    "Operation timed out while waiting for file list.")

            QtGui.QApplication.processEvents()

        log("Files to update: [" + ', '.join(self.filesToUpdate) + "]")

    def waitUntilFilesAreUpdated(self):
        """
        A simple loop that updates the progress bar while the server sends actual file data
        """
        self.lastData = time.time()

        self.progress.setValue(0)
        self.progress.setMinimum(0)
        self.progress.setMaximum(0)

        while len(self.filesToUpdate) > 0:
            if self.progress.wasCanceled():
                raise UpdaterCancellation(
                    "Operation aborted while waiting for data.")

            if (self.result != self.RESULT_NONE):
                raise UpdaterFailure(
                    "Operation failed while waiting for data.")

            if (time.time() - self.lastData > self.TIMEOUT):
                raise UpdaterTimeout(
                    "Connection timed out while waiting for data.")

            QtGui.QApplication.processEvents()

        log("Updates applied successfully.")

    def prepareBinFAF(self):
        '''
        Creates all necessary files in the binFAF folder, which contains a modified copy of all
        that is in the standard bin folder of Forged Alliance
        '''
        self.progress.setLabelText("Preparing binFAF...")

        #now we check if we've got a binFAF folder
        FABindir = os.path.join(config.Settings.get("ForgedAlliance/app/path"),
                                'bin')
        FAFdir = util.BIN_DIR

        #Try to copy without overwriting, but fill in any missing files, otherwise it might miss some files to update
        root_src_dir = FABindir
        root_dst_dir = FAFdir

        for src_dir, _, files in os.walk(root_src_dir):
            dst_dir = src_dir.replace(root_src_dir, root_dst_dir)
            if not os.path.exists(dst_dir):
                os.mkdir(dst_dir)
            for file_ in files:
                src_file = os.path.join(src_dir, file_)
                dst_file = os.path.join(dst_dir, file_)
                if not os.path.exists(dst_file):
                    shutil.copy(src_file, dst_dir)
                st = os.stat(dst_file)
                os.chmod(
                    dst_file, st.st_mode | stat.S_IWRITE
                )  # make all files we were considering writable, because we may need to patch them

    def doUpdate(self):
        """ The core function that does most of the actual update work."""
        try:
            if self.sim:
                self.writeToServer("REQUEST_SIM_PATH", self.featured_mod)
                self.waitForSimModPath()
                if self.result == self.RESULT_SUCCESS:
                    if modvault.downloadMod(self.modpath):
                        self.writeToServer("ADD_DOWNLOAD_SIM_MOD",
                                           self.featured_mod)

            else:
                #Prepare FAF directory & all necessary files
                self.prepareBinFAF()

                #Update the mod if it's requested
                if self.featured_mod == "faf" or self.featured_mod == "ladder1v1":  #HACK - ladder1v1 "is" FAF. :-)
                    self.updateFiles("bin", "FAF")
                    self.updateFiles("gamedata", "FAFGAMEDATA")
                    pass
                elif self.featured_mod:
                    self.updateFiles("bin", "FAF")
                    self.updateFiles("gamedata", "FAFGAMEDATA")
                    self.updateFiles("bin", self.featured_mod)
                    self.updateFiles("gamedata",
                                     self.featured_mod + "Gamedata")

        except UpdaterTimeout, e:
            log("TIMEOUT: {}".format(e))
            self.result = self.RESULT_FAILURE
        except UpdaterCancellation, e:
            log("CANCELLED: {}".format(e))
            self.result = self.RESULT_CANCEL
Exemplo n.º 14
0
 def loadSettings(self):
     self.popup = Settings.get(self._settings_key + '/popup',
                               True, type=bool)
     self.sound = Settings.get(self._settings_key + '/sound',
                               True, type=bool)
Exemplo n.º 15
0
class SecondaryServer(QtCore.QObject):

    # Network configuration
    HOST = "lobby." + Settings.get('host')
    TIMEOUT = 5  # seconds

    # Return codes to expect from run()
    RESULT_SUCCESS = 0  # successful
    RESULT_NONE = -1  # operation is still ongoing
    RESULT_FAILURE = 1  # an error occured
    RESULT_CANCEL = 2  # User cancelled
    RESULT_BUSY = 4  # Server is currently busy
    RESULT_PASS = 5  # User refuses to update by canceling

    def __init__(self, name, socket, dispatcher, *args, **kwargs):
        """
        Constructor
        """
        QtCore.QObject.__init__(self, *args, **kwargs)

        self.name = name

        logger = logging.getLogger("faf.secondaryServer.%s" % self.name)
        logger.info("Instantiating secondary server.")
        self.logger = logger

        self.socketPort = socket
        self.dispatcher = dispatcher

        self.command = None
        self.message = None

        self.blockSize = 0
        self.serverSocket = QtNetwork.QTcpSocket()

        self.serverSocket.error.connect(self.handleServerError)
        self.serverSocket.readyRead.connect(self.readDataFromServer)
        self.serverSocket.connected.connect(self.send_pending)
        self.invisible = False
        self._requests = []

    def setInvisible(self):
        self.invisible = True

    def send(self, command, *args, **kwargs):
        """ actually do the settings  """
        self._requests += [{
            'command': command,
            'args': args,
            'kwargs': kwargs
        }]
        self.logger.info("Pending requests: {}".format(len(self._requests)))
        if not self.serverSocket.state(
        ) == QtNetwork.QAbstractSocket.ConnectedState:
            self.logger.info("Connecting to {} {}:{}".format(
                self.name, self.HOST, self.socketPort))
            self.serverSocket.connectToHost(self.HOST, self.socketPort)
        else:
            self.send_pending()

    def send_pending(self):
        for req in self._requests:
            self.send_request(req['command'], req['args'], req['kwargs'])
        self._requests = []

    def send_request(self, command, *args, **kwargs):
        self.sendJson(command)

    def sendJson(self, message):
        data = json.dumps(message)
        logger.debug("Outgoing JSON Message: " + data)
        self.writeToServer(data)

    @QtCore.pyqtSlot()
    def readDataFromServer(self):
        ins = QtCore.QDataStream(self.serverSocket)
        ins.setVersion(QtCore.QDataStream.Qt_4_2)

        while not ins.atEnd():
            if self.blockSize == 0:
                if self.serverSocket.bytesAvailable() < 4:
                    return
                self.blockSize = ins.readUInt32()
            if self.serverSocket.bytesAvailable() < self.blockSize:
                return

            action = ins.readQString()
            self.process(action, ins)
            self.blockSize = 0

    def writeToServer(self, action, *args, **kw):
        block = QtCore.QByteArray()
        out = QtCore.QDataStream(block, QtCore.QIODevice.ReadWrite)
        out.setVersion(QtCore.QDataStream.Qt_4_2)
        out.writeUInt32(0)
        out.writeQString(action)

        for arg in args:
            if type(arg) is int:
                out.writeInt(arg)
            elif isinstance(arg, str):
                out.writeQString(arg)
            elif type(arg) is float:
                out.writeFloat(arg)
            elif type(arg) is list:
                out.writeQVariantList(arg)
            else:
                out.writeQString(str(arg))

        out.device().seek(0)
        out.writeUInt32(block.size() - 4)

        self.bytesToSend = block.size() - 4
        self.serverSocket.write(block)

    def process(self, action, stream):
        self.receiveJSON(action, stream)

    def receiveJSON(self, data_string, stream):
        """
        A fairly pythonic way to process received strings as JSON messages.
        """
        message = json.loads(data_string)
        logger.debug("answering from server :" + str(message["command"]))
        self.dispatcher.dispatch(message)

    @QtCore.pyqtSlot('QAbstractSocket::SocketError')
    def handleServerError(self, socketError):
        """
        Simple error handler that flags the whole operation as failed, not very graceful but what can you do...
        """
        if socketError == QtNetwork.QAbstractSocket.RemoteHostClosedError:
            log("FA Server down: The server is down for maintenance, please try later."
                )

        elif socketError == QtNetwork.QAbstractSocket.HostNotFoundError:
            log("Connection to Host lost. Please check the host name and port settings."
                )

        elif socketError == QtNetwork.QAbstractSocket.ConnectionRefusedError:
            log("The connection was refused by the peer.")
        else:
            log("The following error occurred: %s." %
                self.serverSocket.errorString())
Exemplo n.º 16
0
 def tech_support(self):
     QtGui.QDesktopServices().openUrl(QtCore.QUrl(Settings.get("HELP_URL")))
Exemplo n.º 17
0
# Initialize logging system
import logging

from PyQt5.QtNetwork import QNetworkAccessManager
from enum import IntEnum

from config import Settings

logger = logging.getLogger(__name__)
# logger.setLevel(logging.DEBUG)

# Initialize all important globals
LOBBY_HOST = Settings.get('lobby/host')
LOBBY_PORT = Settings.get('lobby/port')
LOCAL_REPLAY_PORT = Settings.get('lobby/relay/port')


class ClientState(IntEnum):
    """
    Various states the client can be in.
    """
    SHUTDOWN = -666  # Going... DOWN!

    DISCONNECTED = -2
    CONNECTING = -1
    NONE = 0
    CONNECTED = 1
    LOGGED_IN = 2


from ._clientwindow import ClientWindow
Exemplo n.º 18
0
 def on_new_account(self):
     QtGui.QDesktopServices.openUrl(
         QtCore.QUrl(Settings.get("CREATE_ACCOUNT_URL")))
Exemplo n.º 19
0
from PyQt4 import QtCore, QtNetwork, QtGui

import os
import logging
import util
import fa
import json
import time

from config import Settings

INTERNET_REPLAY_SERVER_HOST = Settings.get('replay_server/host')
INTERNET_REPLAY_SERVER_PORT = Settings.get('replay_server/port')

from . import DEFAULT_LIVE_REPLAY
from . import DEFAULT_RECORD_REPLAY


class ReplayRecorder(QtCore.QObject):
    """
    This is a simple class that takes all the FA replay data input from its inputSocket, writes it to a file,
    and relays it to an internet server via its relaySocket.
    """
    __logger = logging.getLogger(__name__)

    def __init__(self, parent, local_socket, *args, **kwargs):
        QtCore.QObject.__init__(self, *args, **kwargs)
        self.parent = parent
        self.inputSocket = local_socket
        self.inputSocket.setSocketOption(QtNetwork.QTcpSocket.KeepAliveOption,
                                         1)
Exemplo n.º 20
0
 def send_the_orcs():
     route = Settings.get('mordor/host')
     if _id != -1:
         QtGui.QDesktopServices.openUrl(QUrl("{}/users/{}".format(route, _id)))
     else:
         QtGui.QDesktopServices.openUrl(QUrl("{}/users/{}".format(route, name)))
Exemplo n.º 21
0
class Updater(QtCore.QObject, ConnectionHandler):
    """
    This is the class that does the actual installation work.
    """
    # Network configuration
    SOCKET = 9001
    HOST = Settings.get('lobby/host')
    TIMEOUT = 20  # seconds

    # Return codes to expect from run()
    RESULT_SUCCESS = 0  # Update successful
    RESULT_NONE = -1  # Update operation is still ongoing
    RESULT_FAILURE = 1  # An error occured during updating
    RESULT_CANCEL = 2  # User cancelled the download process
    RESULT_ILLEGAL = 3  # User has the wrong version of FA
    RESULT_BUSY = 4  # Server is currently busy
    RESULT_PASS = 5  # User refuses to update by canceling the wizard

    def __init__(self,
                 featured_mod,
                 version=None,
                 modversions=None,
                 sim=False,
                 silent=False,
                 *args,
                 **kwargs):
        """
        Constructor
        """
        QtCore.QObject.__init__(self, *args, **kwargs)

        self.filesToUpdate = []
        self.updatedFiles = []

        self.connection = UpdateConnection(self, self.HOST, self.SOCKET)
        self.lastData = time.time()

        self.featured_mod = featured_mod
        self.version = version
        self.modversions = modversions

        self.sim = sim
        self.modpath = None

        self.result = self.RESULT_NONE

        self.destination = None

        self.silent = silent
        self.progress = QtWidgets.QProgressDialog()
        if self.silent:
            self.progress.setCancelButton(None)
        else:
            self.progress.setCancelButtonText("Cancel")
        self.progress.setWindowFlags(QtCore.Qt.CustomizeWindowHint
                                     | QtCore.Qt.WindowTitleHint)
        self.progress.setAutoClose(False)
        self.progress.setAutoReset(False)
        self.progress.setModal(1)
        self.progress.setWindowTitle("Updating %s" %
                                     str(self.featured_mod).upper())

        self.bytesToSend = 0

    def run(self, *args, **kwargs):
        clearLog()
        log("Update started at " + timestamp())
        log("Using appdata: " + util.APPDATA_DIR)

        self.progress.show()
        QtWidgets.QApplication.processEvents()

        # Actual network code adapted from previous version
        self.progress.setLabelText("Connecting to update server...")

        self.connection.connect()

        while not (self.connection.connected()) and self.progress.isVisible():
            QtWidgets.QApplication.processEvents()

        if not self.progress.wasCanceled():
            log("Connected to update server at " + timestamp())

            self.doUpdate()

            self.progress.setLabelText("Cleaning up.")
            self.connection.disconnect()
            self.progress.close()
        else:
            log("Cancelled connecting to server.")
            self.result = self.RESULT_CANCEL

        log("Update finished at " + timestamp())
        return self.result

    def fetchFile(self, url, toFile):
        try:
            logger.info('Updater: Downloading {}'.format(url))
            progress = QtWidgets.QProgressDialog()
            progress.setCancelButtonText("Cancel")
            progress.setWindowFlags(QtCore.Qt.CustomizeWindowHint
                                    | QtCore.Qt.WindowTitleHint)
            progress.setAutoClose(True)
            progress.setAutoReset(False)

            req = urllib.request.Request(url,
                                         headers={'User-Agent': "FAF Client"})
            downloadedfile = urllib.request.urlopen(req)
            meta = downloadedfile.info()

            # Fix for #241, sometimes the server sends an error and no content-length.
            file_size = int(meta.get_all("Content-Length")[0])
            progress.setMinimum(0)
            progress.setMaximum(file_size)
            progress.setModal(1)
            progress.setWindowTitle("Downloading Update")
            label = QtWidgets.QLabel()
            label.setOpenExternalLinks(True)
            progress.setLabel(label)
            progress.setLabelText('Downloading FA file : <a href="' + url +
                                  '">' + url + '</a><br/>File size: ' +
                                  str(int(file_size / 1024 / 1024)) + ' MiB')
            progress.show()

            # Download the file as a series of up to 4 KiB chunks, then uncompress it.

            output = tempfile.NamedTemporaryFile(mode='w+b', delete=False)

            file_size_dl = 0
            block_sz = 4096

            while progress.isVisible():
                QtWidgets.QApplication.processEvents()
                if not progress.isVisible():
                    break
                read_buffer = downloadedfile.read(block_sz)
                if not read_buffer:
                    break
                file_size_dl += len(read_buffer)
                output.write(read_buffer)
                progress.setValue(file_size_dl)

            output.flush()
            os.fsync(output.fileno())
            output.close()

            shutil.move(output.name, toFile)

            if (progress.value() == file_size) or progress.value() == -1:
                logger.debug("File downloaded successfully.")
                return True
            else:
                QtWidgets.QMessageBox.information(None, "Aborted",
                                                  "Download not complete.")
                logger.warning("File download not complete.")
                return False
        except:
            logger.error("Updater error: ", exc_info=sys.exc_info())
            QtWidgets.QMessageBox.information(
                None, "Download Failed",
                "The file wasn't properly sent by the server. "
                "<br/><b>Try again later.</b>")
            return False

    def updateFiles(self, destination, filegroup):
        """
        Updates the files in a given file group, in the destination subdirectory of the Forged Alliance path.
        If existing=True, the existing contents of the directory will be added to the current self.filesToUpdate
        list. 
        """
        QtWidgets.QApplication.processEvents()

        self.progress.setLabelText("Updating files: " + filegroup)
        self.destination = destination

        self.connection.writeToServer("GET_FILES_TO_UPDATE", filegroup)
        self.waitForFileList()

        # Ensure our list is unique
        self.filesToUpdate = list(set(self.filesToUpdate))

        targetdir = os.path.join(util.APPDATA_DIR, destination)
        if not os.path.exists(targetdir):
            os.makedirs(targetdir)

        for fileToUpdate in self.filesToUpdate:
            md5File = util.md5(
                os.path.join(util.APPDATA_DIR, destination, fileToUpdate))
            if md5File is None:
                if self.version:
                    if self.featured_mod == "faf" or self.featured_mod == "ladder1v1" or \
                                    filegroup == "FAF" or filegroup == "FAFGAMEDATA":
                        self.connection.writeToServer("REQUEST_VERSION",
                                                      destination,
                                                      fileToUpdate,
                                                      str(self.version))
                    else:
                        self.connection.writeToServer(
                            "REQUEST_MOD_VERSION", destination, fileToUpdate,
                            json.dumps(self.modversions))
                else:

                    self.connection.writeToServer("REQUEST_PATH", destination,
                                                  fileToUpdate)
            else:
                if self.version:
                    if self.featured_mod == "faf" or self.featured_mod == "ladder1v1" or \
                                    filegroup == "FAF" or filegroup == "FAFGAMEDATA":
                        self.connection.writeToServer("PATCH_TO", destination,
                                                      fileToUpdate, md5File,
                                                      str(self.version))
                    else:

                        self.connection.writeToServer(
                            "MOD_PATCH_TO", destination, fileToUpdate, md5File,
                            json.dumps(self.modversions))
                else:
                    self.connection.writeToServer("UPDATE", destination,
                                                  fileToUpdate, md5File)

        self.waitUntilFilesAreUpdated()

    def waitForSimModPath(self):
        """
        A simple loop that waits until the server has transmitted a sim mod path.
        """
        self.lastData = time.time()

        self.progress.setValue(0)
        self.progress.setMinimum(0)
        self.progress.setMaximum(0)

        while self.modpath is None:
            if self.progress.wasCanceled():
                raise UpdaterCancellation(
                    "Operation aborted while waiting for sim mod path.")

            if self.result != self.RESULT_NONE:
                raise UpdaterFailure(
                    "Operation failed while waiting for sim mod path.")

            if time.time() - self.lastData > self.TIMEOUT:
                raise UpdaterTimeout(
                    "Operation timed out while waiting for sim mod path.")

            QtWidgets.QApplication.processEvents()

    def waitForFileList(self):
        """
        A simple loop that waits until the server has transmitted a file list.
        """
        self.lastData = time.time()

        self.progress.setValue(0)
        self.progress.setMinimum(0)
        self.progress.setMaximum(0)

        while len(self.filesToUpdate) == 0:
            if self.progress.wasCanceled():
                raise UpdaterCancellation(
                    "Operation aborted while waiting for file list.")

            if self.result != self.RESULT_NONE:
                raise UpdaterFailure(
                    "Operation failed while waiting for file list.")

            if time.time() - self.lastData > self.TIMEOUT:
                raise UpdaterTimeout(
                    "Operation timed out while waiting for file list.")

            QtWidgets.QApplication.processEvents()

        log("Files to update: [" + ', '.join(self.filesToUpdate) + "]")

    def waitUntilFilesAreUpdated(self):
        """
        A simple loop that updates the progress bar while the server sends actual file data
        """
        self.lastData = time.time()

        self.progress.setValue(0)
        self.progress.setMinimum(0)
        self.progress.setMaximum(0)

        while len(self.filesToUpdate) > 0:
            if self.progress.wasCanceled():
                raise UpdaterCancellation(
                    "Operation aborted while waiting for data.")

            if self.result != self.RESULT_NONE:
                raise UpdaterFailure(
                    "Operation failed while waiting for data.")

            if time.time() - self.lastData > self.TIMEOUT:
                raise UpdaterTimeout(
                    "Connection timed out while waiting for data.")

            QtWidgets.QApplication.processEvents()

        log("Updates applied successfully.")

    def prepareBinFAF(self):
        """
        Creates all necessary files in the binFAF folder, which contains a modified copy of all
        that is in the standard bin folder of Forged Alliance
        """
        self.progress.setLabelText("Preparing binFAF...")

        # now we check if we've got a binFAF folder
        FABindir = os.path.join(config.Settings.get("ForgedAlliance/app/path"),
                                'bin')
        FAFdir = util.BIN_DIR

        # Try to copy without overwriting, but fill in any missing files, otherwise it might miss some files to update
        root_src_dir = FABindir
        root_dst_dir = FAFdir

        for src_dir, _, files in os.walk(root_src_dir):
            dst_dir = src_dir.replace(root_src_dir, root_dst_dir)
            if not os.path.exists(dst_dir):
                os.mkdir(dst_dir)
            for file_ in files:
                src_file = os.path.join(src_dir, file_)
                dst_file = os.path.join(dst_dir, file_)
                if not os.path.exists(dst_file):
                    shutil.copy(src_file, dst_dir)
                st = os.stat(dst_file)
                os.chmod(
                    dst_file, st.st_mode | stat.S_IWRITE
                )  # make all files we were considering writable, because we may need to patch them

    def doUpdate(self):
        """ The core function that does most of the actual update work."""
        try:
            if self.sim:
                self.connection.writeToServer("REQUEST_SIM_PATH",
                                              self.featured_mod)
                self.waitForSimModPath()
                if self.result == self.RESULT_SUCCESS:
                    if modvault.downloadMod(self.modpath):
                        self.connection.writeToServer("ADD_DOWNLOAD_SIM_MOD",
                                                      self.featured_mod)

            else:
                # Prepare FAF directory & all necessary files
                self.prepareBinFAF()

                # Update the mod if it's requested
                if self.featured_mod == "faf" or self.featured_mod == "ladder1v1":  # HACK - ladder1v1 "is" FAF. :-)
                    self.updateFiles("bin", "FAF")
                    self.updateFiles("gamedata", "FAFGAMEDATA")
                    pass
                elif self.featured_mod:
                    self.updateFiles("bin", "FAF")
                    self.updateFiles("gamedata", "FAFGAMEDATA")
                    self.updateFiles("bin", self.featured_mod)
                    self.updateFiles("gamedata",
                                     self.featured_mod + "Gamedata")

        except UpdaterTimeout as e:
            log("TIMEOUT: {}".format(e))
            self.result = self.RESULT_FAILURE
        except UpdaterCancellation as e:
            log("CANCELLED: {}".format(e))
            self.result = self.RESULT_CANCEL
        except Exception as e:
            log("EXCEPTION: {}".format(e))
            self.result = self.RESULT_FAILURE
        else:
            self.result = self.RESULT_SUCCESS
        finally:
            self.connection.disconnect()

        # Hide progress dialog if it's still showing.
        self.progress.close()

        # Integrated handlers for the various things that could go wrong
        if self.result == self.RESULT_CANCEL:
            pass  # The user knows damn well what happened here.
        elif self.result == self.RESULT_PASS:
            QtWidgets.QMessageBox.information(
                QtWidgets.QApplication.activeWindow(), "Installation Required",
                "You can't play without a legal version of Forged Alliance.")
        elif self.result == self.RESULT_BUSY:
            QtWidgets.QMessageBox.information(
                QtWidgets.QApplication.activeWindow(), "Server Busy",
                "The Server is busy preparing new patch files.<br/>Try again later."
            )
        elif self.result == self.RESULT_FAILURE:
            failureDialog()

        # If nothing terribly bad happened until now,
        # the operation is a success and/or the client can display what's up.
        return self.result

    def handleAction(self, bytecount, action, stream):
        """
        Process server responses by interpreting its intent and then acting upon it
        """
        log("handleAction(%s) - %d bytes" % (action, bytecount))

        if action == "PATH_TO_SIM_MOD":
            path = stream.readQString()
            self.modpath = path
            self.result = self.RESULT_SUCCESS
            return

        elif action == "SIM_MOD_NOT_FOUND":
            log("Error: Unknown sim mod requested.")
            self.modpath = ""
            self.result = self.RESULT_FAILURE
            return

        elif action == "LIST_FILES_TO_UP":
            # Used to be an eval() here, this is a safe backwards-compatible fix
            listStr = str(stream.readQString())
            self.filesToUpdate = ast.literal_eval(listStr)

            if self.filesToUpdate is None:
                self.filesToUpdate = []
            return

        elif action == "UNKNOWN_APP":
            log("Error: Unknown app/mod requested.")
            self.result = self.RESULT_FAILURE
            return

        elif action == "THIS_PATCH_IS_IN_CREATION EXCEPTION":
            log("Error: Patch is in creation.")
            self.result = self.RESULT_BUSY
            return

        elif action == "VERSION_PATCH_NOT_FOUND":
            response = stream.readQString()
            log("Error: Patch version %s not found for %s." %
                (self.version, response))
            self.connection.writeToServer("REQUEST_VERSION", self.destination,
                                          response, self.version)
            return

        elif action == "VERSION_MOD_PATCH_NOT_FOUND":
            response = stream.readQString()
            log("Error: Patch version %s not found for %s." %
                (str(self.modversions), response))
            self.connection.writeToServer("REQUEST_MOD_VERSION",
                                          self.destination, response,
                                          json.dumps(self.modversions))
            return

        elif action == "PATCH_NOT_FOUND":
            response = stream.readQString()
            log("Error: Patch not found for %s." % response)
            self.connection.writeToServer("REQUEST", self.destination,
                                          response)

            return

        elif action == "UP_TO_DATE":
            response = stream.readQString()
            log("file : " + response)
            log("%s is up to date." % response)
            self.filesToUpdate.remove(str(response))
            return

        elif action == "ERROR_FILE":
            response = stream.readQString()
            log("ERROR: File not found on server : %s." % response)
            self.filesToUpdate.remove(str(response))
            self.result = self.RESULT_FAILURE
            return

        elif action == "SEND_FILE_PATH":
            path = stream.readQString()
            fileToCopy = stream.readQString()
            url = stream.readQString()

            toFile = os.path.join(util.APPDATA_DIR, str(path), str(fileToCopy))
            self.fetchFile(url, toFile)
            self.filesToUpdate.remove(str(fileToCopy))
            self.updatedFiles.append(str(fileToCopy))

        elif action == "SEND_FILE":
            path = stream.readQString()

            # HACK for feature/new-patcher
            path = util.LUA_DIR if path == "bin" else path

            fileToCopy = stream.readQString()
            size = stream.readInt()
            fileDatas = stream.readRawData(size)

            toFile = os.path.join(util.APPDATA_DIR, str(path), str(fileToCopy))

            writeFile = QtCore.QFile(toFile)

            if writeFile.open(QtCore.QIODevice.WriteOnly):
                writeFile.write(fileDatas)
                writeFile.close()
            else:
                logger.warning(
                    "%s is not writeable in in %s. Skipping." %
                    (fileToCopy,
                     path))  # This may or may not be desirable behavior

            log("%s is copied in %s." % (fileToCopy, path))
            self.filesToUpdate.remove(str(fileToCopy))
            self.updatedFiles.append(str(fileToCopy))

        elif action == "SEND_PATCH_URL":
            destination = str(stream.readQString())
            fileToUpdate = str(stream.readQString())
            url = str(stream.readQString())

            toFile = os.path.join(util.CACHE_DIR, "temp.patch")
            #
            if self.fetchFile(url, toFile):
                completePath = os.path.join(util.APPDATA_DIR, destination,
                                            fileToUpdate)
                self.applyPatch(completePath, toFile)

                log("%s/%s is patched." % (destination, fileToUpdate))
                self.filesToUpdate.remove(str(fileToUpdate))
                self.updatedFiles.append(str(fileToUpdate))
            else:
                log("Failed to update file :'(")
        else:
            log("Unexpected server command received: " + action)
            self.result = self.RESULT_FAILURE

    def applyPatch(self, original, patch):
        toFile = os.path.join(util.CACHE_DIR, "patchedFile")
        # applying delta
        if sys.platform == 'win32':
            xdelta = os.path.join(fafpath.get_libdir(), "xdelta3.exe")
        else:
            xdelta = "xdelta3"
        subprocess.call([xdelta, '-d', '-f', '-s', original, patch, toFile],
                        stdout=subprocess.PIPE)
        shutil.copy(toFile, original)
        os.remove(toFile)
        os.remove(patch)

    # Connection handler methods start here

    def atConnectionError(self, error):
        self.result = self.RESULT_FAILURE

    def atConnectionRead(self):
        self.lastData = time.time()  # Keep resetting that timeout counter

    def atNewBlock(self, blockSize):
        if blockSize > 65536:
            self.progress.setLabelText("Downloading...")
            self.progress.setValue(0)
            self.progress.setMaximum(blockSize)
        else:
            self.progress.setValue(0)
            self.progress.setMinimum(0)
            self.progress.setMaximum(0)

        # Update our Gui at least once before proceeding
        # (we might be receiving a huge file and this is not the first time we get here)
        self.lastData = time.time()
        QtWidgets.QApplication.processEvents()

    def atBlockProgress(self, avail, blockSize):
        self.progress.setValue(avail)

    def atBlockComplete(self, blockSize, block):
        self.progress.setValue(blockSize)
        # Update our Gui at least once before proceeding (we might have to write a big file)
        self.lastData = time.time()
        QtWidgets.QApplication.processEvents()

        action = block.readQString()
        self.handleAction(blockSize, action, block)
        self.progress.setValue(0)
        self.progress.setMinimum(0)
        self.progress.setMaximum(0)
        self.progress.reset()
Exemplo n.º 22
0
    def loadSettings(self):
        self.mode = Settings.get(self._settings_key+'/mode', 'friends')

        self.checkBoxFriends.setCheckState(QtCore.Qt.Checked if self.mode == 'friends' else QtCore.Qt.Unchecked)
        self.parent.mode = self.mode
Exemplo n.º 23
0

# Developer mode flag
def developer():
    return sys.executable.endswith("python.exe")


from config import VERSION as VERSION_STRING

import logging
logger = logging.getLogger(__name__)

LOGFILE_MAX_SIZE = 256 * 1024  # 256kb should be enough for anyone

UNITS_PREVIEW_ROOT = "{}/faf/unitsDB/icons/big/".format(
    Settings.get('content/host'))

import fafpath
COMMON_DIR = fafpath.get_resdir()

stylesheets = {}  # map [qt obj] ->  filename of stylesheet

APPDATA_DIR = Settings.get('client/data_path')

# This is used to store init_*.lua files
LUA_DIR = os.path.join(APPDATA_DIR, "lua")

# This contains the themes
THEME_DIR = os.path.join(APPDATA_DIR, "themes")

# This contains cached data downloaded while communicating with the lobby - at the moment, mostly map preview pngs.
Exemplo n.º 24
0
 def tech_support(self):
     QDesktopServices().openUrl(QUrl(Settings.get("SUPPORT_URL")))
Exemplo n.º 25
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 = "<i" + str(headerSize) + "si"
        data += struct.pack(headerPackStr, headerSize, headerField, chunkSize)

        for field in self._data :
Exemplo n.º 26
0
    def __init__(self, exc_info, *args, **kwargs):
        QtGui.QDialog.__init__(self, *args, **kwargs)

        exc_type, exc_value, traceback_object = exc_info

        dialog = self
        if kwargs.get('automatic'):
            automatic = True
        else:
            automatic = Settings.get('client/auto_bugreport', type=bool, default=True)

        self.trace = "".join(traceback.format_exception(exc_type, exc_value, traceback_object, 10))

        if automatic:
            self.title = "Bug report"
        else:
            self.title = "Report from " + CRASH_REPORT_USER + u": " + str(exc_value)

        self.bugreport_target = BugReportTarget('client',
                                                'https://github.com/FAForever/client',
                                                config.VERSION)
        self.bugreport = BugReport(self.title,
                                   target=self.bugreport_target,
                                   traceback=self.trace,
                                   automatic=automatic)

        dialog.setWindowTitle(self.title)

        description = u""
        try:
            description += (u"\n**FAF Username:** " + CRASH_REPORT_USER)
            description += (u"\n**FAF Version:** " + VERSION_STRING)
            description += (u"\n**FAF Environment:** " + config.environment)
            description += (u"\n**FAF Directory:** " + APPDATA_DIR)
            description += (u"\n**FA Path:** " + str(util.settings.value("ForgedAlliance/app/path", None, type=str)))
            description += (u"\n**Home Directory:** " + PERSONAL_DIR)
        except StandardError:
            description += (u"\n**(Exception raised while writing debug vars)**")

        log = u""
        try:
            log += (u"\n".join(readlines(LOG_FILE_FAF, False)[-128:]))
        except StandardError:
            log += (unicode(LOG_FILE_FAF))
            log += (u"empty or not readable")

        self.bugreport.description = description
        self.bugreport.log = log

        if not automatic:
            self.box = QtGui.QTextEdit()
            self.box.setFont(QtGui.QFont("Lucida Console", 8))
            self.box.append(description)
            dialog.layout().addWidget(self.box)
            dialog.setLayout(QtGui.QVBoxLayout())
            label = QtGui.QLabel()
            label.setText(
                    "An error has occurred in the FAF client. <br><br>You can report it by clicking the ticket button.")
            label.setWordWrap(True)
            dialog.layout().addWidget(label)

            label = QtGui.QLabel()
            label.setText("<b>This is what happened. If you have more to add please write in the field below.</b>")
            label.setWordWrap(False)
            dialog.layout().addWidget(label)
            self.sendButton = QtGui.QPushButton("\nReport error\n")
            self.sendButton.pressed.connect(self.post_report)

            dialog.layout().addWidget(self.sendButton)

            label = QtGui.QLabel()
            label.setText("<b></b><br/><i>(please note that the error may be fatal, proceed at your own risk)</i>")
            label.setWordWrap(False)
            dialog.layout().addWidget(label)

            self.buttons = QtGui.QDialogButtonBox()
            buttons = self.buttons
            buttons.addButton("Continue", QtGui.QDialogButtonBox.AcceptRole)
            buttons.addButton("Close FAF", QtGui.QDialogButtonBox.RejectRole)
            buttons.addButton("Help", QtGui.QDialogButtonBox.HelpRole)
            buttons.accepted.connect(dialog.accept)
            buttons.rejected.connect(dialog.reject)
            buttons.helpRequested.connect(self.tech_support)
            dialog.layout().addWidget(buttons)
        else:
            dialog.setLayout(QtGui.QVBoxLayout())
            label = QtGui.QLabel()
            label.setText("An error has occurred in the FAF client. It has been automatically reported.")
            label.setWordWrap(True)
            dialog.layout().addWidget(label)
            self.post_report()
            self.sendButton = QtGui.QPushButton("\nOK\n")
            self.sendButton.pressed.connect(dialog.accept)
            dialog.layout().addWidget(self.sendButton)
Exemplo n.º 27
0
 def viewAliases(self):
     QtGui.QDesktopServices.openUrl(
         QUrl("{}?name={}".format(Settings.get("NAME_CHANGE_URL"),
                                  self.name)))
Exemplo n.º 28
0
 def _loadRelations(self):
     if self._key is not None:
         rel = Settings.get(self._key)
         self._relations = set(rel) if rel is not None else set()
     else:
         self._relations = set()
Exemplo n.º 29
0
    def _readloop(self):
            bs = self.blocksize if self.blocksize is not None else self._dfile.bytesAvailable()
            self.dest.write(self._dfile.read(bs))
            self.cb_progress(self)

    def succeeded(self):
        return not self.error and not self.canceled

    def waitForCompletion(self):
        waitFlag = QtCore.QEventLoop.WaitForMoreEvents
        while self._running:
            QtWidgets.QApplication.processEvents(waitFlag)


MAP_PREVIEW_ROOT = "{}/faf/vault/map_previews/small/".format(Settings.get('content/host'))


class PreviewDownload(QtCore.QObject):
    done = QtCore.pyqtSignal(object, object)

    def __init__(self, nam, name, url, target_dir, delay_timer=None):
        QtCore.QObject.__init__(self)
        self.requests = set()
        self.name = name
        self._url = url
        self._nam = nam
        self._target_dir = target_dir
        self._delay_timer = delay_timer
        self._dl = None
        if delay_timer is None:
Exemplo n.º 30
0
    def loadSettings(self):
        self.mode = Settings.get(self._settings_key + '/mode', 'friends')

        self.checkBoxFriends.setCheckState(QtCore.Qt.Checked if self.mode ==
                                           'friends' else QtCore.Qt.Unchecked)
        self.parent.mode = self.mode
Exemplo n.º 31
0
 def linkAccount(self):
     QtGui.QDesktopServices.openUrl(
         QtCore.QUrl(Settings.get("STEAMLINK_URL")))
Exemplo n.º 32
0
import util
import logging
from vault import luaparser
import warnings

import io
import zipfile
from config import Settings
from downloadManager import FileDownload
from vault.dialogs import VaultDownloadDialog, downloadVaultAsset

logger = logging.getLogger(__name__)

MODFOLDER = os.path.join(util.PERSONAL_DIR, "My Games", "Gas Powered Games",
                         "Supreme Commander Forged Alliance", "Mods")
MODVAULT_DOWNLOAD_ROOT = "{}/faf/vault/".format(Settings.get('content/host'))

installedMods = []  # This is a global list that should be kept intact.
# So it should be cleared using installedMods[:] = []

# mods selected by user, are not overwritten by temporary mods selected when joining game
selectedMods = Settings.get('play/mods', default=[])


class ModInfo(object):
    def __init__(self, **kwargs):
        self.name = "Not filled in"
        self.version = 0
        self.folder = ""
        self.__dict__.update(kwargs)
Exemplo n.º 33
0
 def forgotPassword(self):
     QtGui.QDesktopServices.openUrl(
         QtCore.QUrl(Settings.get("PASSWORD_RECOVERY_URL")))
Exemplo n.º 34
0
# Initialize logging system
import logging

from PyQt4.QtNetwork import QNetworkAccessManager
from enum import IntEnum

from config import Settings
from .player import Player

logger = logging.getLogger(__name__)
# logger.setLevel(logging.DEBUG)

# Initialize all important globals
LOBBY_HOST = Settings.get("lobby/host")
LOBBY_PORT = Settings.get("lobby/port")
LOCAL_REPLAY_PORT = Settings.get("lobby/relay/port")


class ClientState(IntEnum):
    """
    Various states the client can be in.
    """

    SHUTDOWN = -666  # Going... DOWN!

    # Disconnected state
    # We enter this state if either:
    #  - The user requested it
    #  - We've reconnected too many times
    DISCONNECTED = -4
Exemplo n.º 35
0
 def viewAliases(self):
     QtGui.QDesktopServices.openUrl(QUrl("{}?name={}".format(Settings.get("NAME_CHANGE_URL"), self.name)))
Exemplo n.º 36
0



from PyQt4 import QtCore, QtNetwork, QtGui

import os
import logging
import util
import fa
import json
import time

from config import Settings

INTERNET_REPLAY_SERVER_HOST = Settings.get('replay_server/host')
INTERNET_REPLAY_SERVER_PORT = Settings.get('replay_server/port')

from . import DEFAULT_LIVE_REPLAY
from . import DEFAULT_RECORD_REPLAY

class ReplayRecorder(QtCore.QObject): 
    """
    This is a simple class that takes all the FA replay data input from its inputSocket, writes it to a file,
    and relays it to an internet server via its relaySocket.
    """
    __logger = logging.getLogger(__name__)

    def __init__(self, parent, local_socket, *args, **kwargs):
        QtCore.QObject.__init__(self, *args, **kwargs)
        self.parent = parent
Exemplo n.º 37
0
 def reportBug(self):
     QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("TICKET_URL")))
Exemplo n.º 38
0
    def loadSettings(self):
        self.enabled = Settings.get('notifications/enabled', True, type=bool)
        self.popup_lifetime = Settings.get('notifications/popup_lifetime', 5, type=int)

        self.nsEnabled.setChecked(self.enabled)
        self.nsPopLifetime.setValue(self.popup_lifetime)
Exemplo n.º 39
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) :
Exemplo n.º 40
0
 def renameAccount(self):
     QtGui.QDesktopServices.openUrl(
         QtCore.QUrl(Settings.get("NAME_CHANGE_URL")))
Exemplo n.º 41
0
 def linkAccount(self):
     QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("STEAMLINK_URL")))
Exemplo n.º 42
0
 def reportBug(self):
     QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("TICKET_URL")))
Exemplo n.º 43
0
 def renameAccount(self):
     QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("NAME_CHANGE_URL")))
Exemplo n.º 44
0
import stat
import struct
import shutil
import urllib.request, urllib.error, urllib.parse
import zipfile
import tempfile
import re
# module imports
import fa
# local imports
from config import Settings
from vault.dialogs import downloadVaultAssetNoMsg

logger = logging.getLogger(__name__)

route = Settings.get('content/host')
VAULT_PREVIEW_ROOT = "{}/faf/vault/map_previews/small/".format(route)
VAULT_DOWNLOAD_ROOT = "{}/faf/vault/".format(route)
VAULT_COUNTER_ROOT = "{}/faf/vault/map_vault/inc_downloads.php".format(route)

from model.game import OFFICIAL_MAPS as maps

__exist_maps = None


def isBase(mapname):
    """
    Returns true if mapname is the name of an official map
    """
    return mapname in maps
Exemplo n.º 45
0
 def forgotPassword(self):
     QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("PASSWORD_RECOVERY_URL")))