示例#1
0
def _detect_game(opts, backup_bash_ini):
    # Read the bash.ini file either from Mopy or from the backup location
    bashIni = _bash_ini_parser(backup_bash_ini)
    # if uArg is None, then get the UserPath from the ini file
    user_path = opts.userPath or None  ##: not sure why this must be set first
    if user_path is None:
        ini_user_path = bass.get_ini_option(bashIni, u'sUserPath')
        if ini_user_path and not ini_user_path == u'.':
            user_path = ini_user_path
    if user_path:
        drive, path = os.path.splitdrive(user_path)
        os.environ['HOMEDRIVE'] = drive
        os.environ['HOMEPATH'] = path
    # Detect the game we're running for ---------------------------------------
    bush_game = _import_bush_and_set_game(opts, bashIni)
    if not bush_game:
        return None, None, None
    #--Initialize Directories to perform backup/restore operations
    #--They depend on setting the bash.ini and the game
    game_ini_path = initialization.init_dirs(bashIni, opts.personalPath,
                                             opts.localAppDataPath, bush_game)
    return bashIni, bush_game, game_ini_path
示例#2
0
def _detectGames(cli_path=u'', bash_ini_=None):
    """Detect which supported games are installed.

    - If Bash supports no games raise.
    - For each game supported by Bash check for a supported game executable
    in the following dirs, in decreasing precedence:
       - the path provided by the -o cli argument if any
       - the sOblivionPath Bash Ini entry if present
       - one directory up from Mopy
    If a game exe is found update the path to this game and return immediately.
    Return (foundGames, name)
      - foundGames: a dict from supported games to their paths (the path will
      default to the windows registry path to the game, if present)
      - name: the game found in the first installDir or None if no game was
      found - a 'suggestion' for a game to use (if no game is specified/found
      via -g argument).
    """
    #--Find all supported games and all games in the windows registry
    foundGames_ = _supportedGames()  # sets _allGames if not set
    if not _allGames:  # if allGames is empty something goes badly wrong
        raise BoltError(_(u'No game support modules found in Mopy/bash/game.'))
    # check in order of precedence the -o argument, the ini and our parent dir
    installPaths = collections.OrderedDict(
    )  #key->(path, found msg, error msg)
    #--First: path specified via the -o command line argument
    if cli_path != u'':
        test_path = GPath(cli_path)
        if not test_path.isabs():
            test_path = Path.getcwd().join(test_path)
        installPaths['cmd'] = (
            test_path,
            _(u'Set game mode to %(gamename)s specified via -o argument') +
            u': ',
            _(u'No known game in the path specified via -o argument: ' +
              u'%(path)s'))
    #--Second: check if sOblivionPath is specified in the ini
    ini_game_path = get_ini_option(bash_ini_, u'sOblivionPath')
    if ini_game_path and not ini_game_path == u'.':
        test_path = GPath(ini_game_path.strip())
        if not test_path.isabs():
            test_path = Path.getcwd().join(test_path)
        installPaths['ini'] = (
            test_path,
            _(u'Set game mode to %(gamename)s based on sOblivionPath setting '
              u'in bash.ini') + u': ',
            _(u'No known game in the path specified in sOblivionPath ini '
              u'setting: %(path)s'))
    #--Third: Detect what game is installed one directory up from Mopy
    test_path = Path.getcwd()
    if test_path.cs[-4:] == u'mopy':
        test_path = GPath(test_path.s[:-5])
        if not test_path.isabs():
            test_path = Path.getcwd().join(test_path)
        installPaths['upMopy'] = (
            test_path,
            _(u'Set game mode to %(gamename)s found in parent directory of'
              u' Mopy') + u': ',
            _(u'No known game in parent directory of Mopy: %(path)s'))
    #--Detect
    deprint(
        u'Detecting games via the -o argument, bash.ini and relative path:')
    # iterate installPaths in insert order ('cmd', 'ini', 'upMopy')
    for test_path, foundMsg, errorMsg in installPaths.itervalues():
        for name, info in _allGames.items():
            if test_path.join(*info.game_detect_file).exists():
                # Must be this game
                deprint(foundMsg % {'gamename': name}, test_path)
                foundGames_[name] = test_path
                return foundGames_, name
        # no game exe in this install path - print error message
        deprint(errorMsg % {'path': test_path.s})
    # no game found in installPaths - foundGames are the ones from the registry
    return foundGames_, None
示例#3
0
def get_path_from_ini(bash_ini_, option_key, section_key=u'General'):
    get_value = get_ini_option(bash_ini_, option_key, section_key)
    get_value = (get_value and get_value.strip()) or u'.'
    return GPath(get_value) if get_value != u'.' else None
示例#4
0
def init_dirs(bashIni_, personal, localAppData, game_info):
    if not mopy_dirs_initialized:
        raise BoltError(u'init_dirs: Mopy dirs uninitialized')
    #--Oblivion (Application) Directories
    dirs['app'] = game_info.gamePath
    dirs['defaultPatches'] = dirs['mopy'].join(u'Bash Patches',
                                               game_info.fsName)

    #  Personal
    personal = getPersonalPath(bashIni_, personal)
    dirs['saveBase'] = personal.join(u'My Games', game_info.fsName)

    #  Local Application Data
    localAppData = getLocalAppDataPath(bashIni_, localAppData)
    dirs['userApp'] = localAppData.join(game_info.fsName)

    # Use local copy of the oblivion.ini if present
    # see: http://en.uesp.net/wiki/Oblivion:Ini_Settings
    # Oblivion reads the Oblivion.ini in the directory where it exists
    # first, and only if bUseMyGames is non-existent or set to 1 does it
    # then look for My Documents\My Games\Oblivion.ini. In other words,
    # both can exist simultaneously, and only the value of bUseMyGames in
    # the Oblivion.ini directory where Oblivion.exe is run from will
    # actually matter.
    # Utumno: not sure how/if this applies to other games
    data_oblivion_ini = dirs['app'].join(game_info.iniFiles[0])
    game_ini_path = dirs['saveBase'].join(game_info.iniFiles[0])
    dirs['mods'] = dirs['app'].join(u'Data')
    if data_oblivion_ini.exists():
        oblivionIni = ConfigParser()
        oblivionIni.read(data_oblivion_ini.s)
        # is bUseMyGamesDirectory set to 0?
        if get_ini_option(oblivionIni, u'bUseMyGamesDirectory') == u'0':
            game_ini_path = data_oblivion_ini
            # Set the save game folder to the Oblivion directory
            dirs['saveBase'] = dirs['app']
            # Set the data folder to sLocalMasterPath
            dirs['mods'] = dirs['app'].join(
                get_ini_option(oblivionIni, u'SLocalMasterPath') or u'Data')
    # these are relative to the mods path so they must be set here
    dirs['patches'] = dirs['mods'].join(u'Bash Patches')
    dirs['tweaks'] = dirs['mods'].join(u'INI Tweaks')
    #--Mod Data, Installers
    oblivionMods, oblivionModsSrc = getOblivionModsPath(bashIni_, game_info)
    dirs['modsBash'], modsBashSrc = getBashModDataPath(bashIni_, game_info)
    dirs['modsBash'], modsBashSrc = getLegacyPathWithSource(
        dirs['modsBash'], dirs['app'].join(u'Data', u'Bash'), modsBashSrc,
        u'Relative Path')

    dirs['installers'] = oblivionMods.join(u'Bash Installers')
    dirs['installers'] = getLegacyPath(dirs['installers'],
                                       dirs['app'].join(u'Installers'))

    dirs['bainData'], bainDataSrc = getBainDataPath(bashIni_)

    dirs['bsaCache'] = dirs['bainData'].join(u'BSA Cache')

    dirs['converters'] = dirs['installers'].join(u'Bain Converters')
    dirs['dupeBCFs'] = dirs['converters'].join(u'--Duplicates')
    dirs['corruptBCFs'] = dirs['converters'].join(u'--Corrupt')

    # create bash user folders, keep these in order
    keys = ('modsBash', 'installers', 'converters', 'dupeBCFs', 'corruptBCFs',
            'bainData', 'bsaCache')
    try:
        env.shellMakeDirs([dirs[key] for key in keys])
    except NonExistentDriveError as e:
        # NonExistentDriveError is thrown by shellMakeDirs if any of the
        # directories cannot be created due to residing on a non-existing
        # drive. Find which keys are causing the errors
        badKeys = set()  # List of dirs[key] items that are invalid
        # First, determine which dirs[key] items are causing it
        for key in keys:
            if dirs[key] in e.failed_paths:
                badKeys.add(key)
        # Now, work back from those to determine which setting created those
        msg = _(u'Error creating required Wrye Bash directories.') + u'  ' + _(
            u'Please check the settings for the following paths in your '
            u'bash.ini, the drive does not exist') + u':\n\n'
        relativePathError = []
        if 'modsBash' in badKeys:
            if isinstance(modsBashSrc, list):
                msg += (u' '.join(modsBashSrc) + u'\n    ' +
                        dirs['modsBash'].s + u'\n')
            else:
                relativePathError.append(dirs['modsBash'])
        if {'installers', 'converters', 'dupeBCFs', 'corruptBCFs'} & badKeys:
            # All derived from oblivionMods -> getOblivionModsPath
            if isinstance(oblivionModsSrc, list):
                msg += (u' '.join(oblivionModsSrc) + u'\n    ' +
                        oblivionMods.s + u'\n')
            else:
                relativePathError.append(oblivionMods)
        if {'bainData', 'bsaCache'} & badKeys:
            # Both derived from 'bainData' -> getBainDataPath
            # Sometimes however, getBainDataPath falls back to oblivionMods,
            # So check to be sure we haven't already added a message about that
            if bainDataSrc != oblivionModsSrc:
                if isinstance(bainDataSrc, list):
                    msg += (u' '.join(bainDataSrc) + u'\n    ' +
                            dirs['bainData'].s + u'\n')
                else:
                    relativePathError.append(dirs['bainData'])
        if relativePathError:
            msg += u'\n' + _(u'A path error was the result of relative paths.')
            msg += u'  ' + _(
                u'The following paths are causing the errors, '
                u'however usually a relative path should be fine.')
            msg += u'  ' + _(u'Check your setup to see if you are using '
                             u'symbolic links or NTFS Junctions') + u':\n\n'
            msg += u'\n'.join([u'%s' % x for x in relativePathError])
        raise BoltError(msg)
    global bash_dirs_initialized
    bash_dirs_initialized = True
    return game_ini_path