def main(*, game_name, game_path, mod_type, mod_options=[], is_steam=True): sys.stdout = logger.Logger(common.Globals.LOG_FILE_PATH) logger.setGlobalLogger(sys.stdout) sys.stderr = logger.StdErrRedirector(sys.stdout) common.Globals.scanForExecutables() gui_main.check07thModServerConnection() modList = gui_main.getModList() subModList = gui_main.getSubModConfigList(modList) print("\n") suitableSubMods = [ x for x in subModList if all(y in x.modName.lower().split() for y in game_name.lower().split("-")) and x.subModName == mod_type ] if len(suitableSubMods) != 1: print(f'Could not find a mod matching "{game_name}"') return neededSubMod = suitableSubMods[0] neededModOptions = [] for i in mod_options: neededModOption = [ x for x in neededSubMod.modOptions if all(y in x.id.lower().split() for y in i.lower().split("-")) ] if len(neededModOption) == 1: neededModOptions += neededModOption if len(neededModOptions) != len(mod_options): print("Couldn't find specified mod options.") return for i in neededSubMod.modOptions: if i.id in [x.id for x in neededModOptions]: i.value = True install_config = installConfiguration.FullInstallConfiguration( neededSubMod, game_path, is_steam ) if neededSubMod.family == "umineko": uminekoInstaller.mainUmineko(install_config) elif neededSubMod.family == "umineko_nscripter": uminekoNScripterInstaller.main(install_config) elif neededSubMod.family == "higurashi": higurashiInstaller.main(install_config) else: print( f"Submod family is not recognised, the script may be out of date." "Please ask us to update it." )
Description: [{}]""".format(option.name, option.description) ) # Ask the user about each group of radio options def customFormatter(option): return "[{}]:\n{}\n".format(option.name, option.description) for (optionGroupName, optionList) in radioOptions.items(): chosenRadioOption = userPickFromList(optionList, "Please choose [{}]".format(optionGroupName), customFormatter=customFormatter) chosenRadioOption.value = True if __name__ == "__main__": sys.stdout = logger.Logger(common.Globals.LOG_FILE_PATH) logger.setGlobalLogger(sys.stdout) sys.stderr = logger.StdErrRedirector(sys.stdout) gui_main.check07thModServerConnection() common.Globals.scanForExecutables() modList = gui_main.getModList() subModList = gui_main.getSubModConfigList(modList) #type: List[SubModConfig] # Get a list of unique game names uniqueGameNames = [] seenGameNames = set() for subMod in subModList: if subMod.modName not in seenGameNames: seenGameNames.add(subMod.modName) uniqueGameNames.append(subMod.modName) # Ask the user which game they want to install
def installerCommonStartupTasks(): """ Peforms tasks common to both the normal GUI installer and the CLI Installer - Change current directory to path of the launched python file - Setup logging - Read the launcher path (works only on Windows) - Enable developer mode if installData.json found on disk - Log information about the environment (current dir, python version etc.) - On Windows, check for hostname problems """ errors = [] print("Installer script name (argv[0]): [{}]".format(sys.argv[0])) # If you double-click on the file in Finder on macOS, it will not open with a path that is near the .py file # Since we want to properly find things like `./aria2c`, we should move to that path first. dirname = os.path.dirname(sys.argv[0]) if dirname.strip(): os.chdir(dirname) # redirect stdout to both a file and console # TODO: on MAC using a .app file, not sure if this logfile will be writeable # could do a try-catch, and then only begin logging once the game path has been set? sys.stdout = logger.Logger(common.Globals.LOG_FILE_PATH) logger.setGlobalLogger(sys.stdout) sys.stderr = logger.StdErrRedirector(sys.stdout) parser = argparse.ArgumentParser() parser.add_argument("launcher_path", nargs='?', default=None) parser.add_argument( "-ao", "--asset-os", action="store", dest="force_asset_os_string", metavar="ASSET_OS", default=None, choices=['windows', 'linux', 'mac'], help= ('Force the installer to install assets from another operating system' 'Mainly used on Linux to install Windows assets for use under Wine'), ) args = parser.parse_args() # Optional first argument tells the script the path of the launcher (currently only used with Windows launcher) if args.launcher_path is not None: common.Globals.NATIVE_LAUNCHER_PATH = sys.argv[1] print("Launcher is located at [{}]".format( common.Globals.NATIVE_LAUNCHER_PATH)) else: if common.Globals.IS_WINDOWS: print( "WARNING: Launcher path not given to Python script. Will try to use PowerShell file chooser instead of native one." ) common.Globals.FORCE_ASSET_OS_STRING = args.force_asset_os_string if common.Globals.FORCE_ASSET_OS_STRING is not None: print( "Warning: Force asset argument passed - will install {} assets despite os being {}" .format(common.Globals.FORCE_ASSET_OS_STRING, common.Globals.OS_STRING)) # Enable developer mode if we detect the program is run from the git repository # Comment out this line to simulate a 'normal' installation - files will be fetched from the web. if os.path.exists("installData.json"): common.Globals.DEVELOPER_MODE = True print( """------ NOTE: Developer mode is enabled (will use installData.json from disk) ----""" ) print("> Install Started On {}".format(datetime.datetime.now())) common.Globals.getBuildInfo() print("Python {}".format(sys.version)) print("Locale - Default: {} | Preferred: {} | Filesystem: {}".format( sys.getdefaultencoding(), locale.getpreferredencoding(), sys.getfilesystemencoding())) print("Installer Build Information: {}".format(common.Globals.BUILD_INFO)) print("Installer is being run from: [{}]".format(os.getcwd())) # Windows only checks if common.Globals.IS_WINDOWS: # Check for non-ascii characters in hostname, which prevent the server starting up if not all(ord(c) < 128 for c in socket.gethostname()): errors.append( "ERROR: It looks like your hostname [{}] contains non-ASCII characters. This may prevent the installer from starting up.\n" "Please change your hostname to only contain ASCII characters, then restart the installer." .format(socket.gethostname())) # Check if installer is being run from system root (C:\Windows for example) system_root = os.environ.get('SYSTEMROOT') if system_root: if os.path.realpath(os.getcwd()).startswith( os.path.realpath(system_root)): errors.append( "ERROR: You are trying to run the installer from the system folder [{}]. Please do not use the start menu to launch the installer. Please run the installer from a user writeable folder instead" .format(dirname)) # Check if the current folder is writeable try: # Write some dummy data to a temp file test_data = "test" temp_file_handle, temp_file_path = tempfile.mkstemp(dir='.') with os.fdopen(temp_file_handle, 'w') as temp_file: temp_file.write(test_data) # Wait for the file to appear on the filesystem (in most cases this happens immediately) for i in range(3): if os.path.exists(temp_file_path): break time.sleep(.5) # Read back the file and check its contents is the same that was written earlier with open(temp_file_path) as temp_file: if temp_file.read() != test_data: errors.append( "ERROR: File written to installer folder was not readable [{}]. Please run the installer from a user writeable folder instead" .format(temp_file_path)) # Remove the temp file os.remove(temp_file_path) except Exception as e: traceback.print_exc() errors.append( "ERROR: Installer folder is not writeable [{}]. Please run the installer from a user writeable folder instead. Full error:\n{}" .format(os.getcwd(), e)) if errors: print( '\n--------------------------------------------------------------') print('The following problems were found during startup:') print('- ', end='') print('\n- '.join(errors)) print('--------------------------------------------------------------') print( 'Please try to fix these errors before continuing, then restart the installer.' ) input( 'If you think the error was a false positive, press ENTER to continue anyway' ) input( "If you're absolutely sure you want to continue, press ENTER again" )
def setUp(self): class DummyLogger: def write(self, message, runCallbacks=True, noTerminal=False): print(message) logger.setGlobalLogger(DummyLogger())