def handle_noargs(self, **options):
        project_root = options.get("path", None)
        if not project_root:
            project_root = getattr(settings, 'BASE_DIR', None)

        verbosity = int(options.get("verbosity"))
        if not project_root:
            warnings.warn("settings.BASE_DIR or specifying --path will become mandatory in 1.4.0", DeprecationWarning)
            project_root = get_project_root()
            if verbosity > 0:
                self.stdout.write("""No path specified and settings.py does not contain BASE_DIR.
Assuming '%s' is the project root.

Please add BASE_DIR to your settings.py future versions 1.4.0 and higher of Django-Extensions
will require either BASE_DIR or specifying the --path option.

Waiting for 30 seconds. Press ctrl-c to abort.
""" % project_root)
                if getattr(settings, 'COMPILE_PYC_DEPRECATION_WAIT', True):
                    try:
                        time.sleep(30)
                    except KeyboardInterrupt:
                        self.stdout.write("Aborted\n")
                        return

        for root, dirs, filenames in os.walk(project_root):
            for filename in fnmatch.filter(filenames, '*.py'):
                full_path = _j(root, filename)
                if verbosity > 1:
                    self.stdout.write("Compiling %s...\n" % full_path)
                py_compile.compile(full_path)
    def handle_noargs(self, **options):
        project_root = get_project_root()
	verbose = options.get("verbose", False)
	for root, dirs, files in os.walk(project_root):
	    for file in files:
		ext = os.path.splitext(file)[1]
		if ext==".py":
		    full_path = _j(root, file)
		    if verbose:
			print "%sc" % full_path
		    py_compile.compile(full_path)
		    
    def handle_noargs(self, **options):
        project_root = get_project_root()
	exts = options.get("optimize", False) and [".pyc", ".pyo"] or [".pyc"]
	verbose = options.get("verbose", False)
	for root, dirs, files in os.walk(project_root):
	    for file in files:
		ext = os.path.splitext(file)[1]
		if ext in exts:
		    full_path = _j(root, file)
		    if verbose:
			print full_path
		    os.remove(full_path)
Example #4
0
    def handle_noargs(self, **options):
        project_root = options.get('path', None)
        if not project_root:
            project_root = get_project_root()
        verbose = int(options.get('verbosity', 1)) > 1

        for (root, dirs, files) in os.walk(project_root):
            for file in files:
                ext = os.path.splitext(file)[1]
                if ext == '.py':
                    full_path = _j(root, file)
                    if verbose:
                        print '%sc' % full_path
                    py_compile.compile(full_path)
Example #5
0
    def handle_noargs(self, **options):
        project_root = options.get("path", None)
        if not project_root:
            project_root = get_project_root()
        verbose = int(options.get("verbosity", 1)) > 1

        for root, dirs, files in os.walk(project_root):
            for file in files:
                ext = os.path.splitext(file)[1]
                if ext == ".py":
                    full_path = _j(root, file)
                    if verbose:
                        print("%sc" % full_path)
                    py_compile.compile(full_path)
    def handle_noargs(self, **options):
        project_root = options.get("path", None)
        if not project_root:
            project_root = getattr(settings, 'BASE_DIR', None)

        verbosity = int(options.get("verbosity"))
        if not project_root:
            raise CommandError("No --path specified and settings.py does not contain BASE_DIR")

        for root, dirs, filenames in os.walk(project_root):
            for filename in fnmatch.filter(filenames, '*.py'):
                full_path = _j(root, filename)
                if verbosity > 1:
                    self.stdout.write("Compiling %s...\n" % full_path)
                py_compile.compile(full_path)
Example #7
0
    def handle_noargs(self, **options):
        project_root = options.get('path', None)
        if not project_root:
            project_root = get_project_root()
        exts = options.get('optimize', False) and ['.pyc', '.pyo'] \
            or ['.pyc']
        verbose = int(options.get('verbosity', 1)) > 1

        for (root, dirs, files) in os.walk(project_root):
            for file in files:
                ext = os.path.splitext(file)[1]
                if ext in exts:
                    full_path = _j(root, file)
                    if verbose:
                        print full_path
                    os.remove(full_path)
    def handle_noargs(self, **options):
        project_root = options.get("path", None)
        verbosity = int(options.get("verbosity"))
        if not project_root:
            project_root = get_project_root()
            if verbosity > 0:
                self.stdout.write(
                    "No path specified, assuming %s is the project root.\n"
                    % project_root)

        for root, dirs, filenames in os.walk(project_root):
            for filename in fnmatch.filter(filenames, '*.py'):
                full_path = _j(root, filename)
                if verbosity > 1:
                    self.stdout.write("Compiling %s...\n" % full_path)
                py_compile.compile(full_path)
Example #9
0
    def handle_noargs(self, **options):
        project_root = options.get("path", None)
        verbosity = int(options.get("verbosity"))
        if not project_root:
            project_root = get_project_root()
            if verbosity > 0:
                self.stdout.write(
                    "No path specified, assuming %s is the project root.\n"
                    % project_root)
        exts = options.get("optimize", False) and "*.py[co]" or "*.pyc"

        for root, dirs, filenames in os.walk(project_root):
            for filename in fnmatch.filter(filenames, exts):
                full_path = _j(root, filename)
                if verbosity > 1:
                    self.stdout.write("%s\n" % full_path)
                os.remove(full_path)
Example #10
0
    def handle_noargs(self, **options):
        project_root = options.get("path", getattr(settings, 'BASE_DIR', None))
        if not project_root:
            project_root = getattr(settings, 'BASE_DIR', None)

        verbosity = int(options.get("verbosity"))
        if not project_root:
            raise CommandError("No --path specified and settings.py does not contain BASE_DIR")

        exts = options.get("optimize", False) and "*.py[co]" or "*.pyc"

        for root, dirs, filenames in os.walk(project_root):
            for filename in fnmatch.filter(filenames, exts):
                full_path = _j(root, filename)
                if verbosity > 1:
                    self.stdout.write("%s\n" % full_path)
                os.remove(full_path)
    def handle_noargs(self, **options):
        project_root = options.get("path", None)
        if not project_root:
            project_root = get_project_root()
        exts = options.get("optimize", False) and [".pyc", ".pyo"] or [".pyc"]
        verbose = int(options.get("verbosity", 1))

        if verbose > 1:
            print "Project Root: %s" % project_root

        for root, dirs, files in os.walk(project_root):
            for file in files:
                ext = os.path.splitext(file)[1]
                if ext in exts:
                    full_path = _j(root, file)
                    if verbose > 1:
                        print full_path
                    os.remove(full_path)
Example #12
0
def memoize_newer_than_subdirs(func, args, pickle_file, directory):
    """
    A pickle_file is invalid if at least one subdirectory is newer than it.
    """
    pickle_mtime = os.path.getmtime(pickle_file)
    for d in os.listdir(directory):
        d_path = _j(directory, d)
        if not os.path.isdir(d_path) or \
                        os.path.basename(d_path) in [
                    # These change all the time.  Ignore them.
                    '.git',
                    'shadow_library',
                    'paper',
                    'generated',
                ]:
            continue
        if os.path.getmtime(d_path) > pickle_mtime:
            # print ("INVALID: {d_path} > {pickle_file}".format(**locals()))
            return False
    # Valid
    return True
Example #13
0
    def handle_noargs(self, **options):
        from django.conf import settings
        if settings.BUILT:
            settings.LOG.info("Installation built by build process; skipping clean_pyc")
            return

        project_root = options.get("path", None)
        if not project_root:
            project_root = get_project_root()
        exts = options.get("optimize", False) and [".pyc", ".pyo"] or [".pyc"]
        verbose = int(options.get("verbosity", 1))

        if verbose > 1:
            print "Project Root: %s" % project_root

        for root, dirs, files in os.walk(project_root):
            for file in files:
                ext = os.path.splitext(file)[1]
                if ext in exts:
                    full_path = _j(root, file)
                    if verbose > 1:
                        print full_path
                    os.remove(full_path)
Example #14
0
 def each_file(self):
     for dirpath, dirnames, filenames in os.walk(self.directory):
         for base in filenames:
             path = _j(dirpath, base)
             if self.is_venn_js_path(path) or self.is_js_path(path):
                 yield path
distributed with RL-Scope python wheel.
"""
from rlscope.profiler.rlscope_logging import logger
import sys
import textwrap
import os

from os.path import join as _j, abspath as _a, exists as _e, dirname as _d, basename as _b

from rlscope.profiler.util import print_cmd
import rlscope

DEBUG = False

INSTALL_ROOT = _d(os.path.realpath(rlscope.__file__))
CPP_LIB = _j(INSTALL_ROOT, 'cpp', 'lib')
CPP_BIN = _j(INSTALL_ROOT, 'cpp', 'bin')
CPP_INCLUDE = _j(INSTALL_ROOT, 'cpp', 'include')

def execve_rlscope_binary(binary):
    exe_path = _j(CPP_BIN, binary)
    if not os.path.exists(exe_path):
        logger.error("Couldn't find {bin} binary @ {path}".format(
            bin=binary,
            path=exe_path,
        ))
        sys.exit(1)
    cmd = [exe_path] + sys.argv[1:]
    if DEBUG:
        print_cmd(cmd)
    env = dict(os.environ)
Example #16
0
class Fallout3GameInfo(GameInfo):
    displayName = u'Fallout 3'
    fsName = u'Fallout3'
    altName = u'Wrye Flash'
    bash_root_prefix = u'Fallout3'
    launch_exe = u'Fallout3.exe'
    game_detect_file = u'Fallout3.exe'
    version_detect_file = u'Fallout3.exe'
    master_file = u'Fallout3.esm'
    pklfile = u'Fallout3_ids.pkl'
    masterlist_dir = u'Fallout3'
    regInstallKeys = (u'Bethesda Softworks\\Fallout3',u'Installed Path')
    nexusUrl = u'https://www.nexusmods.com/fallout3/'
    nexusName = u'Fallout 3 Nexus'
    nexusKey = u'bash.installers.openFallout3Nexus'

    using_txt_file = False
    plugin_name_specific_dirs = GameInfo.plugin_name_specific_dirs + [
        _j(u'textures', u'characters', u'BodyMods'),
        _j(u'textures', u'characters', u'FaceMods')]

    class Ck(GameInfo.Ck):
        ck_abbrev = u'GECK'
        long_name = u'Garden of Eden Creation Kit'
        exe = u'GECK.exe'
        se_args = u'-editor'
        image_name = u'geck%s.png'

    class Se(GameInfo.Se):
        se_abbrev = u'FOSE'
        long_name = u'Fallout 3 Script Extender'
        exe = u'fose_loader.exe'
        # There is no fose_steam_loader.dll, so we have to list all included
        # DLLs, since people could delete any DLL not matching the game version
        # they're using
        ver_files = [u'fose_loader.exe', u'fose_1_7ng.dll', u'fose_1_7.dll',
                     u'fose_1_6.dll', u'fose_1_5.dll', u'fose_1_4b.dll',
                     u'fose_1_4.dll', u'fose_1_1.dll', u'fose_1_0.dll']
        plugin_dir = u'FOSE'
        cosave_tag = u'FOSE'
        cosave_ext = u'.fose'
        url = u'http://fose.silverlock.org/'
        url_tip = u'http://fose.silverlock.org/'

    class Ini(GameInfo.Ini):
        allow_new_lines = False
        bsa_redirection_key = (u'Archive', u'sArchiveList')
        default_ini_file = u'Fallout_default.ini'
        dropdown_inis = [u'Fallout.ini', u'FalloutPrefs.ini']
        supports_mod_inis = False

    class Ess(GameInfo.Ess):
        ext = u'.fos'

    class Bsa(GameInfo.Bsa):
        allow_reset_timestamps = True
        # ArchiveInvalidation Invalidated, which we shipped unmodified for a
        # long time, uses an Oblivion BSA with version 0x67, so we have to
        # accept those here as well
        valid_versions = {0x67, 0x68}

    class Xe(GameInfo.Xe):
        full_name = u'FO3Edit'
        xe_key_prefix = u'fo3View'

    class Bain(GameInfo.Bain):
        data_dirs = GameInfo.Bain.data_dirs | {
            u'config', # mod config files (INIs)
            u'distantlod',
            u'docs',
            u'facegen',
            u'fonts',
            u'fose',
            u'menus',
            u'uio', # User Interface Organizer
            u'scripts',
            u'shaders',
            u'trees',
        }
        keep_data_dirs = {u'LSData'}
        keep_data_files = {u'Fallout - AI!.bsa'}
        skip_bain_refresh = {u'fo3edit backups', u'fo3edit cache'}
        wrye_bash_data_files = {u'ArchiveInvalidationInvalidated!.bsa'}

    class Esp(GameInfo.Esp):
        canBash = True
        canEditHeader = True
        validHeaderVersions = (0.85, 0.94)
        stringsFiles = []
        generate_temp_child_onam = True

    # Remaining to add:
    # 'Body-F', 'Body-M', 'Body-Size-F', 'Body-Size-M', 'Eyes', 'Hair',
    # 'R.Attributes-F', 'R.Attributes-M', 'R.Description', 'R.Ears', 'R.Head',
    # 'R.Mouth', 'R.Relations', 'R.Skills', 'R.Teeth', 'Voice-F', 'Voice-M'
    allTags = {
        u'Actors.ACBS', u'Actors.AIData', u'Actors.AIPackages',
        u'Actors.AIPackagesForceAdd', u'Actors.Anims', u'Actors.CombatStyle',
        u'Actors.DeathItem', u'Actors.RecordFlags', u'Actors.Skeleton',
        u'Actors.Spells', u'Actors.SpellsForceAdd', u'Actors.Stats',
        u'C.Acoustic', u'C.Climate', u'C.Encounter', u'C.ForceHideLand',
        u'C.ImageSpace', u'C.Light', u'C.Music', u'C.Name', u'C.Owner',
        u'C.RecordFlags', u'C.Regions', u'C.Water', u'Creatures.Blood',
        u'Creatures.Type', u'Deactivate', u'Deflst', u'Delev', u'Destructible',
        u'EffectStats', u'EnchantmentStats', u'Factions', u'Filter',
        u'Graphics', u'Invent.Add', u'Invent.Change', u'Invent.Remove',
        u'MustBeActiveIfImported', u'Names', u'NoMerge', u'NPC.Class',
        u'NPC.Eyes', u'NPC.FaceGen', u'NPC.Hair', u'NPC.Race',
        u'NpcFacesForceFullImport', u'ObjectBounds', u'Relations.Add',
        u'Relations.Change', u'Relations.Remove', u'Relev', u'Scripts',
        u'Sound', u'SpellStats', u'Stats', u'Text',
    }

    # Remaining to add:
    #  AssortedTweaker, NamesTweaker, RacePatcher, UpdateReferences
    patchers = (
        u'PatchMerger', # PatchMerger must come first!
        u'ActorImporter', u'AliasesPatcher', u'CellImporter',
        u'ContentsChecker', u'DeathItemPatcher', u'DestructiblePatcher',
        u'FidListsMerger', u'GmstTweaker', u'GraphicsPatcher',
        u'ImportActorsSpells', u'ImportEffectsStats', u'ImportEnchantmentStats',
        u'ImportFactions', u'ImportInventory', u'ImportRelations',
        u'ImportScripts', u'KFFZPatcher', u'ListsMerger', u'NamesPatcher',
        u'NPCAIPackagePatcher', u'NpcFacePatcher', u'ObjectBoundsImporter',
        u'SoundPatcher', u'SpellsPatcher', u'StatsPatcher', u'TextImporter',
        u'TweakActors',
    )

    weaponTypes = (
        _(u'Big gun'),
        _(u'Energy'),
        _(u'Small gun'),
        _(u'Melee'),
        _(u'Unarmed'),
        _(u'Thrown'),
        _(u'Mine'),
        )

    raceNames = {
        0x000019 : _(u'Caucasian'),
        0x0038e5 : _(u'Hispanic'),
        0x0038e6 : _(u'Asian'),
        0x003b3e : _(u'Ghoul'),
        0x00424a : _(u'AfricanAmerican'),
        0x0042be : _(u'AfricanAmerican Child'),
        0x0042bf : _(u'AfricanAmerican Old'),
        0x0042c0 : _(u'Asian Child'),
        0x0042c1 : _(u'Asian Old'),
        0x0042c2 : _(u'Caucasian Child'),
        0x0042c3 : _(u'Caucasian Old'),
        0x0042c4 : _(u'Hispanic Child'),
        0x0042c5 : _(u'Hispanic Old'),
        0x04bb8d : _(u'Caucasian Raider'),
        0x04bf70 : _(u'Hispanic Raider'),
        0x04bf71 : _(u'Asian Raider'),
        0x04bf72 : _(u'AfricanAmerican Raider'),
        0x0987dc : _(u'Hispanic Old Aged'),
        0x0987dd : _(u'Asian Old Aged'),
        0x0987de : _(u'AfricanAmerican Old Aged'),
        0x0987df : _(u'Caucasian Old Aged'),
        }

    raceShortNames = {
        0x000019 : u'Cau',
        0x0038e5 : u'His',
        0x0038e6 : u'Asi',
        0x003b3e : u'Gho',
        0x00424a : u'Afr',
        0x0042be : u'AfC',
        0x0042bf : u'AfO',
        0x0042c0 : u'AsC',
        0x0042c1 : u'AsO',
        0x0042c2 : u'CaC',
        0x0042c3 : u'CaO',
        0x0042c4 : u'HiC',
        0x0042c5 : u'HiO',
        0x04bb8d : u'CaR',
        0x04bf70 : u'HiR',
        0x04bf71 : u'AsR',
        0x04bf72 : u'AfR',
        0x0987dc : u'HOA',
        0x0987dd : u'AOA',
        0x0987de : u'FOA',
        0x0987df : u'COA',
        }

    raceHairMale = {
        0x000019 : 0x014b90, #--Cau
        0x0038e5 : 0x0a9d6f, #--His
        0x0038e6 : 0x014b90, #--Asi
        0x003b3e : None, #--Gho
        0x00424a : 0x0306be, #--Afr
        0x0042be : 0x060232, #--AfC
        0x0042bf : 0x0306be, #--AfO
        0x0042c0 : 0x060232, #--AsC
        0x0042c1 : 0x014b90, #--AsO
        0x0042c2 : 0x060232, #--CaC
        0x0042c3 : 0x02bfdb, #--CaO
        0x0042c4 : 0x060232, #--HiC
        0x0042c5 : 0x02ddee, #--HiO
        0x04bb8d : 0x02bfdb, #--CaR
        0x04bf70 : 0x02bfdb, #--HiR
        0x04bf71 : 0x02bfdb, #--AsR
        0x04bf72 : 0x0306be, #--AfR
        0x0987dc : 0x0987da, #--HOA
        0x0987dd : 0x0987da, #--AOA
        0x0987de : 0x0987d9, #--FOA
        0x0987df : 0x0987da, #--COA
        }

    raceHairFemale = {
        0x000019 : 0x05dc6b, #--Cau
        0x0038e5 : 0x05dc76, #--His
        0x0038e6 : 0x022e50, #--Asi
        0x003b3e : None, #--Gho
        0x00424a : 0x05dc78, #--Afr
        0x0042be : 0x05a59e, #--AfC
        0x0042bf : 0x072e39, #--AfO
        0x0042c0 : 0x05a5a3, #--AsC
        0x0042c1 : 0x072e39, #--AsO
        0x0042c2 : 0x05a59e, #--CaC
        0x0042c3 : 0x072e39, #--CaO
        0x0042c4 : 0x05a59e, #--HiC
        0x0042c5 : 0x072e39, #--HiO
        0x04bb8d : 0x072e39, #--CaR
        0x04bf70 : 0x072e39, #--HiR
        0x04bf71 : 0x072e39, #--AsR
        0x04bf72 : 0x072e39, #--AfR
        0x0987dc : 0x044529, #--HOA
        0x0987dd : 0x044529, #--AOA
        0x0987de : 0x044529, #--FOA
        0x0987df : 0x044529, #--COA
        }

    @classmethod
    def init(cls):
        cls._dynamic_import_modules(__name__)
        from .records import MreActi, MreAddn, MreAlch, MreAmmo, MreAnio, \
            MreArma, MreArmo, MreAspc, MreAvif, MreBook, MreBptd, MreCams, \
            MreClas, MreClmt, MreCobj, MreCont, MreCpth, MreCrea, MreCsty, \
            MreDebr, MreDobj, MreDoor, MreEczn, MreEfsh, MreEnch, MreExpl, \
            MreEyes, MreFact, MreFurn, MreGras, MreHair, MreHdpt, MreTes4, \
            MreIdle, MreIdlm, MreImad, MreImgs, MreIngr, MreIpct, MreIpds, \
            MreKeym, MreLgtm, MreLigh, MreLscr, MreLtex, MreLvlc, MreLvli, \
            MreLvln, MreMesg, MreMgef, MreMicn, MreMisc, MreMstt, MreMusc, \
            MreNote, MreNpc, MrePack, MrePerk, MreProj, MrePwat, MreQust, \
            MreRace, MreRads, MreRegn, MreRgdl, MreScol, MreScpt, MreSoun, \
            MreSpel, MreStat, MreTact, MreTerm, MreTree, MreTxst, MreVtyp, \
            MreWatr, MreWeap, MreWthr, MreAchr, MreAcre, MreCell, MreDial, \
            MreGmst, MreInfo, MreNavi, MreNavm, MrePgre, MrePmis, MreRefr, \
            MreWrld
        cls.mergeClasses = (
            MreActi, MreAddn, MreAlch, MreAmmo, MreAnio, MreArma, MreArmo,
            MreAspc, MreAvif, MreBook, MreBptd, MreCams, MreClas, MreClmt,
            MreCobj, MreCont, MreCpth, MreCrea, MreCsty, MreDebr, MreDobj,
            MreDoor, MreEczn, MreEfsh, MreEnch, MreExpl, MreEyes, MreFact,
            MreFlst, MreFurn, MreGlob, MreGras, MreHair, MreHdpt, MreIdle,
            MreIdlm, MreImad, MreImgs, MreIngr, MreIpct, MreIpds, MreKeym,
            MreLgtm, MreLigh, MreLscr, MreLtex, MreLvlc, MreLvli, MreLvln,
            MreMesg, MreMgef, MreMicn, MreMisc, MreMstt, MreMusc, MreNote,
            MreNpc, MrePack, MrePerk, MreProj, MrePwat, MreQust, MreRace,
            MreRads, MreRegn, MreRgdl, MreScol, MreScpt, MreSoun, MreSpel,
            MreStat, MreTact,MreTerm, MreTree, MreTxst, MreVtyp, MreWatr,
            MreWeap, MreWthr, MreGmst,
            )
        # Setting RecordHeader class variables --------------------------------
        header_type = brec.RecordHeader
        header_type.top_grup_sigs = [
            b'GMST', b'TXST', b'MICN', b'GLOB', b'CLAS', b'FACT', b'HDPT',
            b'HAIR', b'EYES', b'RACE', b'SOUN', b'ASPC', b'MGEF', b'SCPT',
            b'LTEX', b'ENCH', b'SPEL', b'ACTI', b'TACT', b'TERM', b'ARMO',
            b'BOOK', b'CONT', b'DOOR', b'INGR', b'LIGH', b'MISC', b'STAT',
            b'SCOL', b'MSTT', b'PWAT', b'GRAS', b'TREE', b'FURN', b'WEAP',
            b'AMMO', b'NPC_', b'CREA', b'LVLC', b'LVLN', b'KEYM', b'ALCH',
            b'IDLM', b'NOTE', b'PROJ', b'LVLI', b'WTHR', b'CLMT', b'COBJ',
            b'REGN', b'NAVI', b'CELL', b'WRLD', b'DIAL', b'QUST', b'IDLE',
            b'PACK', b'CSTY', b'LSCR', b'ANIO', b'WATR', b'EFSH', b'EXPL',
            b'DEBR', b'IMGS', b'IMAD', b'FLST', b'PERK', b'BPTD', b'ADDN',
            b'AVIF', b'RADS', b'CAMS', b'CPTH', b'VTYP', b'IPCT', b'IPDS',
            b'ARMA', b'ECZN', b'MESG', b'RGDL', b'DOBJ', b'LGTM', b'MUSC',
        ]
        header_type.valid_header_sigs = set(
            header_type.top_grup_sigs + [b'GRUP', b'TES4', b'ACHR', b'ACRE',
                                         b'INFO', b'LAND', b'NAVM', b'PGRE',
                                         b'PMIS', b'REFR'])
        header_type.plugin_form_version = 15
        brec.MreRecord.type_class = {x.rec_sig: x for x in
                (cls.mergeClasses + # Not Mergeable
                (MreAchr, MreAcre, MreCell, MreDial, MreInfo, MreNavi,
                 MreNavm, MrePgre, MrePmis, MreRefr, MreWrld, MreTes4))}
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) - {
            b'TES4', b'ACHR', b'ACRE', b'CELL', b'DIAL', b'INFO', b'LAND',
            b'NAVI', b'NAVM', b'PGRE', b'PMIS', b'REFR', b'WRLD'})
        cls._validate_records()
Example #17
0
class SkyrimGameInfo(PatchGame):
    displayName = u'Skyrim'
    fsName = u'Skyrim'
    altName = u'Wrye Smash'
    game_icon = u'skyrim_%u.png'
    bash_root_prefix = u'Skyrim'
    bak_game_name = u'Skyrim'
    my_games_name = u'Skyrim'
    appdata_name = u'Skyrim'
    launch_exe = u'TESV.exe'
    # Set to this because TESV.exe also exists for Enderal
    game_detect_includes = [u'SkyrimLauncher.exe']
    version_detect_file = u'TESV.exe'
    master_file = u'Skyrim.esm'
    taglist_dir = u'Skyrim'
    loot_dir = u'Skyrim'
    boss_game_name = u'Skyrim'
    regInstallKeys = (u'Bethesda Softworks\\Skyrim', u'Installed Path')
    nexusUrl = u'https://www.nexusmods.com/skyrim/'
    nexusName = u'Skyrim Nexus'
    nexusKey = u'bash.installers.openSkyrimNexus.continue'

    plugin_name_specific_dirs = GameInfo.plugin_name_specific_dirs + [
        _j(u'meshes', u'actors', u'character', u'facegendata', u'facegeom'),
        _j(u'textures', u'actors', u'character', u'facegendata', u'facetint')]

    class Ck(GameInfo.Ck):
        ck_abbrev = u'CK'
        long_name = u'Creation Kit'
        exe = u'CreationKit.exe'
        image_name = u'creationkit%s.png'

    class Se(GameInfo.Se):
        se_abbrev = u'SKSE'
        long_name = u'Skyrim Script Extender'
        exe = u'skse_loader.exe'
        ver_files = [u'skse_loader.exe', u'skse_steam_loader.dll']
        plugin_dir = u'SKSE'
        cosave_tag = u'SKSE'
        cosave_ext = u'.skse'
        url = u'http://skse.silverlock.org/'
        url_tip = u'http://skse.silverlock.org/'

    class Sd(GameInfo.Sd):
        sd_abbrev = u'SD'
        long_name = u'Script Dragon'
        install_dir = u'asi'

    class Sp(GameInfo.Sp):
        sp_abbrev = u'SP'
        long_name = u'SkyProc'
        install_dir = u'SkyProc Patchers'

    class Ini(GameInfo.Ini):
        default_ini_file = u'Skyrim_default.ini'
        dropdown_inis = [u'Skyrim.ini', u'SkyrimPrefs.ini']
        resource_archives_keys = (u'sResourceArchiveList',
                                  u'sResourceArchiveList2')

    class Bsa(GameInfo.Bsa):
        # Skyrim only accepts the base name
        attachment_regex = u''
        has_bsl = True
        valid_versions = {0x68}

    class Psc(GameInfo.Psc):
        source_extensions = {u'.psc'}
        # In SSE Bethesda made the mistake of packaging the CK's script source
        # as 'source/scripts' instead of 'scripts/source'. The CK even still
        # expects the sources to be in 'scripts/source', so you'd have to edit
        # its INI if you wanted to use 'source/scripts'. However, some modders
        # have nonetheless adopted this convention, so to support this we
        # redirect them to the correct path while scanning the package in BAIN.
        # Sits here because the situation then got worse - some modders have
        # started packaging 'source' dirs even in Skyrim LE.
        source_redirects = {
            _j(u'source', u'scripts'): _j(u'scripts', u'source'),
            u'source': _j(u'scripts', u'source'),
        }

    class Xe(GameInfo.Xe):
        full_name = u'TES5Edit'
        xe_key_prefix = u'tes5View'

    class Bain(GameInfo.Bain):
        data_dirs = GameInfo.Bain.data_dirs | {
            u'asi', # script dragon
            u'calientetools', # bodyslide
            u'dialogueviews',
            u'dyndolod',
            u'grass',
            u'interface',
            u'lodsettings',
            u'scripts',
            u'seq',
            u'shadersfx',
            u'skse',
            u'skyproc patchers',
            u'slanims', # nsfw mods
            u'source', # see Psc.source_redirects above
            u'strings',
            u'tools', # FNIS
        }
        keep_data_dirs = {u'LSData'}
        no_skip = (
            # These are all in the Interface folder. Apart from the skyui_
            # files, they are all present in vanilla.
            u'skyui_cfg.txt',
            u'skyui_translate.txt',
            u'credits.txt',
            u'credits_french.txt',
            u'fontconfig.txt',
            u'controlmap.txt',
            u'gamepad.txt',
            u'mouse.txt',
            u'keyboard_english.txt',
            u'keyboard_french.txt',
            u'keyboard_german.txt',
            u'keyboard_spanish.txt',
            u'keyboard_italian.txt',
        )
        no_skip_dirs = GameInfo.Bain.no_skip_dirs.copy() # PY3: dict join
        no_skip_dirs.update({
            # This rule is to allow mods with string translation enabled.
            _j(u'interface', u'translations'): [u'.txt']
        })
        skip_bain_refresh = {u'tes5edit backups', u'tes5edit cache'}

    class Esp(GameInfo.Esp):
        canBash = True
        canEditHeader = True
        validHeaderVersions = (0.94, 1.70,)
        generate_temp_child_onam = True
        max_lvl_list_size = 255
        biped_flag_names = (
            u'head', u'hair', u'body', u'hands', u'forearms', u'amulet',
            u'ring', u'feet', u'calves', u'shield', u'bodyaddon1_tail',
            u'long_hair', u'circlet', u'bodyaddon2', u'dragon_head',
            u'dragon_lwing', u'dragon_rwing', u'dragon_body', u'bodyaddon7',
            u'bodyaddon8', u'decapate_head', u'decapate', u'bodyaddon9',
            u'bodyaddon10', u'bodyaddon11', u'bodyaddon12', u'bodyaddon13',
            u'bodyaddon14', u'bodyaddon15', u'bodyaddon16', u'bodyaddon17',
            u'fx01')
        reference_types = {b'ACHR', b'PARW', b'PBAR', b'PBEA', b'PCON',
                           b'PFLA', b'PGRE', b'PHZD', b'PMIS', b'REFR'}

    allTags = PatchGame.allTags | {u'NoMerge'}

    patchers = {
        u'AliasModNames', u'ContentsChecker', u'ImportActors', u'ImportRaces',
        u'ImportActorsAIPackages', u'ImportActorsDeathItems',
        u'ImportActorsFactions', u'ImportActorsSpells', u'ImportCells',
        u'ImportDestructible', u'ImportEffectsStats', u'ImportRacesSpells',
        u'ImportEnchantmentStats', u'ImportGraphics', u'ImportInventory',
        u'ImportKeywords', u'ImportNames', u'ImportObjectBounds',
        u'ImportOutfits', u'ImportRelations', u'ImportSounds',
        u'ImportSpellStats', u'ImportStats', u'ImportText', u'LeveledLists',
        u'MergePatches', u'TweakActors', u'TweakAssorted', u'TweakSettings',
        u'TweakRaces', u'ImportActorsPerks', u'TimescaleChecker',
    }

    weaponTypes = (
        _(u'Blade (1 Handed)'),
        _(u'Blade (2 Handed)'),
        _(u'Blunt (1 Handed)'),
        _(u'Blunt (2 Handed)'),
        _(u'Staff'),
        _(u'Bow'),
        )

    raceNames = {
        0x13740 : _(u'Argonian'),
        0x13741 : _(u'Breton'),
        0x13742 : _(u'Dark Elf'),
        0x13743 : _(u'High Elf'),
        0x13744 : _(u'Imperial'),
        0x13745 : _(u'Khajiit'),
        0x13746 : _(u'Nord'),
        0x13747 : _(u'Orc'),
        0x13748 : _(u'Redguard'),
        0x13749 : _(u'Wood Elf'),
        }
    raceShortNames = {
        0x13740 : u'Arg',
        0x13741 : u'Bre',
        0x13742 : u'Dun',
        0x13743 : u'Alt',
        0x13744 : u'Imp',
        0x13745 : u'Kha',
        0x13746 : u'Nor',
        0x13747 : u'Orc',
        0x13748 : u'Red',
        0x13749 : u'Bos',
        }
    raceHairMale = {
        0x13740 : 0x64f32, #--Arg
        0x13741 : 0x90475, #--Bre
        0x13742 : 0x64214, #--Dun
        0x13743 : 0x7b792, #--Alt
        0x13744 : 0x90475, #--Imp
        0x13745 : 0x653d4, #--Kha
        0x13746 : 0x1da82, #--Nor
        0x13747 : 0x66a27, #--Orc
        0x13748 : 0x64215, #--Red
        0x13749 : 0x690bc, #--Bos
        }
    raceHairFemale = {
        0x13740 : 0x64f33, #--Arg
        0x13741 : 0x1da83, #--Bre
        0x13742 : 0x1da83, #--Dun
        0x13743 : 0x690c2, #--Alt
        0x13744 : 0x1da83, #--Imp
        0x13745 : 0x653d0, #--Kha
        0x13746 : 0x1da83, #--Nor
        0x13747 : 0x64218, #--Orc
        0x13748 : 0x64210, #--Red
        0x13749 : 0x69473, #--Bos
        }

    bethDataFiles = {
        #--Vanilla
        u'skyrim.esm',
        u'update.esm',
        u'update.bsa',
        u'dawnguard.esm',
        u'dawnguard.bsa',
        u'hearthfires.bsa',
        u'hearthfires.esm',
        u'dragonborn.esm',
        u'dragonborn.bsa',
        u'skyrim - animations.bsa',
        u'skyrim - interface.bsa',
        u'skyrim - meshes.bsa',
        u'skyrim - misc.bsa',
        u'skyrim - shaders.bsa',
        u'skyrim - sounds.bsa',
        u'skyrim - textures.bsa',
        u'skyrim - voices.bsa',
        u'skyrim - voicesextra.bsa',
        u'highrestexturepack01.esp',
        u'highrestexturepack02.esp',
        u'highrestexturepack03.esp',
        u'highrestexturepack01.bsa',
        u'highrestexturepack02.bsa',
        u'highrestexturepack03.bsa',
    }

    _patcher_package = u'bash.game.skyrim'
    @classmethod
    def init(cls):
        cls._dynamic_import_modules(__name__)
        from .records import MreCell, MreWrld, MreFact, MreAchr, MreDial, \
            MreInfo, MreCams, MreWthr, MreDual, MreMato, MreVtyp, MreMatt, \
            MreLvsp, MreEnch, MreProj, MreDlbr, MreRfct, MreMisc, MreActi, \
            MreEqup, MreCpth, MreDoor, MreAnio, MreHazd, MreIdlm, MreEczn, \
            MreIdle, MreLtex, MreQust, MreMstt, MreNpc, MreIpds, MrePack, \
            MreGmst, MreRevb, MreClmt, MreDebr, MreSmbn, MreLvli, MreSpel, \
            MreKywd, MreLvln, MreAact, MreSlgm, MreRegn, MreFurn, MreGras, \
            MreAstp, MreWoop, MreMovt, MreCobj, MreShou, MreSmen, MreColl, \
            MreArto, MreAddn, MreSopm, MreCsty, MreAppa, MreArma, MreArmo, \
            MreKeym, MreTxst, MreHdpt, MreTes4, MreAlch, MreBook, MreSpgd, \
            MreSndr, MreImgs, MreScrl, MreMust, MreFstp, MreFsts, MreMgef, \
            MreLgtm, MreMusc, MreClas, MreLctn, MreTact, MreBptd, MreDobj, \
            MreLscr, MreDlvw, MreTree, MreWatr, MreFlor, MreEyes, MreWeap, \
            MreIngr, MreClfm, MreMesg, MreLigh, MreExpl, MreLcrt, MreStat, \
            MreAmmo, MreSmqn, MreImad, MreSoun, MreAvif, MreCont, MreIpct, \
            MreAspc, MreRela, MreEfsh, MreSnct, MreOtft, MrePerk, MreRace
        # ---------------------------------------------------------------------
        # Unused records, they have empty GRUP in skyrim.esm-------------------
        # CLDC HAIR PWAT RGDL SCOL SCPT
        # ---------------------------------------------------------------------
        # These Are normally not mergeable but added to brec.MreRecord.type_class
        #
        #       MreCell,
        # ---------------------------------------------------------------------
        # These have undefined FormIDs Do not merge them
        #
        #       MreNavi, MreNavm,
        # ---------------------------------------------------------------------
        # These need syntax revision but can be merged once that is corrected
        #
        #       MreAchr, MreDial, MreInfo,
        # ---------------------------------------------------------------------
        cls.mergeable_sigs = {clazz.rec_sig: clazz for clazz in (# MreAchr, MreDial, MreInfo,
            MreAact, MreActi, MreAddn, MreAlch, MreAmmo, MreAnio, MreAppa,
            MreArma, MreArmo, MreArto, MreAspc, MreAstp, MreAvif, MreBook,
            MreBptd, MreCams, MreClas, MreClfm, MreClmt, MreCobj, MreColl,
            MreCont, MreCpth, MreCsty, MreDebr, MreDlbr, MreDlvw, MreDobj,
            MreDoor, MreDual, MreEczn, MreEfsh, MreEnch, MreEqup, MreExpl,
            MreEyes, MreFlor, MreFlst, MreFstp, MreFsts, MreFurn, MreGlob,
            MreGmst, MreGras, MreHazd, MreHdpt, MreIdle, MreIdlm, MreImad,
            MreImgs, MreIngr, MreIpct, MreIpds, MreKeym, MreKywd, MreLcrt,
            MreLctn, MreLgtm, MreLigh, MreLscr, MreLtex, MreLvli, MreLvln,
            MreLvsp, MreMato, MreMatt, MreMesg, MreMgef, MreMisc, MreMovt,
            MreMstt, MreMusc, MreMust, MreNpc, MreOtft, MrePerk, MreProj,
            MreRegn, MreRela, MreRevb, MreRfct, MreScrl, MreShou, MreSlgm,
            MreSmbn, MreSmen, MreSmqn, MreSnct, MreSndr, MreSopm, MreSoun,
            MreSpel, MreSpgd, MreStat, MreTact, MreTree, MreTxst, MreVtyp,
            MreWatr, MreWeap, MreWoop, MreWthr, MreQust, MrePack, MreFact,
            MreRace,
        )}

        # MreScpt is Oblivion/FO3/FNV Only
        # MreMgef, has not been verified to be used here for Skyrim

        # Setting RecordHeader class variables --------------------------------
        header_type = brec.RecordHeader
        header_type.top_grup_sigs = [
            b'GMST', b'KYWD', b'LCRT', b'AACT', b'TXST', b'GLOB', b'CLAS',
            b'FACT', b'HDPT', b'HAIR', b'EYES', b'RACE', b'SOUN', b'ASPC',
            b'MGEF', b'SCPT', b'LTEX', b'ENCH', b'SPEL', b'SCRL', b'ACTI',
            b'TACT', b'ARMO', b'BOOK', b'CONT', b'DOOR', b'INGR', b'LIGH',
            b'MISC', b'APPA', b'STAT', b'SCOL', b'MSTT', b'PWAT', b'GRAS',
            b'TREE', b'CLDC', b'FLOR', b'FURN', b'WEAP', b'AMMO', b'NPC_',
            b'LVLN', b'KEYM', b'ALCH', b'IDLM', b'COBJ', b'PROJ', b'HAZD',
            b'SLGM', b'LVLI', b'WTHR', b'CLMT', b'SPGD', b'RFCT', b'REGN',
            b'NAVI', b'CELL', b'WRLD', b'DIAL', b'QUST', b'IDLE', b'PACK',
            b'CSTY', b'LSCR', b'LVSP', b'ANIO', b'WATR', b'EFSH', b'EXPL',
            b'DEBR', b'IMGS', b'IMAD', b'FLST', b'PERK', b'BPTD', b'ADDN',
            b'AVIF', b'CAMS', b'CPTH', b'VTYP', b'MATT', b'IPCT', b'IPDS',
            b'ARMA', b'ECZN', b'LCTN', b'MESG', b'RGDL', b'DOBJ', b'LGTM',
            b'MUSC', b'FSTP', b'FSTS', b'SMBN', b'SMQN', b'SMEN', b'DLBR',
            b'MUST', b'DLVW', b'WOOP', b'SHOU', b'EQUP', b'RELA', b'SCEN',
            b'ASTP', b'OTFT', b'ARTO', b'MATO', b'MOVT', b'SNDR', b'DUAL',
            b'SNCT', b'SOPM', b'COLL', b'CLFM', b'REVB',
        ]
        header_type.valid_header_sigs = set(
            header_type.top_grup_sigs + [b'GRUP', b'TES4', b'REFR', b'ACHR',
                                         b'ACRE', b'LAND', b'INFO', b'NAVM',
                                         b'PARW', b'PBAR', b'PBEA', b'PCON',
                                         b'PFLA', b'PGRE', b'PHZD', b'PMIS'])
        header_type.plugin_form_version = 43
        brec.MreRecord.type_class = {x.rec_sig: x for x in (
            MreAchr, MreDial, MreInfo, MreAact, MreActi, MreAddn, MreAlch,
            MreAmmo, MreAnio, MreAppa, MreArma, MreArmo, MreArto, MreAspc,
            MreAstp, MreAvif, MreBook, MreBptd, MreCams, MreClas, MreClfm,
            MreClmt, MreCobj, MreColl, MreCont, MreCpth, MreCsty, MreDebr,
            MreDlbr, MreDlvw, MreDobj, MreDoor, MreDual, MreEczn, MreEfsh,
            MreEnch, MreEqup, MreExpl, MreEyes, MreFact, MreFlor, MreFlst,
            MreFstp, MreFsts, MreFurn, MreGlob, MreGmst, MreGras, MreHazd,
            MreHdpt, MreIdle, MreIdlm, MreImad, MreImgs, MreIngr, MreIpct,
            MreIpds, MreKeym, MreKywd, MreLcrt, MreLctn, MreLgtm, MreLigh,
            MreLscr, MreLtex, MreLvli, MreLvln, MreLvsp, MreMato, MreMatt,
            MreMesg, MreMgef, MreMisc, MreMovt, MreMstt, MreMusc, MreMust,
            MreNpc, MreOtft, MrePerk, MreProj, MreRegn, MreRela, MreRevb,
            MreRfct, MreScrl, MreShou, MreSlgm, MreSmbn, MreSmen, MreSmqn,
            MreSnct, MreSndr, MreSopm, MreSoun, MreSpel, MreSpgd, MreStat,
            MreTact, MreTree, MreTxst, MreVtyp, MreWatr, MreWeap, MreWoop,
            MreWthr, MreCell, MreWrld, MreQust, MreTes4, MrePack, MreRace,
            # MreNavm, MreNavi
        )}
        brec.MreRecord.simpleTypes = (
                set(brec.MreRecord.type_class) - {b'TES4', b'ACHR', b'CELL',
                                                  b'DIAL', b'INFO', b'WRLD'})
        cls._validate_records()
Example #18
0
class NehrimGameInfo(OblivionGameInfo):
    displayName = u'Nehrim'
    bash_root_prefix = u'Nehrim'
    game_detect_file = _j(u'Data', u'Nehrim.esm')
    master_file = u'Nehrim.esm'
    #    pklfile = u'Nehrim_ids.pkl' # TODO new pickle
    nexusUrl = u'https://www.nexusmods.com/nehrim/'
    nexusName = u'Nehrim Nexus'
    nexusKey = u'bash.installers.openNehrimNexus.continue'

    # Oblivion minus Oblivion-specific patchers (Cobl Catalogs, Cobl
    # Exhaustion, Morph Factions and SEWorld Tests)
    patchers = tuple(p for p in OblivionGameInfo.patchers
                     if p not in (u'AlchemicalCatalogs', u'CoblExhaustion',
                                  u'MFactMarker', u'SEWorldEnforcer'))
    CBash_patchers = tuple(
        p for p in OblivionGameInfo.CBash_patchers
        if p not in (u'CBash_AlchemicalCatalogs', u'CBash_CoblExhaustion',
                     u'CBash_MFactMarker', u'CBash_SEWorldEnforcer'))

    raceNames = {
        0x224fc: _(u'Alemanne'),
        0x18d9e5: _(u'Half-Aeterna'),
        0x224fd: _(u'Normanne'),
    }
    raceShortNames = {
        0x224fc: u'Ale',
        0x18d9e5: u'Aet',
        0x224fd: u'Nor',
    }
    raceHairMale = {
        0x224fc: 0x90475,  #--Ale
        0x18d9e5: 0x5c6b,  #--Aet
        0x224fd: 0x1da82,  #--Nor
    }
    raceHairFemale = {
        0x224fc: 0x1da83,  #--Ale
        0x18d9e5: 0x3e1e,  #--Aet
        0x224fd: 0x1da83,  #--Nor
    }

    @classmethod
    def init(cls):
        cls._dynamic_import_modules(__name__)
        from .records import MreActi, MreAlch, MreAmmo, MreAnio, MreAppa, \
            MreArmo, MreBook, MreBsgn, MreClas, MreClot, MreCont, MreCrea, \
            MreDoor, MreEfsh, MreEnch, MreEyes, MreFact, MreFlor, MreFurn, \
            MreGras, MreHair, MreIngr, MreKeym, MreLigh, MreLscr, MreLvlc, \
            MreLvli, MreLvsp, MreMgef, MreMisc, MreNpc, MrePack, MreQust, \
            MreRace, MreScpt, MreSgst, MreSlgm, MreSoun, MreSpel, MreStat, \
            MreTree, MreWatr, MreWeap, MreWthr, MreClmt, MreCsty, MreIdle, \
            MreLtex, MreRegn, MreSbsp, MreSkil, MreAchr, MreAcre, MreCell, \
            MreGmst, MreRefr, MreRoad, MreTes4, MreWrld, MreDial, MreInfo, \
            MrePgrd
        cls.mergeClasses = (
            MreActi,
            MreAlch,
            MreAmmo,
            MreAnio,
            MreAppa,
            MreArmo,
            MreBook,
            MreBsgn,
            MreClas,
            MreClot,
            MreCont,
            MreCrea,
            MreDoor,
            MreEfsh,
            MreEnch,
            MreEyes,
            MreFact,
            MreFlor,
            MreFurn,
            MreGlob,
            MreGras,
            MreHair,
            MreIngr,
            MreKeym,
            MreLigh,
            MreLscr,
            MreLvlc,
            MreLvli,
            MreLvsp,
            MreMgef,
            MreMisc,
            MreNpc,
            MrePack,
            MreQust,
            MreRace,
            MreScpt,
            MreSgst,
            MreSlgm,
            MreSoun,
            MreSpel,
            MreStat,
            MreTree,
            MreWatr,
            MreWeap,
            MreWthr,
            MreClmt,
            MreCsty,
            MreIdle,
            MreLtex,
            MreRegn,
            MreSbsp,
            MreSkil,
            MreAchr,
            MreAcre,
            MreCell,
            MreGmst,
            MreRefr,
            MreRoad,
            MreWrld,
            MreDial,
            MreInfo,
            MreLand,
            MrePgrd,
        )
        cls.readClasses = (
            MreMgef,
            MreScpt,
        )
        cls.writeClasses = (MreMgef, )
        # Setting RecordHeader class variables - Oblivion is special
        header_type = brec.RecordHeader
        header_type.rec_header_size = 20
        header_type.rec_pack_format = [u'=4s', u'I', u'I', u'I', u'I']
        header_type.rec_pack_format_str = u''.join(header_type.rec_pack_format)
        header_type.header_unpack = struct.Struct(
            header_type.rec_pack_format_str).unpack
        header_type.pack_formats = {0: u'=4sI4s2I'}
        header_type.pack_formats.update(
            {x: u'=4s4I'
             for x in {1, 6, 7, 8, 9, 10}})
        header_type.pack_formats.update({x: u'=4sIi2I' for x in {2, 3}})
        header_type.pack_formats.update({x: u'=4sIhh2I' for x in {4, 5}})
        # Similar to other games
        header_type.top_grup_sigs = [
            b'GMST',
            b'GLOB',
            b'CLAS',
            b'FACT',
            b'HAIR',
            b'EYES',
            b'RACE',
            b'SOUN',
            b'SKIL',
            b'MGEF',
            b'SCPT',
            b'LTEX',
            b'ENCH',
            b'SPEL',
            b'BSGN',
            b'ACTI',
            b'APPA',
            b'ARMO',
            b'BOOK',
            b'CLOT',
            b'CONT',
            b'DOOR',
            b'INGR',
            b'LIGH',
            b'MISC',
            b'STAT',
            b'GRAS',
            b'TREE',
            b'FLOR',
            b'FURN',
            b'WEAP',
            b'AMMO',
            b'NPC_',
            b'CREA',
            b'LVLC',
            b'SLGM',
            b'KEYM',
            b'ALCH',
            b'SBSP',
            b'SGST',
            b'LVLI',
            b'WTHR',
            b'CLMT',
            b'REGN',
            b'CELL',
            b'WRLD',
            b'DIAL',
            b'QUST',
            b'IDLE',
            b'PACK',
            b'CSTY',
            b'LSCR',
            b'LVSP',
            b'ANIO',
            b'WATR',
            b'EFSH',
        ]
        header_type.valid_header_sigs = set(header_type.top_grup_sigs + [
            b'GRUP', b'TES4', b'ROAD', b'REFR', b'ACHR', b'ACRE', b'PGRD',
            b'LAND', b'INFO'
        ])
        brec.MreRecord.type_class = {
            x.rec_sig: x
            for x in (MreAchr, MreAcre, MreActi, MreAlch, MreAmmo, MreAnio,
                      MreAppa, MreArmo, MreBook, MreBsgn, MreCell, MreClas,
                      MreClot, MreCont, MreCrea, MreDoor, MreEfsh, MreEnch,
                      MreEyes, MreFact, MreFlor, MreFurn, MreGlob, MreGmst,
                      MreGras, MreHair, MreIngr, MreKeym, MreLigh, MreLscr,
                      MreLvlc, MreLvli, MreLvsp, MreMgef, MreMisc, MreNpc,
                      MrePack, MreQust, MreRace, MreRefr, MreRoad, MreScpt,
                      MreSgst, MreSkil, MreSlgm, MreSoun, MreSpel, MreStat,
                      MreTree, MreTes4, MreWatr, MreWeap, MreWrld, MreWthr,
                      MreClmt, MreCsty, MreIdle, MreLtex, MreRegn, MreSbsp,
                      MreDial, MreInfo, MreLand, MrePgrd)
        }
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) - {
            b'TES4', b'ACHR', b'ACRE', b'REFR', b'CELL', b'PGRD', b'ROAD',
            b'LAND', b'WRLD', b'INFO', b'DIAL'
        })
        cls._validate_records()
Example #19
0
class Fallout4GameInfo(GameInfo):
    displayName = u'Fallout 4'
    fsName = u'Fallout4'
    altName = u'Wrye Flash'
    bash_root_prefix = u'Fallout4'
    launch_exe = u'Fallout4.exe'
    game_detect_file = u'Fallout4.exe'
    version_detect_file = u'Fallout4.exe'
    master_file = u'Fallout4.esm'
    pklfile = u'Fallout4_ids.pkl'
    masterlist_dir = u'Fallout4'
    regInstallKeys = (u'Bethesda Softworks\\Fallout4', u'Installed Path')
    nexusUrl = u'https://www.nexusmods.com/fallout4/'
    nexusName = u'Fallout 4 Nexus'
    nexusKey = 'bash.installers.openFallout4Nexus.continue'

    espm_extensions = GameInfo.espm_extensions | {u'.esl'}
    has_achlist = True
    check_esl = True
    plugin_name_specific_dirs = GameInfo.plugin_name_specific_dirs + [
        _j(u'meshes', u'actors', u'character', u'facegendata', u'facegeom'),
        _j(u'meshes', u'actors', u'character', u'facecustomization')
    ]

    class Ck(GameInfo.Ck):
        ck_abbrev = u'CK'
        long_name = u'Creation Kit'
        exe = u'CreationKit.exe'
        image_name = u'creationkit%s.png'

    class Se(GameInfo.Se):
        se_abbrev = u'F4SE'
        long_name = u'Fallout 4 Script Extender'
        exe = u'f4se_loader.exe'
        ver_files = [u'f4se_loader.exe', u'f4se_steam_loader.dll']
        plugin_dir = u'F4SE'
        cosave_tag = u'F4SE'
        cosave_ext = u'.f4se'
        url = u'http://f4se.silverlock.org/'
        url_tip = u'http://f4se.silverlock.org/'

    class Ini(GameInfo.Ini):
        default_ini_file = u'Fallout4_default.ini'
        dropdown_inis = [u'Fallout4.ini', u'Fallout4Prefs.ini']
        resource_archives_keys = (u'sResourceIndexFileList',
                                  u'sResourceStartUpArchiveList',
                                  u'sResourceArchiveList',
                                  u'sResourceArchiveList2',
                                  u'sResourceArchiveListBeta')

    class Ess(GameInfo.Ess):
        ext = u'.fos'

    class Bsa(GameInfo.Bsa):
        bsa_extension = u'.ba2'
        valid_versions = {0x01}
        vanilla_string_bsas = {
            u'fallout4.esm': [u'Fallout4 - Interface.ba2'],
            u'dlcrobot.esm': [u'DLCRobot - Main.ba2'],
            u'dlcworkshop01.esm': [u'DLCworkshop01 - Main.ba2'],
            u'dlcworkshop02.esm': [u'DLCworkshop02 - Main.ba2'],
            u'dlcworkshop03.esm': [u'DLCworkshop03 - Main.ba2'],
            u'dlccoast.esm': [u'DLCCoast - Main.ba2'],
            u'dlcnukaworld.esm': [u'DLCNukaWorld - Main.ba2'],
        }

    class Psc(GameInfo.Psc):
        source_extensions = {u'.psc'}

    class Xe(GameInfo.Xe):
        full_name = u'FO4Edit'
        xe_key_prefix = u'fo4View'

    class Bain(GameInfo.Bain):
        data_dirs = GameInfo.Bain.data_dirs | {
            u'f4se',
            u'interface',
            u'lodsettings',
            u'materials',
            u'mcm',  # FO4 MCM
            u'misc',
            u'programs',
            u'scripts',
            u'seq',
            u'shadersfx',
            u'strings',
            u'tools',  # bodyslide
            u'vis',
        }
        no_skip_dirs = {
            # This rule is to allow mods with string translation enabled.
            _j(u'interface', u'translations'): [u'.txt']
        }
        skip_bain_refresh = {u'fo4edit backups', u'fo4edit cache'}

    class Esp(GameInfo.Esp):
        canBash = True
        canEditHeader = True
        validHeaderVersions = (0.95, 1.0)
        expanded_plugin_range = True
        max_lvl_list_size = 255

    allTags = {
        u'Deactivate',
        u'Delev',
        u'Filter',
        u'ObjectBounds',
        u'Relev',
    }

    patchers = (  # PatchMerger must come first if enabled!
        u'ListsMerger',
        u'ObjectBoundsImporter',
    )

    # ---------------------------------------------------------------------
    # --Imported - MreGlob is special import, not in records.py
    # ---------------------------------------------------------------------
    @classmethod
    def init(cls):
        cls._dynamic_import_modules(__name__)
        # First import from fallout4.records file, so MelModel is set correctly
        from .records import MreGmst, MreTes4, MreLvli, MreLvln
        # ---------------------------------------------------------------------
        # These Are normally not mergable but added to brec.MreRecord.type_class
        #
        #       MreCell,
        # ---------------------------------------------------------------------
        # These have undefined FormIDs Do not merge them
        #
        #       MreNavi, MreNavm,
        # ---------------------------------------------------------------------
        # These need syntax revision but can be merged once that is corrected
        #
        #       MreAchr, MreDial, MreLctn, MreInfo, MreFact, MrePerk,
        # ---------------------------------------------------------------------
        cls.mergeClasses = (
            # -- Imported from Skyrim/SkyrimSE
            # Added to records.py
            MreGmst,
            MreLvli,
            MreLvln)
        # Setting RecordHeader class variables --------------------------------
        header_type = brec.RecordHeader
        header_type.top_grup_sigs = [
            b'GMST',
            b'KYWD',
            b'LCRT',
            b'AACT',
            b'TRNS',
            b'CMPO',
            b'TXST',
            b'GLOB',
            b'DMGT',
            b'CLAS',
            b'FACT',
            b'HDPT',
            b'RACE',
            b'SOUN',
            b'ASPC',
            b'MGEF',
            b'LTEX',
            b'ENCH',
            b'SPEL',
            b'ACTI',
            b'TACT',
            b'ARMO',
            b'BOOK',
            b'CONT',
            b'DOOR',
            b'INGR',
            b'LIGH',
            b'MISC',
            b'STAT',
            b'SCOL',
            b'MSTT',
            b'GRAS',
            b'TREE',
            b'FLOR',
            b'FURN',
            b'WEAP',
            b'AMMO',
            b'NPC_',
            b'PLYR',
            b'LVLN',
            b'KEYM',
            b'ALCH',
            b'IDLM',
            b'NOTE',
            b'PROJ',
            b'HAZD',
            b'BNDS',
            b'TERM',
            b'LVLI',
            b'WTHR',
            b'CLMT',
            b'SPGD',
            b'RFCT',
            b'REGN',
            b'NAVI',
            b'CELL',
            b'WRLD',
            b'QUST',
            b'IDLE',
            b'PACK',
            b'CSTY',
            b'LSCR',
            b'LVSP',
            b'ANIO',
            b'WATR',
            b'EFSH',
            b'EXPL',
            b'DEBR',
            b'IMGS',
            b'IMAD',
            b'FLST',
            b'PERK',
            b'BPTD',
            b'ADDN',
            b'AVIF',
            b'CAMS',
            b'CPTH',
            b'VTYP',
            b'MATT',
            b'IPCT',
            b'IPDS',
            b'ARMA',
            b'ECZN',
            b'LCTN',
            b'MESG',
            b'DOBJ',
            b'DFOB',
            b'LGTM',
            b'MUSC',
            b'FSTP',
            b'FSTS',
            b'SMBN',
            b'SMQN',
            b'SMEN',
            b'DLBR',
            b'MUST',
            b'DLVW',
            b'EQUP',
            b'RELA',
            b'SCEN',
            b'ASTP',
            b'OTFT',
            b'ARTO',
            b'MATO',
            b'MOVT',
            b'SNDR',
            b'SNCT',
            b'SOPM',
            b'COLL',
            b'CLFM',
            b'REVB',
            b'PKIN',
            b'RFGP',
            b'AMDL',
            b'LAYR',
            b'COBJ',
            b'OMOD',
            b'MSWP',
            b'ZOOM',
            b'INNR',
            b'KSSM',
            b'AECH',
            b'SCCO',
            b'AORU',
            b'SCSN',
            b'STAG',
            b'NOCM',
            b'LENS',
            b'GDRY',
            b'OVIS',
        ]
        header_type.valid_header_sigs = (set(header_type.top_grup_sigs) | {
            b'GRUP', b'TES4', b'REFR', b'ACHR', b'PMIS', b'PARW', b'PGRE',
            b'PBEA', b'PFLA', b'PCON', b'PBAR', b'PHZD', b'LAND', b'NAVM',
            b'DIAL', b'INFO'
        })
        header_type.plugin_form_version = 131
        brec.MreRecord.type_class = {
            x.rec_sig: x
            for x in (
                MreTes4,  #--Always present
                MreGmst,  # Imported from Skyrim or SkyrimSE
                MreLvli,
                MreLvln,  # Added to records.py
            )
        }
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) -
                                      {b'TES4'})
        cls._validate_records()
Example #20
0
class OblivionGameInfo(PatchGame):
    displayName = u'Oblivion'
    fsName = u'Oblivion'
    altName = u'Wrye Bash'
    game_icon = u'oblivion_%u.png'
    bash_root_prefix = u'Oblivion'
    bak_game_name = u'Oblivion'
    template_dir = u'Oblivion'
    bash_patches_dir = u'Oblivion'
    my_games_name = u'Oblivion'
    appdata_name = u'Oblivion'
    launch_exe = u'Oblivion.exe'
    # Set to this because that file does not exist in Nehrim, whereas
    # OblivionLauncher.exe and Oblivion.exe do
    game_detect_includes = [_j(u'Data', u'Oblivion.esm')]
    game_detect_excludes = WS_COMMON
    version_detect_file = u'Oblivion.exe'
    master_file = u'Oblivion.esm'
    taglist_dir = u'Oblivion'
    loot_dir = u'Oblivion'
    boss_game_name = u'Oblivion'
    regInstallKeys = (u'Bethesda Softworks\\Oblivion', u'Installed Path')
    nexusUrl = u'https://www.nexusmods.com/oblivion/'
    nexusName = u'Oblivion Nexus'
    nexusKey = u'bash.installers.openOblivionNexus.continue'

    patchURL = u'http://www.elderscrolls.com/downloads/updates_patches.htm'
    patchTip = u'http://www.elderscrolls.com/'

    using_txt_file = False
    has_standalone_pluggy = True

    class Ck(GameInfo.Ck):
        ck_abbrev = u'TESCS'
        long_name = u'Construction Set'
        exe = u'TESConstructionSet.exe'
        se_args = u'-editor'
        image_name = u'tescs%s.png'

    class Se(GameInfo.Se):
        se_abbrev = u'OBSE'
        long_name = u'Oblivion Script Extender'
        exe = u'obse_loader.exe'
        # Not sure why we need obse_1_2_416.dll, was there before refactoring
        ver_files = [u'obse_loader.exe', u'obse_steam_loader.dll',
                     u'obse_1_2_416.dll']
        plugin_dir = u'OBSE'
        cosave_tag = u'OBSE'
        cosave_ext = u'.obse'
        url = u'http://obse.silverlock.org/'
        url_tip = u'http://obse.silverlock.org/'
        limit_fixer_plugins = [u'mod_limit_fix.dll', u'Trifle.dll']

    class Ge(GameInfo.Ge):
        ge_abbrev = u'OBGE'
        long_name = u'Oblivion Graphics Extender'
        exe = [(u'obse', u'plugins', u'obge.dll'),
               (u'obse', u'plugins', u'obgev2.dll'),
               (u'obse', u'plugins', u'oblivionreloaded.dll'),
               ]
        url = u'https://www.nexusmods.com/oblivion/mods/30054'
        url_tip = u'https://www.nexusmods.com/oblivion'

    class Ini(GameInfo.Ini):
        allow_new_lines = False
        bsa_redirection_key = (u'Archive', u'sArchiveList')
        default_ini_file = u'Oblivion_default.ini'
        dropdown_inis = [u'Oblivion.ini']
        supports_mod_inis = False

    class Ess(GameInfo.Ess):
        canEditMore = True
        can_safely_remove_masters = True

    class Bsa(GameInfo.Bsa):
        allow_reset_timestamps = True
        # Oblivion accepts the base name and literally *anything* after
        # that. E.g. MyModMeshes.bsa will load from a MyMod.esp plugin
        attachment_regex = u'.*'
        redate_dict = defaultdict(lambda: u'2006-01-01', {
            u'Oblivion - Voices1.bsa': u'2005-01-02',
            u'Oblivion - Voices2.bsa': u'2005-01-03',
            u'Oblivion - Meshes.bsa': u'2005-01-04',
            u'Oblivion - Sounds.bsa': u'2005-01-05',
            u'Oblivion - Misc.bsa': u'2005-01-06',
        })
        valid_versions = {0x67}

    class Xe(GameInfo.Xe):
        full_name = u'TES4Edit'
        xe_key_prefix = u'tes4View'

    class Bain(GameInfo.Bain):
        data_dirs = GameInfo.Bain.data_dirs | {
            u'_tejon',
            u'distantlod',
            u'facegen',
            u'fonts',
            u'menus',
            u'obse',
            u'pluggy',
            u'scripts',
            u'shaders',
            u'streamline',
            u'trees',
        }
        keep_data_dirs = {
            _j(u'OBSE', u'Plugins', u'ComponentDLLs', u'CSE'),
            u'LSData'
        }
        keep_data_files = {
            _j(u'OBSE', u'Plugins', u'Construction Set Extender.dll'),
            _j(u'OBSE', u'Plugins', u'Construction Set Extender.ini'),
        }
        keep_data_file_prefixes = {
            _j(u'Meshes', u'Characters', u'_Male', u'specialanims',
                u'0FemaleVariableWalk_'),
        }
        skip_bain_refresh = {
            u'tes4edit backups',
            u'tes4edit cache',
            u'bgsee',
            u'conscribe logs',
        }
        wrye_bash_data_files = {u'ArchiveInvalidationInvalidated!.bsa'}

    class Esp(GameInfo.Esp):
        canBash = True
        canEditHeader = True
        validHeaderVersions = (0.8,1.0)
        stringsFiles = []
        biped_flag_names = (u'head', u'hair', u'upperBody', u'lowerBody',
                            u'hand', u'foot', u'rightRing', u'leftRing',
                            u'amulet', u'weapon', u'backWeapon', u'sideWeapon',
                            u'quiver', u'shield', u'torch', u'tail')
        reference_types = {b'ACHR', b'ACRE', b'REFR'}

    allTags = PatchGame.allTags | {u'IIM', u'NoMerge'}

    patchers = {
        u'AliasModNames', u'CoblCatalogs', u'CoblExhaustion',
        u'ContentsChecker', u'ImportActors', u'ImportActorsAIPackages',
        u'ImportActorsAnimations', u'ImportActorsDeathItems',
        u'ImportActorsFaces', u'ImportActorsFactions', u'ImportActorsSpells',
        u'ImportCells', u'ImportEffectsStats', u'ImportEnchantmentStats',
        u'ImportGraphics', u'ImportInventory', u'ImportNames',
        u'ImportRelations', u'ImportRoads', u'ImportScripts', u'ImportSounds',
        u'ImportSpellStats', u'ImportStats', u'ImportText', u'LeveledLists',
        u'MergePatches', u'MorphFactions', u'NpcChecker', u'ReplaceFormIDs',
        u'SEWorldTests', u'TweakActors', u'TweakAssorted', u'TweakClothes',
        u'TweakNames', u'TweakSettings', u'ImportRaces', u'ImportRacesSpells',
        u'ImportRacesRelations', u'EyeChecker', u'TweakRaces', u'RaceChecker',
        u'TimescaleChecker',
    }

    weaponTypes = (
        _(u'Blade (1 Handed)'),
        _(u'Blade (2 Handed)'),
        _(u'Blunt (1 Handed)'),
        _(u'Blunt (2 Handed)'),
        _(u'Staff'),
        _(u'Bow'),
        )

    raceNames = {
        0x23fe9 : _(u'Argonian'),
        0x224fc : _(u'Breton'),
        0x191c1 : _(u'Dark Elf'),
        0x19204 : _(u'High Elf'),
        0x00907 : _(u'Imperial'),
        0x22c37 : _(u'Khajiit'),
        0x224fd : _(u'Nord'),
        0x191c0 : _(u'Orc'),
        0x00d43 : _(u'Redguard'),
        0x00019 : _(u'Vampire'),
        0x223c8 : _(u'Wood Elf'),
        }
    raceShortNames = {
        0x23fe9 : u'Arg',
        0x224fc : u'Bre',
        0x191c1 : u'Dun',
        0x19204 : u'Alt',
        0x00907 : u'Imp',
        0x22c37 : u'Kha',
        0x224fd : u'Nor',
        0x191c0 : u'Orc',
        0x00d43 : u'Red',
        0x223c8 : u'Bos',
        }
    raceHairMale = {
        0x23fe9 : 0x64f32, #--Arg
        0x224fc : 0x90475, #--Bre
        0x191c1 : 0x64214, #--Dun
        0x19204 : 0x7b792, #--Alt
        0x00907 : 0x90475, #--Imp
        0x22c37 : 0x653d4, #--Kha
        0x224fd : 0x1da82, #--Nor
        0x191c0 : 0x66a27, #--Orc
        0x00d43 : 0x64215, #--Red
        0x223c8 : 0x690bc, #--Bos
        }
    raceHairFemale = {
        0x23fe9 : 0x64f33, #--Arg
        0x224fc : 0x1da83, #--Bre
        0x191c1 : 0x1da83, #--Dun
        0x19204 : 0x690c2, #--Alt
        0x00907 : 0x1da83, #--Imp
        0x22c37 : 0x653d0, #--Kha
        0x224fd : 0x1da83, #--Nor
        0x191c0 : 0x64218, #--Orc
        0x00d43 : 0x64210, #--Red
        0x223c8 : 0x69473, #--Bos
        }

    bethDataFiles = {
        #--Vanilla
        u'oblivion.esm',
        u'oblivion_1.1.esm',
        u'oblivion_si.esm',
        u'oblivion - meshes.bsa',
        u'oblivion - misc.bsa',
        u'oblivion - sounds.bsa',
        u'oblivion - textures - compressed.bsa',
        u'oblivion - textures - compressed.bsa.orig',
        u'oblivion - voices1.bsa',
        u'oblivion - voices2.bsa',
        #--Shivering Isles
        u'dlcshiveringisles.esp',
        u'dlcshiveringisles - meshes.bsa',
        u'dlcshiveringisles - sounds.bsa',
        u'dlcshiveringisles - textures.bsa',
        u'dlcshiveringisles - voices.bsa',
        #--Knights of the Nine - shipped with all WS versions
        u'knights.esp',
        u'knights.bsa',
    }

    @classmethod
    def _dynamic_import_modules(cls, package_name):
        super(OblivionGameInfo, cls)._dynamic_import_modules(package_name)
        # Do the imports *after setting the _constants_members*
        from .patcher import checkers, preservers
        cls.gameSpecificPatchers = {
            u'CoblCatalogs': checkers.CoblCatalogsPatcher,
            u'SEWorldTests': checkers.SEWorldTestsPatcher, }
        cls.gameSpecificListPatchers = {
            u'CoblExhaustion': preservers.CoblExhaustionPatcher,
            u'MorphFactions': preservers.MorphFactionsPatcher, }
        cls.game_specific_import_patchers = {
            u'ImportRoads': preservers.ImportRoadsPatcher, }

    @classmethod
    def init(cls):
        cls._dynamic_import_modules(__name__)
        from .records import MreActi, MreAlch, MreAmmo, MreAnio, MreAppa, \
            MreArmo, MreBook, MreBsgn, MreClas, MreClot, MreCont, MreCrea, \
            MreDoor, MreEfsh, MreEnch, MreEyes, MreFact, MreFlor, MreFurn, \
            MreGras, MreHair, MreIngr, MreKeym, MreLigh, MreLscr, MreLvlc, \
            MreLvli, MreLvsp, MreMgef, MreMisc, MreNpc, MrePack, MreQust, \
            MreRace, MreScpt, MreSgst, MreSlgm, MreSoun, MreSpel, MreStat, \
            MreTree, MreWatr, MreWeap, MreWthr, MreClmt, MreCsty, MreIdle, \
            MreLtex, MreRegn, MreSbsp, MreSkil, MreAchr, MreAcre, MreCell, \
            MreGmst, MreRefr, MreRoad, MreTes4, MreWrld, MreDial, MreInfo, \
            MrePgrd
        cls.mergeable_sigs = {clazz.rec_sig: clazz for clazz in (
            MreActi, MreAlch, MreAmmo, MreAnio, MreAppa, MreArmo, MreBook,
            MreBsgn, MreClas, MreClot, MreCont, MreCrea, MreDoor, MreEfsh,
            MreEnch, MreEyes, MreFact, MreFlor, MreFurn, MreGlob, MreGras,
            MreHair, MreIngr, MreKeym, MreLigh, MreLscr, MreLvlc, MreLvli,
            MreLvsp, MreMgef, MreMisc, MreNpc, MrePack, MreQust, MreRace,
            MreScpt, MreSgst, MreSlgm, MreSoun, MreSpel, MreStat, MreTree,
            MreWatr, MreWeap, MreWthr, MreClmt, MreCsty, MreIdle, MreLtex,
            MreRegn, MreSbsp, MreSkil, MreAchr, MreAcre, MreCell, MreGmst,
            MreRefr, MreRoad, MreWrld, MreDial, MreInfo, MreLand, MrePgrd,
        )}
        cls.readClasses = (b'MGEF', b'SCPT')
        cls.writeClasses = (b'MGEF',)
        # Setting RecordHeader class variables - Oblivion is special
        header_type = brec.RecordHeader
        header_type.rec_header_size = 20
        header_type.rec_pack_format = [u'=4s', u'I', u'I', u'I', u'I']
        header_type.rec_pack_format_str = u''.join(header_type.rec_pack_format)
        header_type.header_unpack = _struct.Struct(
            header_type.rec_pack_format_str).unpack
        header_type.pack_formats = {0: u'=4sI4s2I'}
        header_type.pack_formats.update(
            {x: u'=4s4I' for x in {1, 6, 7, 8, 9, 10}})
        header_type.pack_formats.update({x: u'=4sIi2I' for x in {2, 3}})
        header_type.pack_formats.update({x: u'=4sIhh2I' for x in {4, 5}})
        # Similar to other games
        header_type.top_grup_sigs = [
            b'GMST', b'GLOB', b'CLAS', b'FACT', b'HAIR', b'EYES', b'RACE',
            b'SOUN', b'SKIL', b'MGEF', b'SCPT', b'LTEX', b'ENCH', b'SPEL',
            b'BSGN', b'ACTI', b'APPA', b'ARMO', b'BOOK', b'CLOT', b'CONT',
            b'DOOR', b'INGR', b'LIGH', b'MISC', b'STAT', b'GRAS', b'TREE',
            b'FLOR', b'FURN', b'WEAP', b'AMMO', b'NPC_', b'CREA', b'LVLC',
            b'SLGM', b'KEYM', b'ALCH', b'SBSP', b'SGST', b'LVLI', b'WTHR',
            b'CLMT', b'REGN', b'CELL', b'WRLD', b'DIAL', b'QUST', b'IDLE',
            b'PACK', b'CSTY', b'LSCR', b'LVSP', b'ANIO', b'WATR', b'EFSH',
        ]
        header_type.valid_header_sigs = set(
            header_type.top_grup_sigs + [b'GRUP', b'TES4', b'ROAD', b'REFR',
                                         b'ACHR', b'ACRE', b'PGRD', b'LAND',
                                         b'INFO'])
        brec.MreRecord.type_class = {x.rec_sig: x for x in (
            MreAchr, MreAcre, MreActi, MreAlch, MreAmmo, MreAnio, MreAppa,
            MreArmo, MreBook, MreBsgn, MreCell, MreClas, MreClot, MreCont,
            MreCrea, MreDoor, MreEfsh, MreEnch, MreEyes, MreFact, MreFlor,
            MreFurn, MreGlob, MreGmst, MreGras, MreHair, MreIngr, MreKeym,
            MreLigh, MreLscr, MreLvlc, MreLvli, MreLvsp, MreMgef, MreMisc,
            MreNpc, MrePack, MreQust, MreRace, MreRefr, MreRoad, MreScpt,
            MreSgst, MreSkil, MreSlgm, MreSoun, MreSpel, MreStat, MreTree,
            MreTes4, MreWatr, MreWeap, MreWrld, MreWthr, MreClmt, MreCsty,
            MreIdle, MreLtex, MreRegn, MreSbsp, MreDial, MreInfo, MreLand,
            MrePgrd)}
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) - {
            b'TES4', b'ACHR', b'ACRE', b'REFR', b'CELL', b'PGRD', b'ROAD',
            b'LAND', b'WRLD', b'INFO', b'DIAL'})
        cls._validate_records()
Example #21
0
def experiment_config_path(directory):
    path = _j(directory, 'experiment_config.json')
    return path
Example #22
0
import dot_config
import dot_util

#
# Configuration
#

ROOT = _d(_d(_d(_r(__file__))))
if not os.path.exists(ROOT):
    print ("ERROR: ROOT ({ROOT}) doesn't exist".format(ROOT=ROOT))
    sys.exit(1)

# Time to wait to connect to various things.
MAX_TIME_SEC = 60

COMMON_SH = _j(ROOT, "src/sh/common.sh")
EXPORTS_SH = _j(ROOT, "src/sh/exports.sh")

#
# End of configuration
#

def config_vars():
    ignore = set([
    '__builtins__',
    '__doc__',
    '__file__',
    '__name__',
    '__package__',
    '_prev_dir',
    ])
Example #23
0
 def _call_times_summary_path(self, bench_name):
     path = _j(
         self.directory, "pyprof_call_times{bench}.txt".format(
             bench=bench_suffix(bench_name)))
     return path
 def _csv_path(self):
     return _j(self.directory, "extrapolated_training_time.csv")
Example #25
0
 def pickle_path(self, directory, func, args):
     basename = self.pickle_basename(func)
     sha = self.argument_hash(args)
     return _j(directory, ".{basename}.{sha}.cpickle".format(**locals()))
def get_trace_path(directory, trace_id):
    path = _j(
        directory,
        'machine_util{trace}.proto'.format(trace=trace_suffix(trace_id), ))
    return path
Example #27
0
 def _flamegraph_svg_path(self, op_name):
     return _j(
         self.directory,
         'flamegraph{bench}.svg'.format(bench=bench_suffix(op_name), ))
Example #28
0
 def _adjust_paths(self, old_entry):
     entry = dict(old_entry)
     for key in list(entry.keys()):
         if re.search(r'_path$', key):
             entry[key] = _j(self.directory, entry[key])
     return entry
Example #29
0
import json
import codecs
from os.path import join as _j, abspath as _a, dirname as _d, exists as _e, basename as _b

# pip install progressbar2
import progressbar

from rlscope.parser.common import *
from rlscope.parser import constants
from rlscope.parser.stats import Stats, KernelTime

from rlscope.parser.db import SQLCategoryTimesReader, sql_get_source_files, sql_input_path, process_op_nest_single_thread, each_stack_trace

from rlscope import py_config

FLAME_GRAPH_PERL = _j(py_config.ROOT, 'third_party', 'FlameGraph',
                      'flamegraph.pl')


class PythonFlameGraphParser:
    def __init__(
            self,
            directory,
            host=None,
            user=None,
            password=None,
            op_name=None,
            debug=False,
            # Swallow any excess arguments
            **kwargs):
        self.directory = directory
        self.host = host
Example #30
0
"""
import argparse
import subprocess
import textwrap
import sys
import os
import re
from os.path import join as _j, abspath as _a, exists as _e, dirname as _d, basename as _b
import datetime
import pytz

from rlscope.profiler.rlscope_logging import logger
from rlscope import py_config
from rlscope.profiler.util import pprint_msg

VERSION_PY = _j(py_config.ROOT, "rlscope", "version.py")
RLSCOPE_INIT_PY = _j(py_config.ROOT, "rlscope", "__init__.py")
TIME_ZONE = 'America/New_York'


class VersionGenerator:
    def __init__(self, args):
        self.args = args
        self._init_versions()

        self.utc_now = pytz.utc.localize(datetime.datetime.utcnow())
        self.tz_now = self.utc_now.astimezone(pytz.timezone(TIME_ZONE))

    def _init_versions(self):
        args = self.args
        self.cuda = args.cuda_version
Example #31
0
class Fallout3GameInfo(PatchGame):
    displayName = u'Fallout 3'
    fsName = u'Fallout3'
    altName = u'Wrye Flash'
    game_icon = u'fallout3_%u.png'
    bash_root_prefix = u'Fallout3'
    bak_game_name = u'Fallout3'
    template_dir = u'Fallout3'
    my_games_name = u'Fallout3'
    appdata_name = u'Fallout3'
    launch_exe = u'Fallout3.exe'
    game_detect_includes = [u'Fallout3.exe']
    version_detect_file = u'Fallout3.exe'
    master_file = u'Fallout3.esm'
    taglist_dir = u'Fallout3'
    loot_dir = u'Fallout3'
    boss_game_name = u'Fallout3'
    regInstallKeys = (u'Bethesda Softworks\\Fallout3',u'Installed Path')
    nexusUrl = u'https://www.nexusmods.com/fallout3/'
    nexusName = u'Fallout 3 Nexus'
    nexusKey = u'bash.installers.openFallout3Nexus.continue'

    using_txt_file = False
    plugin_name_specific_dirs = GameInfo.plugin_name_specific_dirs + [
        _j(u'textures', u'characters', u'BodyMods'),
        _j(u'textures', u'characters', u'FaceMods')]

    class Ck(GameInfo.Ck):
        ck_abbrev = u'GECK'
        long_name = u'Garden of Eden Creation Kit'
        exe = u'GECK.exe'
        se_args = u'-editor'
        image_name = u'geck%s.png'

    class Se(GameInfo.Se):
        se_abbrev = u'FOSE'
        long_name = u'Fallout 3 Script Extender'
        exe = u'fose_loader.exe'
        # There is no fose_steam_loader.dll, so we have to list all included
        # DLLs, since people could delete any DLL not matching the game version
        # they're using
        ver_files = [u'fose_loader.exe', u'fose_1_7ng.dll', u'fose_1_7.dll',
                     u'fose_1_6.dll', u'fose_1_5.dll', u'fose_1_4b.dll',
                     u'fose_1_4.dll', u'fose_1_1.dll', u'fose_1_0.dll']
        plugin_dir = u'FOSE'
        cosave_tag = u'FOSE'
        cosave_ext = u'.fose'
        url = u'http://fose.silverlock.org/'
        url_tip = u'http://fose.silverlock.org/'
        limit_fixer_plugins = [u'mod_limit_fix.dll']

    class Ini(GameInfo.Ini):
        allow_new_lines = False
        bsa_redirection_key = (u'Archive', u'sArchiveList')
        default_ini_file = u'Fallout_default.ini'
        dropdown_inis = [u'Fallout.ini', u'FalloutPrefs.ini']
        supports_mod_inis = False

    class Ess(GameInfo.Ess):
        ext = u'.fos'
        can_safely_remove_masters = True

    class Bsa(GameInfo.Bsa):
        allow_reset_timestamps = True
        redate_dict = defaultdict(lambda: u'2006-01-01', {
            u'Fallout - MenuVoices.bsa': u'2005-01-01',
            u'Fallout - Meshes.bsa': u'2005-01-02',
            u'Fallout - Misc.bsa': u'2005-01-03',
            u'Fallout - Sound.bsa': u'2005-01-04',
            u'Fallout - Textures.bsa': u'2005-01-05',
            u'Fallout - Voices.bsa': u'2005-01-06',
        })
        # ArchiveInvalidation Invalidated, which we shipped unmodified for a
        # long time, uses an Oblivion BSA with version 0x67, so we have to
        # accept those here as well
        valid_versions = {0x67, 0x68}

    class Xe(GameInfo.Xe):
        full_name = u'FO3Edit'
        xe_key_prefix = u'fo3View'

    class Bain(GameInfo.Bain):
        data_dirs = GameInfo.Bain.data_dirs | {
            u'config', # mod config files (INIs)
            u'distantlod',
            u'docs',
            u'facegen',
            u'fonts',
            u'fose',
            u'menus',
            u'uio', # User Interface Organizer
            u'scripts',
            u'shaders',
            u'trees',
        }
        keep_data_dirs = {u'LSData'}
        keep_data_files = {u'Fallout - AI!.bsa'}
        skip_bain_refresh = {u'fo3edit backups', u'fo3edit cache'}
        wrye_bash_data_files = {u'ArchiveInvalidationInvalidated!.bsa'}

    class Esp(GameInfo.Esp):
        canBash = True
        canEditHeader = True
        validHeaderVersions = (0.85, 0.94)
        stringsFiles = []
        generate_temp_child_onam = True
        biped_flag_names = (u'head', u'hair', u'upperBody', u'leftHand',
                            u'rightHand', u'weapon', u'pipboy', u'backpack',
                            u'necklace', u'headband', u'hat', u'eyeGlasses',
                            u'noseRing', u'earrings', u'mask', u'choker',
                            u'mouthObject', u'bodyAddOn1', u'bodyAddOn2',
                            u'bodyAddOn3')
        reference_types = {b'ACHR', b'ACRE', b'PBEA', b'PGRE', b'PMIS',
                           b'REFR'}

    allTags = PatchGame.allTags | {u'NoMerge'}

    patchers = {
        u'AliasModNames', u'ContentsChecker', u'FormIDLists', u'ImportActors',
        u'ImportActorsAIPackages', u'ImportActorsAnimations', u'NpcChecker',
        u'ImportActorsDeathItems', u'ImportActorsFaces', u'RaceChecker',
        u'ImportActorsFactions', u'ImportActorsSpells', u'ImportCells',
        u'ImportDestructible', u'ImportEffectsStats', u'ImportRaces',
        u'ImportEnchantmentStats', u'ImportGraphics', u'ImportInventory',
        u'ImportNames', u'ImportObjectBounds', u'ImportRelations',
        u'ImportScripts', u'ImportSounds', u'ImportSpellStats', u'ImportStats',
        u'ImportText', u'LeveledLists', u'MergePatches', u'TweakActors',
        u'TweakAssorted', u'TweakSettings', u'ImportRacesRelations',
        u'TweakRaces', u'TimescaleChecker', u'TweakNames',
    }

    weaponTypes = (
        _(u'Big gun'),
        _(u'Energy'),
        _(u'Small gun'),
        _(u'Melee'),
        _(u'Unarmed'),
        _(u'Thrown'),
        _(u'Mine'),
        )

    raceNames = {
        0x000019 : _(u'Caucasian'),
        0x0038e5 : _(u'Hispanic'),
        0x0038e6 : _(u'Asian'),
        0x003b3e : _(u'Ghoul'),
        0x00424a : _(u'AfricanAmerican'),
        0x0042be : _(u'AfricanAmerican Child'),
        0x0042bf : _(u'AfricanAmerican Old'),
        0x0042c0 : _(u'Asian Child'),
        0x0042c1 : _(u'Asian Old'),
        0x0042c2 : _(u'Caucasian Child'),
        0x0042c3 : _(u'Caucasian Old'),
        0x0042c4 : _(u'Hispanic Child'),
        0x0042c5 : _(u'Hispanic Old'),
        0x04bb8d : _(u'Caucasian Raider'),
        0x04bf70 : _(u'Hispanic Raider'),
        0x04bf71 : _(u'Asian Raider'),
        0x04bf72 : _(u'AfricanAmerican Raider'),
        0x0987dc : _(u'Hispanic Old Aged'),
        0x0987dd : _(u'Asian Old Aged'),
        0x0987de : _(u'AfricanAmerican Old Aged'),
        0x0987df : _(u'Caucasian Old Aged'),
        }

    raceShortNames = {
        0x000019 : u'Cau',
        0x0038e5 : u'His',
        0x0038e6 : u'Asi',
        0x003b3e : u'Gho',
        0x00424a : u'Afr',
        0x0042be : u'AfC',
        0x0042bf : u'AfO',
        0x0042c0 : u'AsC',
        0x0042c1 : u'AsO',
        0x0042c2 : u'CaC',
        0x0042c3 : u'CaO',
        0x0042c4 : u'HiC',
        0x0042c5 : u'HiO',
        0x04bb8d : u'CaR',
        0x04bf70 : u'HiR',
        0x04bf71 : u'AsR',
        0x04bf72 : u'AfR',
        0x0987dc : u'HOA',
        0x0987dd : u'AOA',
        0x0987de : u'FOA',
        0x0987df : u'COA',
        }

    raceHairMale = {
        0x000019 : 0x014b90, #--Cau
        0x0038e5 : 0x0a9d6f, #--His
        0x0038e6 : 0x014b90, #--Asi
        0x003b3e : None, #--Gho
        0x00424a : 0x0306be, #--Afr
        0x0042be : 0x060232, #--AfC
        0x0042bf : 0x0306be, #--AfO
        0x0042c0 : 0x060232, #--AsC
        0x0042c1 : 0x014b90, #--AsO
        0x0042c2 : 0x060232, #--CaC
        0x0042c3 : 0x02bfdb, #--CaO
        0x0042c4 : 0x060232, #--HiC
        0x0042c5 : 0x02ddee, #--HiO
        0x04bb8d : 0x02bfdb, #--CaR
        0x04bf70 : 0x02bfdb, #--HiR
        0x04bf71 : 0x02bfdb, #--AsR
        0x04bf72 : 0x0306be, #--AfR
        0x0987dc : 0x0987da, #--HOA
        0x0987dd : 0x0987da, #--AOA
        0x0987de : 0x0987d9, #--FOA
        0x0987df : 0x0987da, #--COA
        }

    raceHairFemale = {
        0x000019 : 0x05dc6b, #--Cau
        0x0038e5 : 0x05dc76, #--His
        0x0038e6 : 0x022e50, #--Asi
        0x003b3e : None, #--Gho
        0x00424a : 0x05dc78, #--Afr
        0x0042be : 0x05a59e, #--AfC
        0x0042bf : 0x072e39, #--AfO
        0x0042c0 : 0x05a5a3, #--AsC
        0x0042c1 : 0x072e39, #--AsO
        0x0042c2 : 0x05a59e, #--CaC
        0x0042c3 : 0x072e39, #--CaO
        0x0042c4 : 0x05a59e, #--HiC
        0x0042c5 : 0x072e39, #--HiO
        0x04bb8d : 0x072e39, #--CaR
        0x04bf70 : 0x072e39, #--HiR
        0x04bf71 : 0x072e39, #--AsR
        0x04bf72 : 0x072e39, #--AfR
        0x0987dc : 0x044529, #--HOA
        0x0987dd : 0x044529, #--AOA
        0x0987de : 0x044529, #--FOA
        0x0987df : 0x044529, #--COA
        }

    bethDataFiles = {
        #--Vanilla
        u'fallout3.esm',
        u'fallout - menuvoices.bsa',
        u'fallout - meshes.bsa',
        u'fallout - misc.bsa',
        u'fallout - sound.bsa',
        u'fallout - textures.bsa',
        u'fallout - voices.bsa',
        #-- DLC
        u'anchorage.esm',
        u'anchorage - main.bsa',
        u'anchorage - sounds.bsa',
        u'thepitt.esm',
        u'thepitt - main.bsa',
        u'thepitt - sounds.bsa',
        u'brokensteel.esm',
        u'brokensteel - main.bsa',
        u'brokensteel - sounds.bsa',
        u'pointlookout.esm',
        u'pointlookout - main.bsa',
        u'pointlookout - sounds.bsa',
        u'zeta.esm',
        u'zeta - main.bsa',
        u'zeta - sounds.bsa',
    }

    @classmethod
    def init(cls):
        cls._dynamic_import_modules(__name__)
        from .records import MreActi, MreAddn, MreAlch, MreAmmo, MreAnio, \
            MreArma, MreArmo, MreAspc, MreAvif, MreBook, MreBptd, MreCams, \
            MreClas, MreClmt, MreCobj, MreCont, MreCpth, MreCrea, MreCsty, \
            MreDebr, MreDobj, MreDoor, MreEczn, MreEfsh, MreEnch, MreExpl, \
            MreEyes, MreFact, MreFurn, MreGras, MreHair, MreHdpt, MreTes4, \
            MreIdle, MreIdlm, MreImad, MreImgs, MreIngr, MreIpct, MreIpds, \
            MreKeym, MreLgtm, MreLigh, MreLscr, MreLtex, MreLvlc, MreLvli, \
            MreLvln, MreMesg, MreMgef, MreMicn, MreMisc, MreMstt, MreMusc, \
            MreNote, MreNpc, MrePack, MrePerk, MreProj, MrePwat, MreQust, \
            MreRace, MreRads, MreRegn, MreRgdl, MreScol, MreScpt, MreSoun, \
            MreSpel, MreStat, MreTact, MreTerm, MreTree, MreTxst, MreVtyp, \
            MreWatr, MreWeap, MreWthr, MreAchr, MreAcre, MreCell, MreDial, \
            MreGmst, MreInfo, MreNavi, MreNavm, MrePgre, MrePmis, MreRefr, \
            MreWrld
        cls.mergeable_sigs = {clazz.rec_sig: clazz for clazz in (
            MreActi, MreAddn, MreAlch, MreAmmo, MreAnio, MreArma, MreArmo,
            MreAspc, MreAvif, MreBook, MreBptd, MreCams, MreClas, MreClmt,
            MreCobj, MreCont, MreCpth, MreCrea, MreCsty, MreDebr, MreDobj,
            MreDoor, MreEczn, MreEfsh, MreEnch, MreExpl, MreEyes, MreFact,
            MreFlst, MreFurn, MreGlob, MreGras, MreHair, MreHdpt, MreIdle,
            MreIdlm, MreImad, MreImgs, MreIngr, MreIpct, MreIpds, MreKeym,
            MreLgtm, MreLigh, MreLscr, MreLtex, MreLvlc, MreLvli, MreLvln,
            MreMesg, MreMgef, MreMicn, MreMisc, MreMstt, MreMusc, MreNote,
            MreNpc, MrePack, MrePerk, MreProj, MrePwat, MreQust, MreRace,
            MreRads, MreRegn, MreRgdl, MreScol, MreScpt, MreSoun, MreSpel,
            MreStat, MreTact,MreTerm, MreTree, MreTxst, MreVtyp, MreWatr,
            MreWeap, MreWthr, MreGmst,
        )}
        # Setting RecordHeader class variables --------------------------------
        header_type = brec.RecordHeader
        header_type.top_grup_sigs = [
            b'GMST', b'TXST', b'MICN', b'GLOB', b'CLAS', b'FACT', b'HDPT',
            b'HAIR', b'EYES', b'RACE', b'SOUN', b'ASPC', b'MGEF', b'SCPT',
            b'LTEX', b'ENCH', b'SPEL', b'ACTI', b'TACT', b'TERM', b'ARMO',
            b'BOOK', b'CONT', b'DOOR', b'INGR', b'LIGH', b'MISC', b'STAT',
            b'SCOL', b'MSTT', b'PWAT', b'GRAS', b'TREE', b'FURN', b'WEAP',
            b'AMMO', b'NPC_', b'CREA', b'LVLC', b'LVLN', b'KEYM', b'ALCH',
            b'IDLM', b'NOTE', b'PROJ', b'LVLI', b'WTHR', b'CLMT', b'COBJ',
            b'REGN', b'NAVI', b'CELL', b'WRLD', b'DIAL', b'QUST', b'IDLE',
            b'PACK', b'CSTY', b'LSCR', b'ANIO', b'WATR', b'EFSH', b'EXPL',
            b'DEBR', b'IMGS', b'IMAD', b'FLST', b'PERK', b'BPTD', b'ADDN',
            b'AVIF', b'RADS', b'CAMS', b'CPTH', b'VTYP', b'IPCT', b'IPDS',
            b'ARMA', b'ECZN', b'MESG', b'RGDL', b'DOBJ', b'LGTM', b'MUSC',
        ]
        header_type.valid_header_sigs = set(
            header_type.top_grup_sigs + [b'GRUP', b'TES4', b'ACHR', b'ACRE',
                                         b'INFO', b'LAND', b'NAVM', b'PGRE',
                                         b'PMIS', b'REFR'])
        header_type.plugin_form_version = 15
        brec.MreRecord.type_class = {x.rec_sig: x for x in ( # Not Mergeable
             (MreAchr, MreAcre, MreCell, MreDial, MreInfo, MreNavi, MreNavm,
              MrePgre, MrePmis, MreRefr, MreWrld, MreTes4))}
        brec.MreRecord.type_class.update(cls.mergeable_sigs)
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) - {
            b'TES4', b'ACHR', b'ACRE', b'CELL', b'DIAL', b'INFO', b'LAND',
            b'NAVI', b'NAVM', b'PGRE', b'PMIS', b'REFR', b'WRLD'})
        cls._validate_records()
Example #32
0
class GameInfo(object):
    # Main game info - should be overridden -----------------------------------
    # Name of the game to use in UI.
    displayName = u''  ## Example: u'Skyrim'
    # Name of the game's filesystem folder.
    fsName = u''  ## Example: u'Skyrim'
    # Alternate display name of Wrye Bash when managing this game
    altName = u''  ## Example: u'Wrye Smash'
    # Name of the prefix of the '<X> Mods' folder, i.e. <X> is this string.
    # Preferably pick a single word here, equal to fsName if possible.
    bash_root_prefix = u''  ## Example: u'Skyrim'
    # True if the game uses the 'My Documents' folder, False to just use the
    # game path
    uses_personal_folders = True
    # The exe to use when launching the game (without xSE present)
    launch_exe = u''  ## Example: u'TESV.exe'
    # Path to a file to look for to see if this is the right game when joined
    # with the -o parameter. Must be unique among all games. As a rule of
    # thumb, use the file you specified in launch_exe, unless that file is
    # shared by multiple games, in which case you MUST find unique files - see
    # Skyrim and Enderal, which share TESV.exe.
    game_detect_file = u''
    # Path to a file to pass to env.get_file_version to determine the game's
    # version. Usually the same as launch_exe, but some games need different
    # ones here (e.g. Enderal, which has Skyrim's version in the launch_exe,
    # and therefore needs a different file here).
    version_detect_file = u''
    # The main plugin Wrye Bash should look for
    master_file = u''
    # The directory in which mods and other data files reside. This is relative
    # to the game directory.
    mods_dir = u'Data'
    # The pickle file for this game.  Holds encoded GMST IDs from the big list
    # below
    pklfile = u'*GAMENAME*_ids.pkl'
    # The directory containing the masterlist for this game, relative to
    # 'Mopy/Bash Patches'
    masterlist_dir = u''
    # Registry keys to read to find the install location
    # These are relative to:
    #  HKLM\Software
    #  HKLM\Software\Wow6432Node
    #  HKCU\Software
    #  HKCU\Software\Wow6432Node
    # Example: (u'Bethesda Softworks\\Oblivion', u'Installed Path')
    regInstallKeys = ()
    # URL to the Nexus site for this game
    nexusUrl = u''  # URL
    nexusName = u''  # Long Name
    nexusKey = u''  # Key for the "always ask this question" setting in
    # settings.dat

    # Additional game info - override as needed -------------------------------
    # URL to download patches for the main game.
    patchURL = u''
    # Tooltip to display over the URL when displayed
    patchTip = u'Update via Steam'
    # plugin extensions
    espm_extensions = {u'.esm', u'.esp', u'.esu'}
    # Load order info
    using_txt_file = True
    # bethesda net export files
    has_achlist = False
    # check if a plugin is convertible to a light master instead of checking
    # mergeability
    check_esl = False
    # Whether or not this game has standalone .pluggy cosaves
    has_standalone_pluggy = False
    # Information about Plugin-Name-specific Directories supported by this
    # game. Some examples are sound\voices\PLUGIN_NAME.esp, or the facegendata
    # ones. An empty list means that the game does not have any such
    # directories.
    plugin_name_specific_dirs = [_j(u'sound', u'voice')]

    def __init__(self, gamePath):
        self.gamePath = gamePath  # absolute bolt Path to the game directory
        self.has_esl = u'.esl' in self.espm_extensions

    class Ck(object):
        """Information about the official plugin editor (generally called some
        variation of 'Creation Kit') for this game."""
        ck_abbrev = u''  # Abbreviated name
        long_name = u''  # Full name
        exe = u'*DNE*'  # Executable to run
        # Argument to pass to the script extender to load the CK. If None,
        # indicates that this game's script extender does not have this feature
        se_args = None
        image_name = u''  # Image name template for the status bar

    class Se(object):
        """Information about the Script Extender for this game."""
        se_abbrev = u''  # Abbreviated name. If this is empty, it signals that
        # no xSE is available for this game. Note that this
        # should NEVER be used to program other xSE
        # behavior - create new variables like plugin_dir and
        # cosave_ext instead.
        long_name = u''  # Full name
        exe = u''  # Exe to run
        ver_files = []  # List of file names to use for version detection.
        # Tried in order until one exists. Needed because
        # it's technically not required to install the EXE.
        plugin_dir = u''  # One level above the directory in which xSE plugins
        # should be placed (e.g. when plugins should be in
        # Data\OBSE\Plugins, this should be u'OBSE')
        cosave_tag = u''  # The magic tag that the cosaves use (e.g. u'SKSE').
        # If this is empty, it signals that this script
        # extender has no cosaves.
        cosave_ext = u''  # The extension that the cosaves use (e.g. u'.skse')
        url = u''  # URL to download from
        url_tip = u''  # Tooltip for mouse over the URL

    class Sd(object):
        """Information about Script Dragon for this game."""
        sd_abbrev = u''  # Abbreviated name. If this is empty, it signals that
        # no Script Dragon is available for this game.
        long_name = u''  # Full name
        install_dir = u''  # The directory, relative to the Data folder, into
        # which Script Dragon plugins will be installed.

    class Sp(object):
        """Information about SkyProc patchers for this game."""
        sp_abbrev = u''  # Abbreviated name. If this is empty, it signals that
        # this game does not support SkyProc patchers.
        long_name = u''  # Full name
        install_dir = u''  # The directory, relative to the Data folder, into
        # which SkyProc patchers will be installed.

    class Ge(object):
        """Information about the Graphics Extender for this game."""
        ge_abbrev = u''  # Abbreviated name. If this is empty, it signals
        # that no graphics extender is available for this game.
        long_name = u''  # Full name
        # exe is treated specially here.  If it is a string, then it should
        # be the path relative to the root directory of the game, if it is
        # a list, each list element should be an iterable to pass to Path.join
        # relative to the root directory of the game.  In this case,
        # each filename will be tested in reverse order.  This was required
        # for Oblivion, as the newer OBGE has a different filename than the
        # older OBGE
        exe = u''
        url = u''  # URL to download from
        url_tip = u''  # Tooltip for mouse over the URL

    class Laa(object):
        """Information about the LAA (Large Address Aware) launcher for this
        game."""
        laa_name = u''  # Display name of the launcher
        exe = u'*DNE*'  # Executable to run
        launchesSE = False  # Whether the launcher will automatically launch
        # the SE

    class Ini(object):
        """Information about this game's INI handling."""
        # True means new lines are allowed to be added via INI tweaks
        # (by default)
        allow_new_lines = True
        # INI Entry to enable BSA Redirection - two empty strings if this game
        # does not need BSA redirection
        bsa_redirection_key = (u'', u'')
        # Name of game's default ini file.
        default_ini_file = u''
        # INI files that should show up in the INI Edits tab. Note that the
        # first one *must* be the main INI!
        #  Example: [u'Oblivion.ini']
        dropdown_inis = []
        # INI setting used to setup Save Profiles
        #  (section, key)
        save_profiles_key = (u'General', u'SLocalSavePath')
        # Base dir for the save_profiles_key setting above
        save_prefix = u'Saves'
        # INI setting used to enable or disable screenshots
        #  (section, key, default value)
        screenshot_enabled_key = (u'Display', u'bAllowScreenShot', u'1')
        # INI setting used to set base screenshot name
        #  (section, key, default value)
        screenshot_base_key = (u'Display', u'sScreenShotBaseName',
                               u'ScreenShot')
        # INI setting used to set screenshot index
        #  (section, key, default value)
        screenshot_index_key = (u'Display', u'iScreenShotIndex', u'0')
        # The INI entries listing vanilla BSAs to load
        resource_archives_keys = ()
        # Whether this game supports mod ini files aka ini fragments
        supports_mod_inis = True

    class Ess(object):
        """Information about WB's capabilities with regards to save file
        viewing and editing for this game."""
        canReadBasic = True  # Can read the info needed for the Save Tab display
        canEditMore = False  # Advanced editing
        ext = u'.ess'  # Save file extension

    class Bsa(object):
        """Information about the BSAs (Bethesda Archives) used by this game."""
        # Whether or not the INI setting ResetBSATimestamps should have any
        # effect on this game
        allow_reset_timestamps = False
        # Part of a regex used to determine which BSAs will attach to a plugin.
        # The full regex prepends the base name of the plugin (e.g. for
        # MyMod.esp, MyMod will be prepended) and appends Bsa.bsa_extension.
        # Most games accept arbitrary BSA names, hence this default
        attachment_regex = r'(?: \- \w+)?'
        # The extension used for BSA files
        bsa_extension = u'.bsa'
        # Whether or not the Archive.exe tool for this game creates BSL files
        has_bsl = False
        # Maps BSA names to the date to which they should be redated. Fallback
        # will be used for BSAs which are not explicitly listed. Format is
        # ISO 8601 (year-month-day)
        redate_dict = defaultdict(lambda: u'2006-01-01')
        # All BSA versions accepted by this game. If empty, indicates that this
        # game does not use BSA versions and so BSA version checks will be
        # skipped entirely.
        valid_versions = set()
        # Maps vanilla plugin names to the BSA that contain their localization
        # strings
        vanilla_string_bsas = {}

    class Psc(object):
        """Information about script sources (only Papyrus right now) for this
        game."""
        # Extensions for external script sources. Empty if this game doesn't
        # have any.
        source_extensions = set()
        # Maps directories from which BAIN should redirect script sources from
        # to the directories that BAIN should redirect them to. Empty if this
        # is not applicable to this game.
        source_redirects = {}

    class Xe(object):
        """Information about xEdit for this game."""
        # The name that xEdit has for this game, e.g. 'TES5Edit' for Skyrim
        full_name = u'xEdit'
        # A prefix for settings keys related to this version of xEdit (e.g.
        # expert mode)
        xe_key_prefix = u''

    class Bain(object):
        """Information about what BAIN should do for this game."""
        # The allowed default data directories that BAIN can install to
        data_dirs = {
            u'ini', u'meshes', u'music', u'sound', u'textures', u'video'
        }
        # Directories in the Data folder to exclude from Clean Data
        keep_data_dirs = set()
        # Files in the Data folder to exclude from Clean Data
        keep_data_files = set()
        # File prefixes in the Data folder to exclude from Clean Data
        keep_data_file_prefixes = set()
        # Files BAIN shouldn't skip
        no_skip = ()
        # Directories where specific file extensions should not be skipped
        no_skip_dirs = {}
        # Folders BAIN should never CRC check in the Data directory
        skip_bain_refresh = set(
            # Use lowercase names
        )
        # Wrye Bash files to exclude from Clean Data
        wrye_bash_data_files = set()
        # Wrye Bash directories to exclude from Clean Data
        wrye_bash_data_dirs = {u'Bash Patches', u'BashTags', u'INI Tweaks'}

    # Plugin format stuff
    class Esp(object):
        # Wrye Bash capabilities
        canBash = False  # Can create Bashed Patches
        canCBash = False  # CBash can handle this game's records
        canEditHeader = False  # Can edit basic info in the main header
        # record - generally has signature 'TES4'
        # Valid ESM/ESP header versions
        #  These are the valid 'version' numbers for the game file headers
        validHeaderVersions = tuple()
        # used to locate string translation files
        stringsFiles = [
            ((u'Strings', ), u'%(body)s_%(language)s.STRINGS'),
            ((u'Strings', ), u'%(body)s_%(language)s.DLSTRINGS'),
            ((u'Strings', ), u'%(body)s_%(language)s.ILSTRINGS'),
        ]
        # Signature of the main plugin header record type
        plugin_header_sig = b'TES4'
        # If True, then plugins with at least one master can use the
        # 0x000-0x800 range for their own records.
        # If False, that range is reserved for hardcoded engine records.
        expanded_plugin_range = False
        # If True, check if the main header's DATA subrecords match the on-disk
        # master sizes and highlight the corresponding masters with a light
        # background color if that is the case. Needs meaningful information in
        # the DATA subrecords.
        check_master_sizes = False
        # If True, generate ONAM by reading each temp CELL child when adding
        # the ESM flag to plugins and discard it when removing the ESM flag.
        generate_temp_child_onam = False
        # The maximum number of entries inside a leveled list for this game.
        # Zero means no limit.
        max_lvl_list_size = 0

    # Bash Tags supported by this game
    allTags = set()

    # Patcher available when building a Bashed Patch (referenced by class name)
    # PatchMerger must come first if enabled, see
    # patcher.base.APatchMerger.__init__
    patchers = ()

    # CBash patchers available when building a Bashed Patch
    CBash_patchers = ()  # CBash_PatchMerger must come first if enabled!

    # Magic Info
    weaponTypes = ()

    # Race Info, used in faces.py
    raceNames = {}
    raceShortNames = {}
    raceHairMale = {}
    raceHairFemale = {}

    # Record information - set in cls.init ------------------------------------
    # Mergeable record types
    mergeClasses = ()
    # Extra read classes: these record types will always be loaded, even if
    # patchers don't need them directly (for example, for MGEF info)
    readClasses = ()
    writeClasses = ()

    # Class attributes moved to constants module, set dynamically at init
    #--Game ESM/ESP/BSA files
    ## These are all of the ESM,ESP,and BSA data files that belong to the game
    ## These filenames need to be in lowercase,
    bethDataFiles = set()  # initialize with literal

    # Function Info -----------------------------------------------------------
    # CTDA Data for the game. Maps function ID to tuple with name of function
    # and the parameter types of the function.
    # 0: no param; 1: int param; 2: formid param; 3: float param
    # Note that each line must have the same number of parameters after the
    # function name - so pad out functions with fewer parameters with zeroes
    condition_function_data = {}
    # The function index for the GetVATSValue function. This function is
    # special, because the type of its second parameter depends on the value of
    # the first parameter.
    getvatsvalue_index = 0

    # Known record types - maps integers from the save format to human-readable
    # names for the record types. Used in save editing code.
    save_rec_types = {}

    #--List of GMST's in the main plugin (Oblivion.esm) that have 0x00000000
    #  as the form id.  Any GMST as such needs it Editor Id listed here.
    gmstEids = []
    """
    GLOB record tweaks used by patcher.patchers.multitweak_settings.GmstTweaker

    Each entry is a tuple in the following format:
      (DisplayText, MouseoverText, GLOB EditorID, Option1, Option2, ...,
      OptionN)
      -EditorID can be a plain string, or a tuple of multiple Editor IDs.
      If it's a tuple, then Value (below) must be a tuple of equal length,
      providing values for each GLOB
    Each Option is a tuple:
      (DisplayText, Value)
      - If you enclose DisplayText in brackets like this: _(u'[Default]'),
      then the patcher will treat this option as the default value.
      - If you use _(u'Custom') as the entry, the patcher will bring up a
      number input dialog

    To make a tweak Enabled by Default, enclose the tuple entry for the
    tweak in a list, and make a dictionary as the second list item with {
    'defaultEnabled ':True}. See the UOP Vampire face fix for an example of
    this (in the GMST Tweaks)
    """
    GlobalsTweaks = []
    """
    GMST record tweaks used by patcher.patchers.multitweak_settings.GmstTweaker

    Each entry is a tuple in the following format:
      (DisplayText, MouseoverText, GMST EditorID, Option1, Option2, ...,
      OptionN)
      - EditorID can be a plain string, or a tuple of multiple Editor IDs.
      If it's a tuple, then Value (below) must be a tuple of equal length,
      providing values for each GMST
    Each Option is a tuple:
      (DisplayText, Value)
      - If you enclose DisplayText in brackets like this: _(u'[Default]'),
      then the patcher will treat this option as the default value.
      - If you use _(u'Custom') as the entry, the patcher will bring up a
      number input dialog

    To make a tweak Enabled by Default, enclose the tuple entry for the
    tweak in a list, and make a dictionary as the second list item with {
    'defaultEnabled ':True}. See the UOP Vampire facefix for an example of
    this (in the GMST Tweaks)
    """
    GmstTweaks = []

    #--------------------------------------------------------------------------
    # ListsMerger patcher (leveled list patcher)
    #--------------------------------------------------------------------------
    listTypes = ()

    #--------------------------------------------------------------------------
    # NamesPatcher
    #--------------------------------------------------------------------------
    namesTypes = set()  # initialize with literal

    #--------------------------------------------------------------------------
    # ItemPrices Patcher
    #--------------------------------------------------------------------------
    pricesTypes = {}

    #--------------------------------------------------------------------------
    # StatsImporter
    #--------------------------------------------------------------------------
    statsTypes = {}
    statsHeaders = ()

    #--------------------------------------------------------------------------
    # SoundPatcher
    #--------------------------------------------------------------------------
    # Needs longs in SoundPatcher
    soundsLongsTypes = set()  # initialize with literal
    soundsTypes = {}

    #--------------------------------------------------------------------------
    # CellImporter
    #--------------------------------------------------------------------------
    cellAutoKeys = set()  # use a set literal
    cellRecAttrs = {}
    cellRecFlags = {}
    cell_float_attrs = set()

    #--------------------------------------------------------------------------
    # GraphicsPatcher
    #--------------------------------------------------------------------------
    graphicsTypes = {}
    graphicsFidTypes = {}
    graphicsModelAttrs = ()

    #--------------------------------------------------------------------------
    # Inventory Patcher
    #--------------------------------------------------------------------------
    inventoryTypes = ()

    #--------------------------------------------------------------------------
    # Race Patcher
    #--------------------------------------------------------------------------
    default_eyes = {}

    #--------------------------------------------------------------------------
    # Keywords Patcher
    #--------------------------------------------------------------------------
    keywords_types = ()

    #--------------------------------------------------------------------------
    # Text Patcher
    #--------------------------------------------------------------------------
    text_long_types = set()
    text_types = {}

    #--------------------------------------------------------------------------
    # Object Bounds Patcher
    #--------------------------------------------------------------------------
    object_bounds_types = set()

    #--------------------------------------------------------------------------
    # Contents Checker
    #--------------------------------------------------------------------------
    cc_valid_types = {}
    # (targeted types, structs/groups name, entry/item name)
    # OR (targeted types, fid list name)
    cc_passes = ()

    #--------------------------------------------------------------------------
    # Scripts Patcher
    #--------------------------------------------------------------------------
    scripts_types = set()

    #--------------------------------------------------------------------------
    # Destructible Patcher
    #--------------------------------------------------------------------------
    destructible_types = set()

    #--------------------------------------------------------------------------
    # Actor Patchers
    #--------------------------------------------------------------------------
    actor_importer_attrs = {}
    actor_types = ()

    #--------------------------------------------------------------------------
    # Spell Stats Patcher
    #--------------------------------------------------------------------------
    spell_stats_attrs = ()

    #--------------------------------------------------------------------------
    # Actor Tweaker
    #--------------------------------------------------------------------------
    actor_tweaks = set()

    #--------------------------------------------------------------------------
    # Assorted Tweaker
    #--------------------------------------------------------------------------
    nirnroots = _(u'Nirnroots')

    #--------------------------------------------------------------------------
    # Names Tweaker
    #--------------------------------------------------------------------------
    body_tags = u''

    #--------------------------------------------------------------------------
    # Relations Patcher
    #--------------------------------------------------------------------------
    relations_attrs = ()
    relations_csv_header = u''
    relations_csv_row_format = u''

    #--------------------------------------------------------------------------
    # Enchantment Stats Patcher
    #--------------------------------------------------------------------------
    ench_stats_attrs = ()

    #--------------------------------------------------------------------------
    # Effect Stats Patcher
    #--------------------------------------------------------------------------
    mgef_stats_attrs = ()

    #--------------------------------------------------------------------------
    # Magic Effects - Oblivion-specific
    #--------------------------------------------------------------------------
    # Doesn't list MGEFs that use actor values, but rather MGEFs that have a
    # generic name.
    # Ex: Absorb Attribute becomes Absorb Magicka if the effect's actorValue
    #     field contains 9, but it is actually using an attribute rather than
    #     an actor value
    # Ex: Burden uses an actual actor value (encumbrance) but it isn't listed
    #     since its name doesn't change
    generic_av_effects = set()
    # MGEFs that are considered hostile
    hostile_effects = set()
    # Maps MGEF signatures to certain MGEF properties
    mgef_basevalue = dict()
    mgef_name = dict()
    mgef_school = dict()

    # Human-readable names for each actor value
    actor_values = []

    # Record type to name dictionary
    record_type_name = {}

    # Set in game/*/default_tweaks.py, this is a dictionary mapping names for
    # 'default' INI tweaks (i.e. ones that we ship with WB and that can't be
    # deleted) to OrderedDicts that implement the actual tweaks. See
    # DefaultIniFile.__init__ for how the tweaks are parsed.
    default_tweaks = {}

    # Set in game/*/vanilla_files.py, this is a set listing every file that
    # exists in the Data directory of the game in a purely vanilla
    # installation. Set in a separate file because this can be *very* large,
    # and would make editing the constants a miserable experience if included
    # (see e.g. skyrim/vanilla_files.py).
    vanilla_files = set()

    @property
    def plugin_header_class(self):
        return brec.MreRecord.type_class[self.Esp.plugin_header_sig]

    # Set in game/*/patcher.py used in Mopy/bash/basher/gui_patchers.py
    gameSpecificPatchers = {}
    gameSpecificListPatchers = {}
    game_specific_import_patchers = {}

    # Import from the constants module ----------------------------------------
    # Class attributes moved to constants module, set dynamically at init
    _constants_members = {
        u'GlobalsTweaks',
        u'GmstTweaks',
        u'actor_importer_attrs',
        u'actor_tweaks',
        u'actor_types',
        u'actor_values',
        u'bethDataFiles',
        u'body_tags',
        u'cc_valid_types',
        u'cc_passes',
        u'cellAutoKeys',
        u'cell_float_attrs',
        u'cellRecAttrs',
        u'cellRecFlags',
        u'condition_function_data',
        u'default_eyes',
        u'destructible_types',
        u'ench_stats_attrs',
        u'generic_av_effects',
        u'getvatsvalue_index',
        u'gmstEids',
        u'graphicsFidTypes',
        u'graphicsModelAttrs',
        u'graphicsTypes',
        u'hostile_effects',
        u'inventoryTypes',
        u'keywords_types',
        u'listTypes',
        u'mgef_basevalue',
        u'mgef_name',
        u'mgef_school',
        u'mgef_stats_attrs',
        u'namesTypes',
        u'nirnroots',
        u'object_bounds_types',
        u'pricesTypes',
        u'record_type_name',
        u'relations_attrs',
        u'relations_csv_header',
        u'relations_csv_row_format',
        u'save_rec_types',
        u'scripts_types',
        u'soundsLongsTypes',
        u'soundsTypes',
        u'spell_stats_attrs',
        u'statsHeaders',
        u'statsTypes',
        u'text_long_types',
        u'text_types',
    }

    @classmethod
    def init(cls):
        # Setting RecordHeader class variables --------------------------------
        # Top types in order of the main ESM
        header_type = brec.RecordHeader
        header_type.top_grup_sigs = []
        header_type.valid_header_sigs = set(header_type.top_grup_sigs +
                                            [b'GRUP', b'TES4'])
        # Record Types
        brec.MreRecord.type_class = {x.rec_sig: x for x in ()}
        # Simple records
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) -
                                      {b'TES4'})
        cls._validate_records()

    @classmethod
    def _dynamic_import_modules(cls, package_name):
        """Dynamically import package modules to avoid importing them for every
        game. We need to pass the package name in for importlib to work.
        Currently populates the GameInfo namespace with the members defined in
        the relevant constants.py and imports default_tweaks.py and
        vanilla_files.py."""
        constants = importlib.import_module('.constants', package=package_name)
        for k in dir(constants):
            if k.startswith('_'): continue
            if k not in cls._constants_members:
                raise RuntimeError(u'Unexpected game constant %s' % k)
            setattr(cls, k, getattr(constants, k))
        tweaks_module = importlib.import_module('.default_tweaks',
                                                package=package_name)
        cls.default_tweaks = tweaks_module.default_tweaks
        vf_module = importlib.import_module('.vanilla_files',
                                            package=package_name)
        cls.vanilla_files = vf_module.vanilla_files
        patchers_module = importlib.import_module('.patcher',
                                                  package=package_name)
        cls.gameSpecificPatchers = patchers_module.gameSpecificPatchers
        cls.gameSpecificListPatchers = patchers_module.gameSpecificListPatchers
        cls.game_specific_import_patchers = \
            patchers_module.game_specific_import_patchers

    @staticmethod
    def _validate_records():
        """Performs validation on the record syntax for all decoded records."""
        for rec_class in brec.MreRecord.type_class.itervalues():
            if issubclass(rec_class, brec.MelRecord):
                rec_class.validate_record_syntax()
Example #33
0
class Fallout4GameInfo(PatchGame):
    displayName = u'Fallout 4'
    fsName = u'Fallout4'
    altName = u'Wrye Flash'
    game_icon = u'fallout4_%u.png'
    bash_root_prefix = u'Fallout4'
    bak_game_name = u'Fallout4'
    my_games_name = u'Fallout4'
    appdata_name = u'Fallout4'
    launch_exe = u'Fallout4.exe'
    game_detect_includes = [u'Fallout4.exe']
    game_detect_excludes = WS_COMMON
    version_detect_file = u'Fallout4.exe'
    master_file = u'Fallout4.esm'
    taglist_dir = u'Fallout4'
    loot_dir = u'Fallout4'
    regInstallKeys = (u'Bethesda Softworks\\Fallout4', u'Installed Path')
    nexusUrl = u'https://www.nexusmods.com/fallout4/'
    nexusName = u'Fallout 4 Nexus'
    nexusKey = u'bash.installers.openFallout4Nexus.continue'

    espm_extensions = GameInfo.espm_extensions | {u'.esl'}
    has_achlist = True
    check_esl = True
    plugin_name_specific_dirs = GameInfo.plugin_name_specific_dirs + [
        _j(u'meshes', u'actors', u'character', u'facegendata', u'facegeom'),
        _j(u'meshes', u'actors', u'character', u'facecustomization')
    ]

    class Ck(GameInfo.Ck):
        ck_abbrev = u'CK'
        long_name = u'Creation Kit'
        exe = u'CreationKit.exe'
        image_name = u'creationkit%s.png'

    class Se(GameInfo.Se):
        se_abbrev = u'F4SE'
        long_name = u'Fallout 4 Script Extender'
        exe = u'f4se_loader.exe'
        ver_files = [u'f4se_loader.exe', u'f4se_steam_loader.dll']
        plugin_dir = u'F4SE'
        cosave_tag = u'F4SE'
        cosave_ext = u'.f4se'
        url = u'http://f4se.silverlock.org/'
        url_tip = u'http://f4se.silverlock.org/'

    class Ini(GameInfo.Ini):
        default_ini_file = u'Fallout4_default.ini'
        dropdown_inis = [u'Fallout4.ini', u'Fallout4Prefs.ini']
        resource_archives_keys = (u'sResourceIndexFileList',
                                  u'sResourceStartUpArchiveList',
                                  u'sResourceArchiveList',
                                  u'sResourceArchiveList2',
                                  u'sResourceArchiveListBeta')

    class Ess(GameInfo.Ess):
        ext = u'.fos'

    class Bsa(GameInfo.Bsa):
        bsa_extension = u'.ba2'
        valid_versions = {0x01}

    class Psc(GameInfo.Psc):
        source_extensions = {u'.psc'}

    class Xe(GameInfo.Xe):
        full_name = u'FO4Edit'
        xe_key_prefix = u'fo4View'

    class Bain(GameInfo.Bain):
        data_dirs = GameInfo.Bain.data_dirs | {
            u'f4se',
            u'interface',
            u'lodsettings',
            u'materials',
            u'mcm',  # FO4 MCM
            u'misc',
            u'programs',
            u'scripts',
            u'seq',
            u'shadersfx',
            u'strings',
            u'tools',  # bodyslide
            u'vis',
        }
        no_skip_dirs = GameInfo.Bain.no_skip_dirs.copy()  # PY3: dict join
        no_skip_dirs.update({
            # This rule is to allow mods with string translation enabled.
            _j(u'interface', u'translations'): [u'.txt']
        })
        skip_bain_refresh = {u'fo4edit backups', u'fo4edit cache'}

    class Esp(GameInfo.Esp):
        canBash = True
        canEditHeader = True
        validHeaderVersions = (0.95, 1.0)
        expanded_plugin_range = True
        max_lvl_list_size = 255
        reference_types = {
            b'ACHR', b'PARW', b'PBAR', b'PBEA', b'PCON', b'PFLA', b'PGRE',
            b'PHZD', b'PMIS', b'REFR'
        }

    patchers = {
        u'ImportObjectBounds',
        u'LeveledLists',
    }

    bethDataFiles = {
        #--Vanilla
        u'fallout4.esm',
        u'fallout4.cdx',
        u'fallout4 - animations.ba2',
        u'fallout4 - geometry.csg',
        u'fallout4 - interface.ba2',
        u'fallout4 - materials.ba2',
        u'fallout4 - meshes.ba2',
        u'fallout4 - meshesextra.ba2',
        u'fallout4 - misc.ba2',
        u'fallout4 - nvflex.ba2',
        u'fallout4 - shaders.ba2',
        u'fallout4 - sounds.ba2',
        u'fallout4 - startup.ba2',
        u'fallout4 - textures1.ba2',
        u'fallout4 - textures2.ba2',
        u'fallout4 - textures3.ba2',
        u'fallout4 - textures4.ba2',
        u'fallout4 - textures5.ba2',
        u'fallout4 - textures6.ba2',
        u'fallout4 - textures7.ba2',
        u'fallout4 - textures8.ba2',
        u'fallout4 - textures9.ba2',
        u'fallout4 - voices.ba2',
        u'dlcrobot.esm',
        u'dlcrobot.cdx',
        u'dlcrobot - geometry.csg',
        u'dlcrobot - main.ba2',
        u'dlcrobot - textures.ba2',
        u'dlcrobot - voices_en.ba2',
        u'dlcworkshop01.esm',
        u'dlcworkshop01.cdx',
        u'dlcworkshop01 - geometry.csg',
        u'dlcworkshop01 - main.ba2',
        u'dlcworkshop01 - textures.ba2',
        u'dlccoast.esm',
        u'dlccoast.cdx',
        u'dlccoast - geometry.csg',
        u'dlccoast - main.ba2',
        u'dlccoast - textures.ba2',
        u'dlccoast - voices_en.ba2',
        u'dlcworkshop02.esm',
        u'dlcworkshop02 - main.ba2',
        u'dlcworkshop02 - textures.ba2',
        u'dlcworkshop03.esm',
        u'dlcworkshop03.cdx',
        u'dlcworkshop03 - geometry.csg',
        u'dlcworkshop03 - main.ba2',
        u'dlcworkshop03 - textures.ba2',
        u'dlcworkshop03 - voices_en.ba2',
        u'dlcnukaworld.esm',
        u'dlcnukaworld.cdx',
        u'dlcnukaworld - geometry.csg',
        u'dlcnukaworld - main.ba2',
        u'dlcnukaworld - textures.ba2',
        u'dlcnukaworld - voices_en.ba2',
    }

    @classmethod
    def init(cls):
        cls._dynamic_import_modules(__name__)
        from .records import MreGmst, MreTes4, MreLvli, MreLvln
        cls.mergeable_sigs = {
            clazz.rec_sig: clazz
            for clazz in (MreGmst, MreLvli, MreLvln)
        }
        # Setting RecordHeader class variables --------------------------------
        header_type = brec.RecordHeader
        header_type.top_grup_sigs = [
            b'GMST',
            b'KYWD',
            b'LCRT',
            b'AACT',
            b'TRNS',
            b'CMPO',
            b'TXST',
            b'GLOB',
            b'DMGT',
            b'CLAS',
            b'FACT',
            b'HDPT',
            b'RACE',
            b'SOUN',
            b'ASPC',
            b'MGEF',
            b'LTEX',
            b'ENCH',
            b'SPEL',
            b'ACTI',
            b'TACT',
            b'ARMO',
            b'BOOK',
            b'CONT',
            b'DOOR',
            b'INGR',
            b'LIGH',
            b'MISC',
            b'STAT',
            b'SCOL',
            b'MSTT',
            b'GRAS',
            b'TREE',
            b'FLOR',
            b'FURN',
            b'WEAP',
            b'AMMO',
            b'NPC_',
            b'PLYR',
            b'LVLN',
            b'KEYM',
            b'ALCH',
            b'IDLM',
            b'NOTE',
            b'PROJ',
            b'HAZD',
            b'BNDS',
            b'TERM',
            b'LVLI',
            b'WTHR',
            b'CLMT',
            b'SPGD',
            b'RFCT',
            b'REGN',
            b'NAVI',
            b'CELL',
            b'WRLD',
            b'QUST',
            b'IDLE',
            b'PACK',
            b'CSTY',
            b'LSCR',
            b'LVSP',
            b'ANIO',
            b'WATR',
            b'EFSH',
            b'EXPL',
            b'DEBR',
            b'IMGS',
            b'IMAD',
            b'FLST',
            b'PERK',
            b'BPTD',
            b'ADDN',
            b'AVIF',
            b'CAMS',
            b'CPTH',
            b'VTYP',
            b'MATT',
            b'IPCT',
            b'IPDS',
            b'ARMA',
            b'ECZN',
            b'LCTN',
            b'MESG',
            b'DOBJ',
            b'DFOB',
            b'LGTM',
            b'MUSC',
            b'FSTP',
            b'FSTS',
            b'SMBN',
            b'SMQN',
            b'SMEN',
            b'DLBR',
            b'MUST',
            b'DLVW',
            b'EQUP',
            b'RELA',
            b'SCEN',
            b'ASTP',
            b'OTFT',
            b'ARTO',
            b'MATO',
            b'MOVT',
            b'SNDR',
            b'SNCT',
            b'SOPM',
            b'COLL',
            b'CLFM',
            b'REVB',
            b'PKIN',
            b'RFGP',
            b'AMDL',
            b'LAYR',
            b'COBJ',
            b'OMOD',
            b'MSWP',
            b'ZOOM',
            b'INNR',
            b'KSSM',
            b'AECH',
            b'SCCO',
            b'AORU',
            b'SCSN',
            b'STAG',
            b'NOCM',
            b'LENS',
            b'GDRY',
            b'OVIS',
        ]
        header_type.valid_header_sigs = (set(header_type.top_grup_sigs) | {
            b'GRUP', b'TES4', b'REFR', b'ACHR', b'PMIS', b'PARW', b'PGRE',
            b'PBEA', b'PFLA', b'PCON', b'PBAR', b'PHZD', b'LAND', b'NAVM',
            b'DIAL', b'INFO'
        })
        header_type.plugin_form_version = 131
        brec.MreRecord.type_class = {
            x.rec_sig: x
            for x in (
                MreTes4,
                MreGmst,
                MreLvli,
                MreLvln,
            )
        }
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) -
                                      {b'TES4'})
        cls._validate_records()
Example #34
0
 def get_variable_path(ParserKlass, src_files, bench_name):
     pretty_base = "{base}.variable.pretty.txt".format(base=_b(src_files.get('profile_path', bench_name)))
     return _j(_d(src_files.get('profile_path', bench_name)), pretty_base)
Example #35
0
 def _profiling_overhead_agg_csv_path(self):
     return _j(self.directory,
               "overall_training_progress.profiling_overhead.agg.csv")
Example #36
0
 def plot_index_path(self):
     return _j(self.out_dir, self.basename)
Example #37
0
 def workers_dir(self, algo, env, num_workers):
     return _j(self.root_directory, algo, env,
               "num_workers_{n}".format(n=num_workers))
Example #38
0
class GameInfo(object):
    # Main game info - should be overridden -----------------------------------
    # Name of the game to use in UI.
    displayName = u''  ## Example: u'Skyrim'
    # A name used throughout the codebase for identifying the current game in
    # various situations, e.g. to decide which BSAs to use, which save header
    # types to use, etc.
    fsName = u''  ## Example: u'Skyrim'
    # Alternate display name of Wrye Bash when managing this game
    altName = u''  ## Example: u'Wrye Smash'
    # Name of the icon to use for the game, including a %u specifier for the
    # icon size (16/24/32)
    game_icon = u''  ## Example: u'skyrim_%u.png'
    # Name of the prefix of the '<X> Mods' folder, i.e. <X> is this string.
    # Preferably pick a single word without spaces here, but don't change it
    # once set due to backwards compatibility (duh)
    bash_root_prefix = u''  ## Example: u'Skyrim'
    # Name of the prefix for the game folder inside created backups and for
    # naming backups. Should not be changed once set, otherwise restoring old
    # backups will no longer work
    bak_game_name = u''
    # The name of the directory, relative to Mopy/templates, in which the BSA
    # redirection template for this game is placed. This folder is
    # *deprecated*, see issue #519
    template_dir = u''
    # The name of the directory, relative to Mopy/Bash Patches, in which
    # default Bashed Patch resource files (e.g. CSV files) are stored. If
    # empty, indicates that WB does not come with any such files for this game
    bash_patches_dir = u''
    # True if the game uses the 'My Documents' folder, False to just use the
    # game path
    uses_personal_folders = True
    # Name of the folder in My Documents\My Games that holds this game's data
    # (saves, INIs, etc.)
    my_games_name = u''
    # Name of the game's AppData folder, relative to %LocalAppData%
    appdata_name = u''
    # The exe to use when launching the game (without xSE present)
    launch_exe = u''  ## Example: u'TESV.exe'
    # Path to one or more files to look for to see if this is the right game
    # when joined with the game's root path (i.e. the one above the Data
    # folder). The combination of these files must be unique among all games.
    # As a rule of thumb, use the file you specified in launch_exe, unless that
    # file is shared by multiple games, in which case you MUST find unique
    # files - for an example, see Enderal and Skyrim (and the SE versions of
    # both).
    game_detect_includes = []
    # Path to one or more files to look for to see if this is *not* the right
    # game when joined with the game's root path. Used to differentia between
    # versions of the game distributed on different platforms (Windows Store).
    game_detect_excludes = []
    # Path to a file to pass to env.get_file_version to determine the game's
    # version. Usually the same as launch_exe, but some games need different
    # ones here (e.g. Enderal, which has Skyrim's version in the launch_exe,
    # and therefore needs a different file here).
    version_detect_file = u''
    # The main plugin Wrye Bash should look for
    master_file = u''
    # The directory in which mods and other data files reside. This is relative
    # to the game directory.
    mods_dir = u'Data'
    # The name of the directory containing the taglist for this game, relative
    # to 'Mopy/taglists'
    taglist_dir = u''
    # The name of the directory that LOOT writes its masterlist into, relative
    # to '%LocalAppData%\LOOT'
    loot_dir = u''
    # The name that this game has on the BOSS command line. If empty, indicates
    # that BOSS does not support this game
    boss_game_name = u''
    # Registry keys to read to find the install location
    # These are relative to:
    #  HKLM\Software
    #  HKLM\Software\Wow6432Node
    #  HKCU\Software
    #  HKCU\Software\Wow6432Node
    # Example: (u'Bethesda Softworks\\Oblivion', u'Installed Path')
    regInstallKeys = ()
    # URL to the Nexus site for this game
    nexusUrl = u''  # URL
    nexusName = u''  # Long Name
    nexusKey = u''  # Key for the "always ask this question" setting in
    # settings.dat

    # Additional game info - override as needed -------------------------------
    # URL to download patches for the main game.
    patchURL = u''
    # Tooltip to display over the URL when displayed
    patchTip = u'Update via Steam'
    # plugin extensions
    espm_extensions = {u'.esm', u'.esp', u'.esu'}
    # Load order info
    using_txt_file = True
    # bethesda net export files
    has_achlist = False
    # check if a plugin is convertible to a light master instead of checking
    # mergeability
    check_esl = False
    # Whether or not this game has standalone .pluggy cosaves
    has_standalone_pluggy = False
    # Information about Plugin-Name-specific Directories supported by this
    # game. Some examples are sound\voices\PLUGIN_NAME.esp, or the facegendata
    # ones. An empty list means that the game does not have any such
    # directories.
    plugin_name_specific_dirs = [_j(u'sound', u'voice')]

    def __init__(self, gamePath):
        self.gamePath = gamePath  # absolute bolt Path to the game directory
        self.has_esl = u'.esl' in self.espm_extensions

    class Ws(object):
        """Information about this game on the Windows Store."""
        # A list of directory names for different language versions that ship
        # with this game. Each one acts as a separate game installation under
        # the main Windows Store path. If empty, indicates that the Windows
        # Store location is the game installtion
        game_language_dirs = []
        # The publisher name for common games. Currently only 'Bethesda' is
        # allowed for Bethesda games. If specified, publisher_id is not
        # required
        publisher_name = u''
        # The publisher ID for the publisher of the game. Required except for
        # common publishers supported above. For example, Bethesda's publisher
        # ID is '3275kfvn8vcwc'
        publisher_id = u''
        # The internal name used by the Windows Store to identify the game.
        # For example, Morrowind is 'BethesdaSofworks.TESMorrowind-PC'
        win_store_name = u''

    class Ck(object):
        """Information about the official plugin editor (generally called some
        variation of 'Creation Kit') for this game."""
        # Abbreviated name
        ck_abbrev = u''
        # Full name
        long_name = u''
        # Executable to run
        exe = u'*DNE*'
        # Argument to pass to the script extender to load the CK. If None,
        # indicates that this game's script extender does not have this feature
        se_args = None
        # Image name template for the status bar
        image_name = u''

    class Se(object):
        """Information about the Script Extender for this game."""
        # Abbreviated name. If this is empty, it signals that no xSE is
        # available for this game. Note that this should NEVER be used to
        # program other xSE behavior - create new variables like plugin_dir and
        # cosave_ext instead.
        se_abbrev = u''
        # Full name
        long_name = u''
        # Exe to run
        exe = u''
        # List of file names to use for version detection. Tried in order until
        # one exists. Needed because it's technically not required to install
        # the EXE.
        ver_files = []
        # One level above the directory in which xSE plugins should be placed
        # (e.g. when plugins should be in Data\OBSE\Plugins, this should be
        # u'OBSE')
        plugin_dir = u''
        # The magic tag that the cosaves use (e.g. u'SKSE'). If this is empty,
        # it signals that this script extender has no cosaves.
        cosave_tag = u''
        # The extension that the cosaves use (e.g. u'.skse')
        cosave_ext = u''
        # URL to download from
        url = u''
        # Tooltip for mouse over the URL
        url_tip = u''
        # A list of xSE plugins that fix the plugin/BSA handle problem. Empty
        # if that does not apply to this game.
        limit_fixer_plugins = []

    class Sd(object):
        """Information about Script Dragon for this game."""
        # Abbreviated name. If this is empty, it signals that no Script Dragon
        # is available for this game.
        sd_abbrev = u''
        # Full name
        long_name = u''
        # The directory, relative to the Data folder, into which Script Dragon
        # plugins will be installed.
        install_dir = u''

    class Sp(object):
        """Information about SkyProc patchers for this game."""
        # Abbreviated name. If this is empty, it signals that this game does
        # not support SkyProc patchers.
        sp_abbrev = u''
        # Full name
        long_name = u''
        # The directory, relative to the Data folder, into which SkyProc
        # patchers will be installed.
        install_dir = u''

    class Ge(object):
        """Information about the Graphics Extender for this game."""
        # Abbreviated name. If this is empty, it signals that no graphics
        # extender is available for this game.
        ge_abbrev = u''
        # Full name
        long_name = u''
        # exe is treated specially here.  If it is a string, then it should
        # be the path relative to the root directory of the game, if it is
        # a list, each list element should be an iterable to pass to Path.join
        # relative to the root directory of the game.  In this case,
        # each filename will be tested in reverse order.  This was required
        # for Oblivion, as the newer OBGE has a different filename than the
        # older OBGE
        exe = u''
        # URL to download from
        url = u''
        # Tooltip for mouse over the URL
        url_tip = u''

    class Laa(object):
        """Information about the LAA (Large Address Aware) launcher for this
        game."""
        # Display name of the launcher
        laa_name = u''
        # Executable to run
        exe = u'*DNE*'
        # Whether the launcher will automatically launch the SE
        launchesSE = False

    class Ini(object):
        """Information about this game's INI handling."""
        # True means new lines are allowed to be added via INI tweaks
        # (by default)
        allow_new_lines = True
        # INI Entry to enable BSA Redirection - two empty strings if this game
        # does not need BSA redirection
        bsa_redirection_key = (u'', u'')
        # Name of game's default ini file.
        default_ini_file = u''
        # INI files that should show up in the INI Edits tab. Note that the
        # first one *must* be the main INI!
        #  Example: [u'Oblivion.ini']
        dropdown_inis = []
        # INI setting used to setup Save Profiles
        #  (section, key)
        save_profiles_key = (u'General', u'SLocalSavePath')
        # Base dir for the save_profiles_key setting above
        save_prefix = u'Saves'
        # INI setting used to enable or disable screenshots
        #  (section, key, default value)
        screenshot_enabled_key = (u'Display', u'bAllowScreenShot', u'1')
        # INI setting used to set base screenshot name
        #  (section, key, default value)
        screenshot_base_key = (u'Display', u'sScreenShotBaseName',
                               u'ScreenShot')
        # INI setting used to set screenshot index
        #  (section, key, default value)
        screenshot_index_key = (u'Display', u'iScreenShotIndex', u'0')
        # The INI entries listing vanilla BSAs to load
        resource_archives_keys = ()
        # An INI key listing BSAs that will override all plugin BSAs. Blank if
        # it doesn't exist for this game
        resource_override_key = u''
        # The default value for resource_override_key if it's missing from the
        # game INI
        resource_override_defaults = []
        # Whether this game supports mod ini files aka ini fragments
        supports_mod_inis = True

    class Ess(object):
        """Information about WB's capabilities with regards to save file
        viewing and editing for this game."""
        # Can read the info needed for the Save Tab display
        canReadBasic = True
        # Advanced editing
        canEditMore = False
        # Save file extension
        ext = u'.ess'
        # If True, then this game will reliably and safely remove a missing
        # master from an existing save if you just load the game without that
        # master
        can_safely_remove_masters = False

    class Bsa(object):
        """Information about the BSAs (Bethesda Archives) used by this game."""
        # Whether or not the INI setting ResetBSATimestamps should have any
        # effect on this game
        allow_reset_timestamps = False
        # Part of a regex used to determine which BSAs will attach to a plugin.
        # The full regex prepends the base name of the plugin (e.g. for
        # MyMod.esp, MyMod will be prepended) and appends Bsa.bsa_extension.
        # Most games accept arbitrary BSA names, hence this default
        attachment_regex = r'(?: \- \w+)?'
        # The extension used for BSA files
        bsa_extension = u'.bsa'
        # Whether or not the Archive.exe tool for this game creates BSL files
        has_bsl = False
        # Maps BSA names to the date to which they should be redated. Fallback
        # will be used for BSAs which are not explicitly listed. Format is
        # ISO 8601 (year-month-day). Generally used to redate the vanilla BSAs
        # before all mod BSAs, and all BSAs before loose files by choosing
        # dates older than the game's release date.
        redate_dict = defaultdict(lambda: u'2006-01-01')
        # All BSA versions accepted by this game. If empty, indicates that this
        # game does not use BSA versions and so BSA version checks will be
        # skipped entirely.
        valid_versions = set()

    class Psc(object):
        """Information about script sources (only Papyrus right now) for this
        game."""
        # Extensions for external script sources. Empty if this game doesn't
        # have any.
        source_extensions = set()
        # Maps directories from which BAIN should redirect script sources from
        # to the directories that BAIN should redirect them to. Empty if this
        # is not applicable to this game.
        source_redirects = {}

    class Xe(object):
        """Information about xEdit for this game."""
        # The name that xEdit has for this game, e.g. 'TES5Edit' for Skyrim
        full_name = u'xEdit'
        # A prefix for settings keys related to this version of xEdit (e.g.
        # expert mode)
        xe_key_prefix = u''

    class Bain(object):
        """Information about what BAIN should do for this game."""
        # The allowed default data directories that BAIN can install to
        data_dirs = {
            u'ini', u'meshes', u'music', u'sound', u'textures', u'video'
        }
        # Directories in the Data folder to exclude from Clean Data
        keep_data_dirs = set()
        # Files in the Data folder to exclude from Clean Data
        keep_data_files = set()
        # File prefixes in the Data folder to exclude from Clean Data
        keep_data_file_prefixes = set()
        # Files BAIN shouldn't skip
        no_skip = ()
        # Directories where specific file extensions should not be skipped
        no_skip_dirs = {
            # BashTags files are obviously not docs, so don't skip them
            u'bashtags': [u'.txt'],
        }
        # Folders BAIN should never CRC check in the Data directory
        skip_bain_refresh = set(
            # Use lowercase names
        )
        # Wrye Bash files to exclude from Clean Data
        wrye_bash_data_files = set()
        # Wrye Bash directories to exclude from Clean Data
        wrye_bash_data_dirs = {u'Bash Patches', u'BashTags', u'INI Tweaks'}

    # Plugin format stuff
    class Esp(object):
        # Wrye Bash capabilities
        # Can create Bashed Patches
        canBash = False
        # Can edit basic info in the main header record - generally has
        # signature b'TES4'
        canEditHeader = False
        # Valid ESM/ESP header versions. These are the valid 'version' numbers
        # for the game file headers
        validHeaderVersions = tuple()
        # used to locate string translation files
        stringsFiles = [
            u'%(body)s_%(language)s.STRINGS',
            u'%(body)s_%(language)s.DLSTRINGS',
            u'%(body)s_%(language)s.ILSTRINGS',
        ]
        # Signature of the main plugin header record type
        plugin_header_sig = b'TES4'
        # If True, then plugins with at least one master can use the
        # 0x000-0x800 range for their own records.
        # If False, that range is reserved for hardcoded engine records.
        expanded_plugin_range = False
        # If True, check if the main header's DATA subrecords match the on-disk
        # master sizes and highlight the corresponding masters with a light
        # background color if that is the case. Needs meaningful information in
        # the DATA subrecords.
        check_master_sizes = False
        # If True, generate ONAM by reading each temp CELL child when adding
        # the ESM flag to plugins and discard it when removing the ESM flag.
        generate_temp_child_onam = False
        # The maximum number of entries inside a leveled list for this game.
        # Zero means no limit.
        max_lvl_list_size = 0
        # A tuple containing all biped flag names (in order) for this game
        biped_flag_names = ()
        # The maximum number of masters that a plugin can have for this game.
        master_limit = 255  # 256 - 1 for the plugin itself
        # All 'reference' types, i.e. record types that occur in CELL/WLRD
        # groups and place some sort of thing into the cell (e.g. ACHR, REFR,
        # PMIS, etc.)
        reference_types = set()

    # Class attributes moved to constants module, set dynamically at init
    #--Game ESM/ESP/BSA files
    ## These are all of the ESM,ESP,and BSA data files that belong to the game
    ## These filenames need to be in lowercase,
    bethDataFiles = set()  # initialize with literal

    # Known record types - maps integers from the save format to human-readable
    # names for the record types. Used in save editing code.
    save_rec_types = {}

    # Set in game/*/default_tweaks.py, this is a dictionary mapping names for
    # 'default' INI tweaks (i.e. ones that we ship with WB and that can't be
    # deleted) to OrderedDicts that implement the actual tweaks. See
    # DefaultIniFile.__init__ for how the tweaks are parsed.
    default_tweaks = {}

    # Set in game/*/vanilla_files.py, this is a set listing every file that
    # exists in the Data directory of the game in a purely vanilla
    # installation. Set in a separate file because this can be *very* large,
    # and would make editing the constants a miserable experience if included
    # (see e.g. skyrim/vanilla_files.py).
    vanilla_files = set()

    @property
    def plugin_header_class(self):
        return brec.MreRecord.type_class[self.Esp.plugin_header_sig]

    @classmethod
    def init(cls):
        # Setting RecordHeader class variables --------------------------------
        # Top types in order of the main ESM
        header_type = brec.RecordHeader
        header_type.top_grup_sigs = []
        header_type.valid_header_sigs = set(header_type.top_grup_sigs +
                                            [b'GRUP', b'TES4'])
        # Record Types
        brec.MreRecord.type_class = {x.rec_sig: x for x in ()}
        # Simple records
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) -
                                      {b'TES4'})
        cls._validate_records()

    @classmethod
    def _dynamic_import_modules(cls, package_name):
        """Dynamically import package modules to avoid importing them for every
        game. We need to pass the package name in for importlib to work.
        Currently populates the GameInfo namespace with the members defined in
        the relevant constants.py and imports default_tweaks.py and
        vanilla_files.py."""
        tweaks_module = importlib.import_module(u'.default_tweaks',
                                                package=package_name)
        cls.default_tweaks = tweaks_module.default_tweaks
        vf_module = importlib.import_module(u'.vanilla_files',
                                            package=package_name)
        cls.vanilla_files = vf_module.vanilla_files

    @staticmethod
    def _validate_records():
        """Performs validation on the record syntax for all decoded records."""
        sr_to_r = brec.MreRecord.subrec_sig_to_record_sig
        for rec_class in brec.MreRecord.type_class.itervalues():
            if issubclass(rec_class, brec.MelRecord):
                rec_class.validate_record_syntax()
                for sr_sig in rec_class.melSet.loaders:
                    sr_to_r[sr_sig].add(rec_class.rec_sig)

    @classmethod
    def supported_games(cls):
        game_types = set(cls.__subclasses__())
        game_types.update(
            chain.from_iterable(c.__subclasses__() for c in list(game_types)))
        return game_types

    @classmethod
    def test_game_path(cls, test_path):
        """Helper method to determine if required game detection files are
           present, and no excluded files are present, in the test path."""
        return (all(
            test_path.join(p).exists()
            for p in cls.game_detect_includes) and not any(
                test_path.join(p).exists() for p in cls.game_detect_excludes))
Example #39
0
from os.path import join as _j, abspath as _a, exists as _e, dirname as _d, basename as _b
from os import environ as ENV
import shutil
import re
import ctypes.util
import sys
import os
import textwrap

# NOTE: Don't import logger here since rlscope_logging needs py_config.
# from rlscope.profiler.rlscope_logging import logger
import rlscope

INSTALL_ROOT = _d(os.path.realpath(rlscope.__file__))

CPP_LIB = _j(INSTALL_ROOT, 'cpp', 'lib')
CPP_BIN = _j(INSTALL_ROOT, 'cpp', 'bin')
CPP_INCLUDE = _j(INSTALL_ROOT, 'cpp', 'include')

USE_NUMBA = False
nb = None
if USE_NUMBA:
  import numba as nb

ROOT = _d(_d(_a(__file__)))

RLSCOPE_DIR = ROOT

GIT_REPO_URL = "https://github.com/UofT-EcoSystem/rlscope"

RLSCOPE_TEST_DIR = _j(RLSCOPE_DIR, 'test_results')
Example #40
0
class OblivionGameInfo(GameInfo):
    displayName = u'Oblivion'
    fsName = u'Oblivion'
    altName = u'Wrye Bash'
    bash_root_prefix = u'Oblivion'
    launch_exe = u'Oblivion.exe'
    game_detect_file = _j(u'Data', u'Oblivion.esm')
    version_detect_file = u'Oblivion.exe'
    master_file = u'Oblivion.esm'
    pklfile = u'Oblivion_ids.pkl'
    masterlist_dir = u'Oblivion'
    regInstallKeys = (u'Bethesda Softworks\\Oblivion', u'Installed Path')
    nexusUrl = u'https://www.nexusmods.com/oblivion/'
    nexusName = u'Oblivion Nexus'
    nexusKey = 'bash.installers.openOblivionNexus.continue'

    patchURL = u'http://www.elderscrolls.com/downloads/updates_patches.htm'
    patchTip = u'http://www.elderscrolls.com/'

    using_txt_file = False
    has_standalone_pluggy = True

    class Ck(GameInfo.Ck):
        ck_abbrev = u'TESCS'
        long_name = u'Construction Set'
        exe = u'TESConstructionSet.exe'
        se_args = u'-editor'
        image_name = u'tescs%s.png'

    class Se(GameInfo.Se):
        se_abbrev = u'OBSE'
        long_name = u'Oblivion Script Extender'
        exe = u'obse_loader.exe'
        # Not sure why we need obse_1_2_416.dll, was there before refactoring
        ver_files = [
            u'obse_loader.exe', u'obse_steam_loader.dll', u'obse_1_2_416.dll'
        ]
        plugin_dir = u'OBSE'
        cosave_tag = u'OBSE'
        cosave_ext = u'.obse'
        url = u'http://obse.silverlock.org/'
        url_tip = u'http://obse.silverlock.org/'

    class Ge(GameInfo.Ge):
        ge_abbrev = u'OBGE'
        long_name = u'Oblivion Graphics Extender'
        exe = [
            (u'obse', u'plugins', u'obge.dll'),
            (u'obse', u'plugins', u'obgev2.dll'),
            (u'obse', u'plugins', u'oblivionreloaded.dll'),
        ]
        url = u'https://www.nexusmods.com/oblivion/mods/30054'
        url_tip = u'https://www.nexusmods.com/oblivion'

    class Ini(GameInfo.Ini):
        allow_new_lines = False
        bsa_redirection_key = (u'Archive', u'sArchiveList')
        default_ini_file = u'Oblivion_default.ini'
        dropdown_inis = [u'Oblivion.ini']
        supports_mod_inis = False

    class Ess(GameInfo.Ess):
        canEditMore = True

    class Bsa(GameInfo.Bsa):
        allow_reset_timestamps = True
        # Oblivion accepts the base name and literally *anything* after
        # that. E.g. MyModMeshes.bsa will load from a MyMod.esp plugin
        attachment_regex = u'.*'
        valid_versions = {0x67}

    class Xe(GameInfo.Xe):
        full_name = u'TES4Edit'
        xe_key_prefix = u'tes4View'

    class Bain(GameInfo.Bain):
        data_dirs = GameInfo.Bain.data_dirs | {
            u'_tejon',
            u'distantlod',
            u'facegen',
            u'fonts',
            u'menus',
            u'obse',
            u'pluggy',
            u'scripts',
            u'shaders',
            u'streamline',
            u'trees',
        }
        keep_data_dirs = {
            _j(u'OBSE', u'Plugins', u'ComponentDLLs', u'CSE'), u'LSData'
        }
        keep_data_files = {
            _j(u'OBSE', u'Plugins', u'Construction Set Extender.dll'),
            _j(u'OBSE', u'Plugins', u'Construction Set Extender.ini'),
        }
        keep_data_file_prefixes = {
            _j(u'Meshes', u'Characters', u'_Male', u'specialanims',
               u'0FemaleVariableWalk_'),
        }
        skip_bain_refresh = {
            u'tes4edit backups',
            u'tes4edit cache',
            u'bgsee',
            u'conscribe logs',
        }
        wrye_bash_data_files = {u'ArchiveInvalidationInvalidated!.bsa'}

    class Esp(GameInfo.Esp):
        canBash = True
        canCBash = True
        canEditHeader = True
        validHeaderVersions = (0.8, 1.0)
        stringsFiles = []

    allTags = {
        u'Actors.ACBS',
        u'Actors.AIData',
        u'Actors.AIPackages',
        u'Actors.AIPackagesForceAdd',
        u'Actors.Anims',
        u'Actors.CombatStyle',
        u'Actors.DeathItem',
        u'Actors.RecordFlags',
        u'Actors.Skeleton',
        u'Actors.Spells',
        u'Actors.SpellsForceAdd',
        u'Actors.Stats',
        u'Body-F',
        u'Body-M',
        u'Body-Size-F',
        u'Body-Size-M',
        u'C.Climate',
        u'C.Light',
        u'C.Music',
        u'C.Name',
        u'C.Owner',
        u'C.RecordFlags',
        u'C.Regions',
        u'C.Water',
        u'Creatures.Blood',
        u'Creatures.Type',
        u'Deactivate',
        u'Delev',
        u'EffectStats',
        u'EnchantmentStats',
        u'Eyes',
        u'Factions',
        u'Filter',
        u'Graphics',
        u'Hair',
        u'IIM',
        u'Invent.Add',
        u'Invent.Change',
        u'Invent.Remove',
        u'MustBeActiveIfImported',
        u'Names',
        u'NoMerge',
        u'NPC.Class',
        u'NPC.Eyes',
        u'NPC.FaceGen',
        u'NPC.Hair',
        u'NPC.Race',
        u'NpcFacesForceFullImport',
        u'R.AddSpells',
        u'R.Attributes-F',
        u'R.Attributes-M',
        u'R.ChangeSpells',
        u'R.Description',
        u'R.Ears',
        u'R.Head',
        u'R.Mouth',
        u'R.Relations',
        u'R.Skills',
        u'R.Teeth',
        u'Relations.Add',
        u'Relations.Change',
        u'Relations.Remove',
        u'Relev',
        u'Roads',
        u'Scripts',
        u'Sound',
        u'SpellStats',
        u'Stats',
        u'Text',
        u'Voice-F',
        u'Voice-M',
    }

    patchers = (
        u'PatchMerger',  # PatchMerger must come first!
        u'ActorImporter',
        u'AlchemicalCatalogs',
        u'AliasesPatcher',
        u'AssortedTweaker',
        u'CellImporter',
        u'ClothesTweaker',
        u'CoblExhaustion',
        u'ContentsChecker',
        u'DeathItemPatcher',
        u'GmstTweaker',
        u'GraphicsPatcher',
        u'ImportActorsSpells',
        u'ImportEffectsStats',
        u'ImportEnchantmentStats',
        u'ImportFactions',
        u'ImportInventory',
        u'ImportRelations',
        u'ImportScripts',
        u'KFFZPatcher',
        u'ListsMerger',
        u'MFactMarker',
        u'NamesPatcher',
        u'NamesTweaker',
        u'NPCAIPackagePatcher',
        u'NpcFacePatcher',
        u'RacePatcher',
        u'RoadImporter',
        u'SEWorldEnforcer',
        u'SoundPatcher',
        u'SpellsPatcher',
        u'StatsPatcher',
        u'TextImporter',
        u'TweakActors',
        u'UpdateReferences',
    )

    CBash_patchers = (
        u'CBash_PatchMerger',  # PatchMerger must come first!
        u'CBash_ActorImporter',
        u'CBash_AlchemicalCatalogs',
        u'CBash_AliasesPatcher',
        u'CBash_AssortedTweaker',
        u'CBash_CellImporter',
        u'CBash_ClothesTweaker',
        u'CBash_CoblExhaustion',
        u'CBash_ContentsChecker',
        u'CBash_DeathItemPatcher',
        u'CBash_GmstTweaker',
        u'CBash_GraphicsPatcher',
        u'CBash_ImportActorsSpells',
        u'CBash_ImportFactions',
        u'CBash_ImportInventory',
        u'CBash_ImportRelations',
        u'CBash_ImportScripts',
        u'CBash_KFFZPatcher',
        u'CBash_ListsMerger',
        u'CBash_MFactMarker',
        u'CBash_NamesPatcher',
        u'CBash_NamesTweaker',
        u'CBash_NPCAIPackagePatcher',
        u'CBash_NpcFacePatcher',
        u'CBash_RacePatcher',
        u'CBash_RoadImporter',
        u'CBash_SEWorldEnforcer',
        u'CBash_SoundPatcher',
        u'CBash_SpellsPatcher',
        u'CBash_StatsPatcher',
        u'CBash_TweakActors',
        u'CBash_UpdateReferences',
    )

    weaponTypes = (
        _(u'Blade (1 Handed)'),
        _(u'Blade (2 Handed)'),
        _(u'Blunt (1 Handed)'),
        _(u'Blunt (2 Handed)'),
        _(u'Staff'),
        _(u'Bow'),
    )

    raceNames = {
        0x23fe9: _(u'Argonian'),
        0x224fc: _(u'Breton'),
        0x191c1: _(u'Dark Elf'),
        0x19204: _(u'High Elf'),
        0x00907: _(u'Imperial'),
        0x22c37: _(u'Khajiit'),
        0x224fd: _(u'Nord'),
        0x191c0: _(u'Orc'),
        0x00d43: _(u'Redguard'),
        0x00019: _(u'Vampire'),
        0x223c8: _(u'Wood Elf'),
    }
    raceShortNames = {
        0x23fe9: u'Arg',
        0x224fc: u'Bre',
        0x191c1: u'Dun',
        0x19204: u'Alt',
        0x00907: u'Imp',
        0x22c37: u'Kha',
        0x224fd: u'Nor',
        0x191c0: u'Orc',
        0x00d43: u'Red',
        0x223c8: u'Bos',
    }
    raceHairMale = {
        0x23fe9: 0x64f32,  #--Arg
        0x224fc: 0x90475,  #--Bre
        0x191c1: 0x64214,  #--Dun
        0x19204: 0x7b792,  #--Alt
        0x00907: 0x90475,  #--Imp
        0x22c37: 0x653d4,  #--Kha
        0x224fd: 0x1da82,  #--Nor
        0x191c0: 0x66a27,  #--Orc
        0x00d43: 0x64215,  #--Red
        0x223c8: 0x690bc,  #--Bos
    }
    raceHairFemale = {
        0x23fe9: 0x64f33,  #--Arg
        0x224fc: 0x1da83,  #--Bre
        0x191c1: 0x1da83,  #--Dun
        0x19204: 0x690c2,  #--Alt
        0x00907: 0x1da83,  #--Imp
        0x22c37: 0x653d0,  #--Kha
        0x224fd: 0x1da83,  #--Nor
        0x191c0: 0x64218,  #--Orc
        0x00d43: 0x64210,  #--Red
        0x223c8: 0x69473,  #--Bos
    }

    @classmethod
    def init(cls):
        cls._dynamic_import_modules(__name__)
        from .records import MreActi, MreAlch, MreAmmo, MreAnio, MreAppa, \
            MreArmo, MreBook, MreBsgn, MreClas, MreClot, MreCont, MreCrea, \
            MreDoor, MreEfsh, MreEnch, MreEyes, MreFact, MreFlor, MreFurn, \
            MreGras, MreHair, MreIngr, MreKeym, MreLigh, MreLscr, MreLvlc, \
            MreLvli, MreLvsp, MreMgef, MreMisc, MreNpc, MrePack, MreQust, \
            MreRace, MreScpt, MreSgst, MreSlgm, MreSoun, MreSpel, MreStat, \
            MreTree, MreWatr, MreWeap, MreWthr, MreClmt, MreCsty, MreIdle, \
            MreLtex, MreRegn, MreSbsp, MreSkil, MreAchr, MreAcre, MreCell, \
            MreGmst, MreRefr, MreRoad, MreTes4, MreWrld, MreDial, MreInfo, \
            MrePgrd
        cls.mergeClasses = (
            MreActi,
            MreAlch,
            MreAmmo,
            MreAnio,
            MreAppa,
            MreArmo,
            MreBook,
            MreBsgn,
            MreClas,
            MreClot,
            MreCont,
            MreCrea,
            MreDoor,
            MreEfsh,
            MreEnch,
            MreEyes,
            MreFact,
            MreFlor,
            MreFurn,
            MreGlob,
            MreGras,
            MreHair,
            MreIngr,
            MreKeym,
            MreLigh,
            MreLscr,
            MreLvlc,
            MreLvli,
            MreLvsp,
            MreMgef,
            MreMisc,
            MreNpc,
            MrePack,
            MreQust,
            MreRace,
            MreScpt,
            MreSgst,
            MreSlgm,
            MreSoun,
            MreSpel,
            MreStat,
            MreTree,
            MreWatr,
            MreWeap,
            MreWthr,
            MreClmt,
            MreCsty,
            MreIdle,
            MreLtex,
            MreRegn,
            MreSbsp,
            MreSkil,
            MreAchr,
            MreAcre,
            MreCell,
            MreGmst,
            MreRefr,
            MreRoad,
            MreWrld,
            MreDial,
            MreInfo,
            MreLand,
            MrePgrd,
        )
        cls.readClasses = (
            MreMgef,
            MreScpt,
        )
        cls.writeClasses = (MreMgef, )
        # Setting RecordHeader class variables - Oblivion is special
        header_type = brec.RecordHeader
        header_type.rec_header_size = 20
        header_type.rec_pack_format = [u'=4s', u'I', u'I', u'I', u'I']
        header_type.rec_pack_format_str = u''.join(header_type.rec_pack_format)
        header_type.header_unpack = struct.Struct(
            header_type.rec_pack_format_str).unpack
        header_type.pack_formats = {0: u'=4sI4s2I'}
        header_type.pack_formats.update(
            {x: u'=4s4I'
             for x in {1, 6, 7, 8, 9, 10}})
        header_type.pack_formats.update({x: u'=4sIi2I' for x in {2, 3}})
        header_type.pack_formats.update({x: u'=4sIhh2I' for x in {4, 5}})
        # Similar to other games
        header_type.top_grup_sigs = [
            b'GMST',
            b'GLOB',
            b'CLAS',
            b'FACT',
            b'HAIR',
            b'EYES',
            b'RACE',
            b'SOUN',
            b'SKIL',
            b'MGEF',
            b'SCPT',
            b'LTEX',
            b'ENCH',
            b'SPEL',
            b'BSGN',
            b'ACTI',
            b'APPA',
            b'ARMO',
            b'BOOK',
            b'CLOT',
            b'CONT',
            b'DOOR',
            b'INGR',
            b'LIGH',
            b'MISC',
            b'STAT',
            b'GRAS',
            b'TREE',
            b'FLOR',
            b'FURN',
            b'WEAP',
            b'AMMO',
            b'NPC_',
            b'CREA',
            b'LVLC',
            b'SLGM',
            b'KEYM',
            b'ALCH',
            b'SBSP',
            b'SGST',
            b'LVLI',
            b'WTHR',
            b'CLMT',
            b'REGN',
            b'CELL',
            b'WRLD',
            b'DIAL',
            b'QUST',
            b'IDLE',
            b'PACK',
            b'CSTY',
            b'LSCR',
            b'LVSP',
            b'ANIO',
            b'WATR',
            b'EFSH',
        ]
        header_type.valid_header_sigs = set(header_type.top_grup_sigs + [
            b'GRUP', b'TES4', b'ROAD', b'REFR', b'ACHR', b'ACRE', b'PGRD',
            b'LAND', b'INFO'
        ])
        brec.MreRecord.type_class = {
            x.rec_sig: x
            for x in (MreAchr, MreAcre, MreActi, MreAlch, MreAmmo, MreAnio,
                      MreAppa, MreArmo, MreBook, MreBsgn, MreCell, MreClas,
                      MreClot, MreCont, MreCrea, MreDoor, MreEfsh, MreEnch,
                      MreEyes, MreFact, MreFlor, MreFurn, MreGlob, MreGmst,
                      MreGras, MreHair, MreIngr, MreKeym, MreLigh, MreLscr,
                      MreLvlc, MreLvli, MreLvsp, MreMgef, MreMisc, MreNpc,
                      MrePack, MreQust, MreRace, MreRefr, MreRoad, MreScpt,
                      MreSgst, MreSkil, MreSlgm, MreSoun, MreSpel, MreStat,
                      MreTree, MreTes4, MreWatr, MreWeap, MreWrld, MreWthr,
                      MreClmt, MreCsty, MreIdle, MreLtex, MreRegn, MreSbsp,
                      MreDial, MreInfo, MreLand, MrePgrd)
        }
        brec.MreRecord.simpleTypes = (set(brec.MreRecord.type_class) - {
            b'TES4', b'ACHR', b'ACRE', b'REFR', b'CELL', b'PGRD', b'ROAD',
            b'LAND', b'WRLD', b'INFO', b'DIAL'
        })
        cls._validate_records()