예제 #1
0
def check(mod, mapname = None, version = None, modVersions = None, sim_mods = None, silent=False):
    '''
    This checks whether the game is properly updated and has the correct map.
    '''
    logger.info("Checking FA for: " + str(mod) + " and map " + str(mapname))
    
    if not mod:
        QtGui.QMessageBox.warning(None, "No Mod Specified", "The application didn't specify which mod to update.")
        return False
        
    if not fa.gamepath:
        savePath(fa.updater.autoDetectPath())
               
    while (not fa.updater.validatePath(fa.gamepath)):
        logger.warn("Invalid path: " + str(fa.gamepath))
        wizard = fa.updater.Wizard(None)
        result = wizard.exec_()
        if not result:  # The wizard only returns successfully if the path is okay.
            return False
    
    # Perform the actual comparisons and updating                    
    logger.info("Updating FA for mod: " + str(mod) + ", version " + str(version))

    # Spawn an update for the required mod
    updater = fa.updater.Updater(mod, version, modVersions, silent=silent)
            
    result = updater.run()

    updater = None #Our work here is done

    if (result != fa.updater.Updater.RESULT_SUCCESS):
        return False 

    logger.info("Writing fa_path.lua config file.")
    try:
        writeFAPathLua()
    except:
        logger.error("fa_path.lua can't be written: ", exc_info=sys.exc_info())
        QtGui.QMessageBox.critical(None, "Cannot write fa_path.lua", "This is a  rare error and you should report it!<br/>(open Menu BETA, choose 'Report a Bug')")             
        return False
        

    # Now it's down to having the right map
    if mapname:
        if not checkMap(mapname, silent=silent):
            return False

    if sim_mods:
        return checkMods(sim_mods)
        
    return True #FA is checked and ready
예제 #2
0
def replay(source, detach = False):
    '''
    Launches FA streaming the replay from the given location. Source can be a QUrl or a string
    '''
    logger.info("fa.exe.replay(" + str(source) + ", detach = " + str(detach))
    
    if (available()):
        version = None
        featured_mod_versions = None
        arg_string = None
        replay_id = None
        # Convert strings to URLs
        if isinstance(source, basestring):
            if os.path.isfile(source):
                if source.endswith(".fafreplay"):   # the new way of doing things
                    replay = open(source, "rt")
                    info = json.loads(replay.readline())
                    
                    binary = QtCore.qUncompress(QtCore.QByteArray.fromBase64(replay.read()))
                    logger.info("Extracted " + str(binary.size()) + " bytes of binary data from .fafreplay.")
                    replay.close()
                    
                    if binary.size() == 0:
                        logger.info("Invalid replay")
                        QtGui.QMessageBox.critical(None, "FA Forever Replay", "Sorry, this replay is corrupted.")
                        return False
                        
                    scfa_replay = QtCore.QFile(os.path.join(util.CACHE_DIR, "temp.scfareplay"))
                    scfa_replay.open(QtCore.QIODevice.WriteOnly | QtCore.QIODevice.Truncate)                
                    scfa_replay.write(binary)
                    scfa_replay.flush()
                    scfa_replay.close()                    
                                
                    mapname = info.get('mapname', None)
                    mod = info['featured_mod']        
                    replay_id = info['uid']
                    featured_mod_versions = info.get('featured_mod_versions', None)
                    arg_string = scfa_replay.fileName()
                    
                    parser = replayParser(arg_string)
                    version = parser.getVersion() 
                    
                    if mod == "gw":
                        infoReplayGW = fa.gwreplayinfo.GWReplayInfo(info['uid'])
                        result = infoReplayGW.run()
                        if (result != fa.gwreplayinfo.GWReplayInfo.RESULT_SUCCESS):
                            logger.info("We don't have the info necessary for GW")
                            return False                  

                        logger.info("Writing GW game table file.")

                elif source.endswith(".scfareplay"):   # compatibility mode
                    filename = os.path.basename(source)
                    if len(filename.split(".")) > 2:                        
                        mod = filename.rsplit(".", 2)[1]
                        logger.info("mod guessed from " + source + " is " + mod)
                    else:
                        mod = "faf" #TODO: maybe offer a list of mods for the user.
                        logger.warn("no mod could be guessed, using fallback ('faf') ")
                                    
                    mapname = None
                    arg_string = source
                    parser = replayParser(arg_string)
                    version = parser.getVersion()
                else:
                    QtGui.QMessageBox.critical(None, "FA Forever Replay", "Sorry, FAF has no idea how to replay this file:<br/><b>" + source + "</b>")        
                
                logger.info("Replaying " + str(arg_string) + " with mod " + str(mod) + " on map " + str(mapname))
            else:
                source = QtCore.QUrl(source)    #Try to interpret the string as an actual url, it may come from the command line
        
        if isinstance(source, QtCore.QUrl):
            url = source
            #Determine if it's a faflive url
            if url.scheme() == "faflive":
                mod = url.queryItemValue("mod")
                mapname = url.queryItemValue("map")                
                replay_id = url.path().split("/")[0]
                # whip the URL into shape so ForgedAlliance.exe understands it
                arg_url = QtCore.QUrl(url)
                arg_url.setScheme("gpgnet")
                arg_url.setEncodedQuery(QtCore.QByteArray())
                arg_string = arg_url.toString()
            else:
                QtGui.QMessageBox.critical(None, "FA Forever Replay", "App doesn't know how to play replays from that scheme:<br/><b>" + url.scheme() + "</b>")        
                return False                        

        # We couldn't construct a decent argument format to tell ForgedAlliance for this replay
        if not arg_string:
            QtGui.QMessageBox.critical(None, "FA Forever Replay", "App doesn't know how to play replays from that source:<br/><b>" + str(source) + "</b>")
            return False
            
        # Launch preparation: Start with an empty arguments list
        arguments = []    
        arguments.append('/replay')         
        arguments.append(arg_string)  
        #arguments.append('/sse2')
        #arguments.append('/networksafe')                        
                        
        #Proper mod loading code
        if not '/init' in arguments:
            arguments.append('/init')
            arguments.append("init_" + mod + ".lua")
                                        
        #disable bug reporter and movies
        arguments.append('/nobugreport')

        #log file
        arguments.append("/log")
        arguments.append('"' + util.LOG_FILE_REPLAY + '"')

        if replay_id:
            arguments.append("/replayid")
            arguments.append(str(replay_id))

        # Update the game appropriately
        if not check(mod, mapname, version, featured_mod_versions):
            logger.error("Can't watch replays without an updated Forged Alliance game!")
            return False        

        if mod == "gw":
        # in case of GW, we need to alter the scenario for support AIs
            if not fa.maps.gwmap(info['mapname']):
                logger.error("You don't have the required map.")
                return    

        # Finally, run executable        
        if __run(None, arguments, detach):
            logger.info("Viewing Replay.")
            return True
        else:
            logger.error("Replaying failed.")
            return False