Ejemplo n.º 1
0
def main(fullInstallConfiguration):
	# type: (installConfiguration.FullInstallConfiguration) -> None

	isVoiceOnly = fullInstallConfiguration.subModConfig.subModName == 'voice-only'
	if isVoiceOnly:
		print("Performing Voice-Only Install - backupUI() and cleanOld() will NOT be performed.")

	modOptionParser = installConfiguration.ModOptionParser(fullInstallConfiguration)

	# The Partial Manual Install option is mainly for Windows, so please don't assume it works properly on Linux/MacOS
	if modOptionParser.partialManualInstall:
		extractDir = fullInstallConfiguration.subModConfig.modName + " " + fullInstallConfiguration.subModConfig.subModName + " Extracted"
		installer = Installer(fullInstallConfiguration, extractDirectlyToGameDirectory=False, modOptionParser=modOptionParser, forcedExtractDirectory=extractDir)
		installer.download()
		installer.extractFiles()
		if installer.optionParser.installSteamGrid:
			steamGridExtractor.extractSteamGrid(installer.downloadDir)
		installer.applyLanguagePatchFixesIfNecessary()
		installer.saveFileVersionInfoFinished(forcedSaveFolder=extractDir)
		common.tryShowInFileBrowser(extractDir)
		common.tryShowInFileBrowser(fullInstallConfiguration.installPath)
	elif common.Globals.IS_WINDOWS:
		# On Windows, extract directly to the game directory to avoid path-length issues and speed up install
		installer = Installer(fullInstallConfiguration, extractDirectlyToGameDirectory=True, modOptionParser=modOptionParser)
		print("Downloading...")
		installer.download()
		installer.saveFileVersionInfoStarted()
		if not isVoiceOnly:
			installer.backupUI()
			installer.cleanOld()
		print("Extracting...")
		installer.extractFiles()
		commandLineParser.printSeventhModStatusUpdate(97, "Cleaning up...")
		if installer.optionParser.installSteamGrid:
			steamGridExtractor.extractSteamGrid(installer.downloadDir)
		installer.applyLanguagePatchFixesIfNecessary()
		installer.saveFileVersionInfoFinished()
		installer.cleanup(cleanExtractionDirectory=False)
	else:
		installer = Installer(fullInstallConfiguration, extractDirectlyToGameDirectory=False, modOptionParser=modOptionParser)
		print("Downloading...")
		installer.download()
		installer.saveFileVersionInfoStarted()
		print("Extracting...")
		installer.extractFiles()
		commandLineParser.printSeventhModStatusUpdate(85, "Moving files into place...")
		if not isVoiceOnly:
			installer.backupUI()
			installer.cleanOld()
		installer.moveFilesIntoPlace()
		commandLineParser.printSeventhModStatusUpdate(97, "Cleaning up...")
		installer.applyLanguagePatchFixesIfNecessary()
		installer.saveFileVersionInfoFinished()
		installer.cleanup(cleanExtractionDirectory=True)


	commandLineParser.printSeventhModStatusUpdate(100, "Install Completed!")
Ejemplo n.º 2
0
def main(fullInstallConfiguration):
    # type: (installConfiguration.FullInstallConfiguration) -> None

    isVoiceOnly = fullInstallConfiguration.subModConfig.subModName == 'voice-only'
    if isVoiceOnly:
        print(
            "Performing Voice-Only Install - backupUI() and cleanOld() will NOT be performed."
        )

    # On Windows, extract directly to the game directory to avoid path-length issues and speed up install
    if common.Globals.IS_WINDOWS:
        installer = Installer(fullInstallConfiguration,
                              extractDirectlyToGameDirectory=True)
        print("Downloading...")
        installer.download()
        installer.saveFileVersionInfoStarted()
        if not isVoiceOnly:
            installer.backupUI()
            installer.cleanOld()
        print("Extracting...")
        installer.extractFiles()
        commandLineParser.printSeventhModStatusUpdate(97, "Cleaning up...")
        if fullInstallConfiguration.installSteamGrid:
            steamGridExtractor.extractSteamGrid(installer.downloadDir)
        installer.applyLanguageSpecificSharedAssets()
        installer.saveFileVersionInfoFinished()
        installer.cleanup(cleanExtractionDirectory=False)
    else:
        installer = Installer(fullInstallConfiguration,
                              extractDirectlyToGameDirectory=False)
        print("Downloading...")
        installer.download()
        installer.saveFileVersionInfoStarted()
        print("Extracting...")
        installer.extractFiles()
        commandLineParser.printSeventhModStatusUpdate(
            85, "Moving files into place...")
        if not isVoiceOnly:
            installer.backupUI()
            installer.cleanOld()
        installer.moveFilesIntoPlace()
        commandLineParser.printSeventhModStatusUpdate(97, "Cleaning up...")
        installer.applyLanguageSpecificSharedAssets()
        installer.saveFileVersionInfoFinished()
        installer.cleanup(cleanExtractionDirectory=True)

    commandLineParser.printSeventhModStatusUpdate(100, "Install Completed!")
Ejemplo n.º 3
0
def mainUmineko(conf):
    # type: (installConfiguration.FullInstallConfiguration) -> None
    logger.getGlobalLogger().trySetSecondaryLoggingPath(
        os.path.join(conf.installPath, common.Globals.LOG_BASENAME))

    isQuestionArcs = 'question' in conf.subModConfig.modName.lower()

    print("CONFIGURATION:")
    print("Install path", conf.installPath)
    print("Mod Option", conf.subModConfig.modName)
    print("Sub Option", conf.subModConfig.subModName)
    print("Is Question Arcs", isQuestionArcs)
    print("Is Windows", common.Globals.IS_WINDOWS)
    print("Is Linux", common.Globals.IS_LINUX)
    print("Is Mac", common.Globals.IS_MAC)

    ####################################### VALIDATE AND PREPARE FOLDERS ###############################################
    # do a quick verification that the directory is correct before starting installer
    if not os.path.isfile(os.path.join(conf.installPath, "arc.nsa")):
        raise Exception(
            "ERROR - wrong game path. Installation Stopped.\n"
            "There is no 'arc.nsa' in the game folder. Are you sure the correct game folder was selected?"
        )

    for filename in os.listdir(conf.installPath):
        # Stop the user installing the mod on pirated versions of the game.
        # Use SHA256 hash of the lowercase filename to avoid listing the website names in our source code.
        if hashlib.sha256(filename.lower().encode('utf-8')).hexdigest() in [
                '2c02ec6f6de9281a68975257a477e8f994affe4eeaaf18b0b56b4047885461e0',
                '4fae41c555fe50034065e59ce33a643c1d93ee846221ecc5756f00e039035076',
        ]:
            raise Exception(
                "\nInstall Failed - The {} mod is not compatible with the pirated version of the game\n"
                "(Detected file [{}]) Please install the latest Steam or Mangagamer release."
                .format(conf.subModConfig.modName, filename))

        # Stop the user installing the mod on the old/original Japanese game.
        # This probably means the user placed a fake identifier (eg the game exe) in the old game's folder.
        if filename == 'snow.dll':
            raise Exception(
                "\nInstall Failed - The {} mod is not compatible with the old/original Japanese game.\n"
                "(Detected [{}]) Please install the latest Steam or Mangagamer release."
                .format(conf.subModConfig.modName, filename))

    # Create aliases for the temp directories, and ensure they exist beforehand
    downloadTempDir = conf.subModConfig.modName + " Downloads"

    if os.path.isdir(downloadTempDir):
        print(
            "Information: Temp directories already exist - continued or overwritten install"
        )

    common.makeDirsExistOK(downloadTempDir)

    ######################################## Query and Download Files ##################################################
    fileVersionManager = fileVersionManagement.VersionManager(
        subMod=conf.subModConfig,
        modFileList=conf.buildFileListSorted(),
        localVersionFolder=conf.installPath)

    filesRequiringUpdate = fileVersionManager.getFilesRequiringUpdate()
    print("Perform Full Install: {}".format(
        fileVersionManager.fullUpdateRequired()))
    downloaderAndExtractor = common.DownloaderAndExtractor(
        filesRequiringUpdate,
        downloadTempDir,
        conf.installPath,
        downloadProgressAmount=45,
        extractionProgressAmount=45)
    downloaderAndExtractor.buildDownloadAndExtractionList()

    parser = installConfiguration.ModOptionParser(conf)

    for opt in parser.downloadAndExtractOptionsByPriority:
        downloaderAndExtractor.addItemManually(
            url=opt.url,
            extractionDir=os.path.join(conf.installPath,
                                       opt.relativeExtractionPath),
        )

    downloaderAndExtractor.printPreview()

    # Delete all non-checksummed files from the download folder, if they exist
    print("Removing non-checksummed downloads:")
    deleteExtractablesFromFolder(
        downloadTempDir,
        [x for x in downloaderAndExtractor.extractList if not x.fromMetaLink])

    downloaderAndExtractor.download()

    # Treat the install as "started" once the "download" stage is complete
    fileVersionManager.saveVersionInstallStarted()

    ###################### Backup/clear the .exe and script files, and old graphics ####################################
    backupOrRemoveFiles(conf.installPath)

    if fileVersionManager.fullUpdateRequired():
        # Remove old graphics from a previous installation, as they can conflict with the voice-only patch
        graphicsPathsToDelete = [
            os.path.join(conf.installPath, x) for x in ['big', 'bmp', 'en']
        ]

        for folderPath in graphicsPathsToDelete:
            if os.path.exists(folderPath):
                print("Deleting {}".format(folderPath))
                try:
                    shutil.rmtree(folderPath)
                except:
                    print("WARNING: failed to remove folder {}".format(
                        folderPath))

    ######################################## Extract Archives ##########################################################
    downloaderAndExtractor.extract()

    ############################################# FIX .ARC FILE NAMING #################################################
    # Steam release has arc files labeled arc.nsa, arc1.nsa, arc2.nsa, arc3.nsa.
    # Mangagamer release has only one arc file labeled arc.nsa
    # Generate dummy arc1-arc3 nsa files if they don't already exist, so the game can find the arc4.nsa that we provide
    for i in range(1, 4):
        nsaPath = os.path.join(conf.installPath, 'arc{}.nsa'.format(i))
        if not os.path.exists(nsaPath):
            print(
                ".nsa archive check: Generating dummy [{}] as it does not already exist (Mangagamer)"
                .format(nsaPath))
            with open(nsaPath, 'wb') as dummyNSAFile:
                dummyNSAFile.write(bytes([0, 0, 0, 0, 0, 6]))
        else:
            print(".nsa archive check: [{}] already exists (Steam)".format(
                nsaPath))

    #################################### MAKE EXECUTABLE, WRITE HELPER SCRIPTS #########################################
    gameBaseName = "Umineko5to8"
    if isQuestionArcs:
        gameBaseName = "Umineko1to4"

    if common.Globals.IS_MAC:
        print("Un-quarantining game executable")
        subprocess.call([
            "xattr", "-d", "com.apple.quarantine",
            os.path.join(conf.installPath, gameBaseName + ".app")
        ])

    print("Creating debug mode batch files")
    # write batch file to let users launch game in debug mode
    with open(os.path.join(conf.installPath, gameBaseName + "_DebugMode.bat"),
              'w') as f:
        f.writelines([gameBaseName + ".exe --debug\n", "pause"])

    #make the following files executable, if they exist
    makeExecutableList = [
        os.path.join(conf.installPath, "Umineko1to4"),
        os.path.join(conf.installPath,
                     "Umineko1to4.app/Contents/MacOS/umineko4"),
        os.path.join(conf.installPath, "Umineko5to8"),
        os.path.join(conf.installPath,
                     "Umineko5to8.app/Contents/MacOS/umineko8")
    ]

    print("Making executables ... executable")
    for exePath in makeExecutableList:
        if os.path.exists(exePath):
            common.makeExecutable(exePath)

    # Patched game uses mysav folder, which Steam can't see so can't get incompatible saves by accident.
    # Add batch file which reverses this behaviour by making a linked folder from (saves->mysav)
    print("Creating EnableSteamSync.bat")
    with open(os.path.join(conf.installPath, "EnableSteamSync.bat"), 'w') as f:
        f.write("""
if exist saves (
    ren saves backup-saves
    mklink /J saves mysav
) else (
    mklink /J saves mysav
)
pause
""")

    # For now, don't copy save data

    steamGridExtractor.extractSteamGrid()
    fileVersionManager.saveVersionInstallFinished()

    if not parser.keepDownloads:
        print("Removing temporary downloads:")
        deleteExtractablesFromFolder(downloadTempDir,
                                     downloaderAndExtractor.extractList)

    commandLineParser.printSeventhModStatusUpdate(
        100, "Umineko install script completed!")