public async Task <IScriptType> GetScriptType(IList <string> modFiles)
        {
            CurrentScriptTypeRegistry = await ScriptTypeRegistry.DiscoverScriptTypes(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            IScriptType FoundScriptType = null;

            await Task.Run(() =>
            {
                foreach (IScriptType scriptType in CurrentScriptTypeRegistry.Types)
                {
                    bool HasFoundScriptType = false;
                    if (scriptType.FileNames != null)
                    {
                        foreach (string scriptFile in scriptType.FileNames)
                        {
                            // ??? Need to check for Fomod/Omod/Whatever before this part
                            string FileToFind = Path.Combine(FomodRoot, scriptFile);
                            string Match      = modFiles.Where(x => Path.GetFileName(x).Contains(scriptFile, StringComparison.OrdinalIgnoreCase) && Path.GetFileName(Path.GetDirectoryName(x)).Contains(FomodRoot, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                            if (!string.IsNullOrEmpty(Match))
                            {
                                HasFoundScriptType = true;
                                FoundScriptType    = scriptType;
                            }
                        }
                    }

                    if (HasFoundScriptType)
                    {
                        break;
                    }
                }
            });

            return(FoundScriptType);
        }
        /// <summary>
        /// A siple constructor that initializes the object with the given dependencies.
        /// </summary>
        /// <param name="p_stgScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> of available <see cref="IScriptType"/>s.</param>
        public ModScriptEditorVM(IScriptTypeRegistry p_stgScriptTypeRegistry)
        {
            IScriptTypeRegistry = p_stgScriptTypeRegistry;

            foreach (IScriptType stpScriptType in IScriptTypeRegistry.Types)
            {
                m_dicScriptEditors[stpScriptType] = stpScriptType.CreateEditor(null);
            }
        }
        /// <summary>
        /// Searches the given list of assemblies for script types, and registers any that are found.
        /// </summary>
        /// <param name="scriptTypeRegistry">The registry with which to register any found script types.</param>
        /// <param name="scriptAssemblies">The assemblies to search for script types.</param>
        private async static Task RegisterScriptTypes(IScriptTypeRegistry scriptTypeRegistry, IList <string> scriptAssemblies)
        {
            List <string> SupportedScriptDLLs = new List <string>()
            {
                "XmlScript.dll",
                "ModScript.dll",
                "CSharpScript.dll"
            };

            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

            try
            {
                await Task.Run(() =>
                {
                    foreach (string assembly in scriptAssemblies)
                    {
                        foreach (string dll in SupportedScriptDLLs)
                        {
                            if (assembly.Contains(dll, StringComparison.OrdinalIgnoreCase))
                            {
                                Assembly CurrentAssembly = Assembly.LoadFrom(assembly);
                                Type[] Types             = CurrentAssembly.GetExportedTypes();
                                foreach (Type type in Types)
                                {
                                    if (typeof(IScriptType).IsAssignableFrom(type) && !type.IsAbstract)
                                    {
                                        Trace.TraceInformation("Initializing: {0}", type.FullName);
                                        Trace.Indent();

                                        IScriptType ScriptType      = null;
                                        ConstructorInfo Constructor = type.GetConstructor(new Type[] { });
                                        if (Constructor != null)
                                        {
                                            ScriptType = (IScriptType)Constructor.Invoke(null);
                                        }
                                        if (ScriptType != null)
                                        {
                                            scriptTypeRegistry.RegisterType(ScriptType);
                                        }

                                        Trace.Unindent();
                                    }
                                }
                            }
                        }
                    }
                });
            }
            finally
            {
                AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
            }
        }
		/// <summary>
		/// Searches for mod format assemblies in the specified path, and loads
		/// any mod formats that are found into a registry.
		/// </summary>
		/// <remarks>
		/// A mod format is loaded if the class implements <see cref="IModFormat"/> and is
		/// not abstract. Once loaded, the format is added to the registry.
		/// </remarks>
		/// <param name="p_mcmModCacheManager">The manager being used to manage mod caches.</param>
		/// <param name="p_stgScriptTypeRegistry">The registry listing the supported script types.</param>
		/// <param name="p_strSearchPath">The path in which to search for mod format assemblies.</param>
		/// <returns>A registry containing all of the discovered mod formats.</returns>
		public static IModFormatRegistry DiscoverFormats(IModCacheManager p_mcmModCacheManager, IScriptTypeRegistry p_stgScriptTypeRegistry, string p_strSearchPath)
		{
			Trace.TraceInformation("Discovering Mod Formats...");
			Trace.Indent();

			Trace.TraceInformation("Looking in: {0}", p_strSearchPath);

			IModFormatRegistry mfrRegistry = new ModFormatRegistry();
			if (!Directory.Exists(p_strSearchPath))
			{
				Trace.TraceError("Format search path does not exist.");
				Trace.Unindent();
				return mfrRegistry;
			}

			string[] strAssemblies = Directory.GetFiles(p_strSearchPath, "*.dll");
			foreach (string strAssembly in strAssemblies)
			{
				Trace.TraceInformation("Checking: {0}", Path.GetFileName(strAssembly));
				Trace.Indent();

				Assembly asmGameMode = Assembly.LoadFile(strAssembly);
				Type[] tpeTypes = asmGameMode.GetExportedTypes();
				foreach (Type tpeType in tpeTypes)
				{
					if (typeof(IModFormat).IsAssignableFrom(tpeType) && !tpeType.IsAbstract)
					{
						Trace.TraceInformation("Initializing: {0}", tpeType.FullName);
						Trace.Indent();

						ConstructorInfo cifConstructor = tpeType.GetConstructor(new Type[] { typeof(IModCacheManager), typeof(IScriptTypeRegistry) });
						IModFormat mftModFormat = null;
						if (cifConstructor != null)
							mftModFormat = (IModFormat)cifConstructor.Invoke(new object[] { p_mcmModCacheManager, p_stgScriptTypeRegistry });
						else
						{
							cifConstructor = tpeType.GetConstructor(new Type[] { });
							if (cifConstructor != null)
								mftModFormat = (IModFormat)cifConstructor.Invoke(null);
						}
						if (mftModFormat != null)
							mfrRegistry.RegisterFormat(mftModFormat);

						Trace.Unindent();
					}
				}
				Trace.Unindent();
			}
			Trace.Unindent();
			return mfrRegistry;
		}
        public async Task <IScriptType> GetScriptType(IList <string> modFiles, string extractedFilePath = null)
        {
            CurrentScriptTypeRegistry = await ScriptTypeRegistry.DiscoverScriptTypes(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            IScriptType FoundScriptType = null;

            string omodMatch = modFiles.Where(x => x.Equals("script") || x.Equals("script.txt")).FirstOrDefault();

            await Task.Run(() =>
            {
                foreach (IScriptType scriptType in CurrentScriptTypeRegistry.Types)
                {
                    bool HasFoundScriptType = false;
                    if (scriptType.FileNames != null)
                    {
                        foreach (string scriptFile in scriptType.FileNames)
                        {
                            string scriptDataString = "";
                            if (!string.IsNullOrEmpty(omodMatch))
                            {
                                byte[] scriptData = File.ReadAllBytes(Path.Combine(extractedFilePath, omodMatch));
                                scriptDataString  = System.Text.Encoding.Default.GetString(scriptData);
                            }

                            if (!string.IsNullOrEmpty(omodMatch) && scriptType.ValidateScript(scriptType.LoadScript(scriptDataString)))
                            {
                                HasFoundScriptType = true;
                                FoundScriptType    = scriptType;
                            }
                            else
                            {
                                string fomodMatch = modFiles.Where(x => scriptMatch(x, scriptFile)).FirstOrDefault();
                                if (!string.IsNullOrEmpty(fomodMatch))
                                {
                                    HasFoundScriptType = true;
                                    FoundScriptType    = scriptType;
                                }
                            }
                        }
                    }

                    if (HasFoundScriptType)
                    {
                        break;
                    }
                }
            });

            return(FoundScriptType);
        }
Example #6
0
        /// <summary>
        /// A simple constructor that initializes the object with the given values.
        /// </summary>
        /// <param name="p_vmlScriptEditorVM">The <see cref="InstallScriptEditorVM"/> that encapsulates the data
        /// and operations for diaplying the <see cref="IScript"/> editor.</param>
        /// <param name="p_vmlInfoEditorVM">The <see cref="ModInfoEditorVM"/> that encapsulates the data
        /// and operations for diaplying the <see cref="IModInfo"/> editor.</param>
        /// <param name="p_prjModProject">The <see cref="Project"/> to edit.</param>
        /// <param name="p_srgScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> of available <see cref="IScriptType"/>s.</param>
        /// <param name="p_mpkModBuilder">he <see cref="ModPackager"/> to use to build mod files
        /// from <see cref="Project"/>s.</param>
        public ModPackagingFormVM(InstallScriptEditorVM p_vmlScriptEditorVM, ModInfoEditorVM p_vmlInfoEditorVM, Project p_prjModProject, IScriptTypeRegistry p_srgScriptTypeRegistry, ModPackager p_mpkModBuilder)
        {
            Errors   = new ErrorContainer();
            Warnings = new ErrorContainer();

            ScriptEditorVM      = p_vmlScriptEditorVM;
            InfoEditorVM        = p_vmlInfoEditorVM;
            IScriptTypeRegistry = p_srgScriptTypeRegistry;
            ModBuilder          = p_mpkModBuilder;

            ModProject = p_prjModProject ?? new Project(p_srgScriptTypeRegistry);

            SaveCommand  = new Command <string>("Save Project", "Save the project.", SaveProject, ModProject.IsDirty);
            OpenCommand  = new Command("Open Project", "Open a project.", OpenProject);
            NewCommand   = new Command("New Project", "Create a new project.", NewProject);
            BuildCommand = new Command <string>("Build Mod", "Builds the mod file.", BuildMod);
        }
        /// <summary>
        /// Searches the given list of assemblies for script types, and registers any that are found.
        /// </summary>
        /// <param name="p_stgScriptTypeRegistry">The registry with which to register any found script types.</param>
        /// <param name="p_enmAssemblies">The assemblies to search for script types.</param>
        private static void RegisterScriptTypes(IScriptTypeRegistry p_stgScriptTypeRegistry, IEnumerable <string> p_enmAssemblies, List <string> p_lstRemovedDLL)
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            try
            {
                foreach (string strAssembly in p_enmAssemblies)
                {
                    Trace.TraceInformation("Checking: {0}", Path.GetFileName(strAssembly));
                    Trace.Indent();

                    if (!p_lstRemovedDLL.Contains(Path.GetFileName(strAssembly)))
                    {
                        Assembly asmGameMode = Assembly.LoadFrom(strAssembly);
                        Type[]   tpeTypes    = asmGameMode.GetExportedTypes();
                        foreach (Type tpeType in tpeTypes)
                        {
                            if (typeof(IScriptType).IsAssignableFrom(tpeType) && !tpeType.IsAbstract)
                            {
                                Trace.TraceInformation("Initializing: {0}", tpeType.FullName);
                                Trace.Indent();

                                IScriptType     sctScriptType  = null;
                                ConstructorInfo cifConstructor = tpeType.GetConstructor(new Type[] { });
                                if (cifConstructor != null)
                                {
                                    sctScriptType = (IScriptType)cifConstructor.Invoke(null);
                                }
                                if (sctScriptType != null)
                                {
                                    p_stgScriptTypeRegistry.RegisterType(sctScriptType);
                                }

                                Trace.Unindent();
                            }
                        }
                    }
                    Trace.Unindent();
                }
            }
            finally
            {
                AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
            }
        }
        public async Task <IList <string> > GetRequirements(IList <string> modFiles, bool includeAssets)
        {
            CurrentScriptTypeRegistry = await ScriptTypeRegistry.DiscoverScriptTypes(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            // TODO: I don't think there is a good way to determine which image files are referenced by the installer script without
            //   unpacking it first, right?
            IList <string> RequiredFiles = includeAssets
                ? modFiles.Where(path => RequiredExtensions.Contains(Path.GetExtension(path))).ToList()
                : new List <string>();

            return(await Task.Run(() =>
            {
                bool HasFoundScriptType = false;
                foreach (IScriptType scriptType in CurrentScriptTypeRegistry.Types)
                {
                    if (scriptType.FileNames != null)
                    {
                        foreach (string scriptFile in scriptType.FileNames)
                        {
                            // ??? Need to check for Fomod/Omod/Whatever before this part
                            string FileToFind = Path.Combine(FomodRoot, scriptFile);
                            string Match = modFiles.Where(x => Path.GetFileName(x).Contains(scriptFile, StringComparison.OrdinalIgnoreCase) && Path.GetFileName(Path.GetDirectoryName(x)).Contains(FomodRoot, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                            if (!string.IsNullOrEmpty(Match))
                            {
                                HasFoundScriptType = true;
                                RequiredFiles.Add(Match);
                            }
                        }
                    }

                    if (HasFoundScriptType)
                    {
                        break;
                    }
                }

                if (!HasFoundScriptType)
                {
                    throw new UnsupportedException();
                }

                return RequiredFiles;
            }));
        }
		/// <summary>
		/// Searches the given list of assemblies for script types, and registers any that are found.
		/// </summary>
		/// <param name="p_stgScriptTypeRegistry">The registry with which to register any found script types.</param>
		/// <param name="p_enmAssemblies">The assemblies to search for script types.</param>
		private static void RegisterScriptTypes(IScriptTypeRegistry p_stgScriptTypeRegistry, IEnumerable<string> p_enmAssemblies)
		{
			AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
			try
			{
				foreach (string strAssembly in p_enmAssemblies)
				{
					Trace.TraceInformation("Checking: {0}", Path.GetFileName(strAssembly));
					Trace.Indent();

					Assembly asmGameMode = Assembly.LoadFrom(strAssembly);
					Type[] tpeTypes = asmGameMode.GetExportedTypes();
					foreach (Type tpeType in tpeTypes)
					{
						if (typeof(IScriptType).IsAssignableFrom(tpeType) && !tpeType.IsAbstract)
						{
							Trace.TraceInformation("Initializing: {0}", tpeType.FullName);
							Trace.Indent();

							IScriptType sctScriptType = null;
							ConstructorInfo cifConstructor = tpeType.GetConstructor(new Type[] { });
							if (cifConstructor != null)
								sctScriptType = (IScriptType)cifConstructor.Invoke(null);
							if (sctScriptType != null)
								p_stgScriptTypeRegistry.RegisterType(sctScriptType);

							Trace.Unindent();
						}
					}
					Trace.Unindent();
				}
			}
			finally
			{
				AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
			}
		}
Example #10
0
        /// <summary>
        /// Searches for mod format assemblies in the specified path, and loads
        /// any mod formats that are found into a registry.
        /// </summary>
        /// <remarks>
        /// A mod format is loaded if the class implements <see cref="IModFormat"/> and is
        /// not abstract. Once loaded, the format is added to the registry.
        /// </remarks>
        /// <param name="p_mcmModCacheManager">The manager being used to manage mod caches.</param>
        /// <param name="p_stgScriptTypeRegistry">The registry listing the supported script types.</param>
        /// <param name="p_strSearchPath">The path in which to search for mod format assemblies.</param>
        /// <returns>A registry containing all of the discovered mod formats.</returns>
        public static IModFormatRegistry DiscoverFormats(IModCacheManager p_mcmModCacheManager, List <string> p_lstSupportedFormats, IScriptTypeRegistry p_stgScriptTypeRegistry, string p_strSearchPath)
        {
            Trace.TraceInformation("Discovering Mod Formats...");
            Trace.Indent();

            Trace.TraceInformation("Looking in: {0}", p_strSearchPath);

            IModFormatRegistry mfrRegistry = new ModFormatRegistry();

            if (!Directory.Exists(p_strSearchPath))
            {
                Trace.TraceError("Format search path does not exist.");
                Trace.Unindent();
                return(mfrRegistry);
            }

            string[] strAssemblies = Directory.GetFiles(p_strSearchPath, "*.dll");
            foreach (string strAssembly in strAssemblies)
            {
                if (!p_lstSupportedFormats.Contains(Path.GetFileNameWithoutExtension(strAssembly), StringComparer.CurrentCultureIgnoreCase))
                {
                    continue;
                }

                Trace.TraceInformation("Checking: {0}", Path.GetFileName(strAssembly));
                Trace.Indent();

                Assembly asmGameMode = Assembly.LoadFile(strAssembly);
                Type[]   tpeTypes    = asmGameMode.GetExportedTypes();
                foreach (Type tpeType in tpeTypes)
                {
                    if (typeof(IModFormat).IsAssignableFrom(tpeType) && !tpeType.IsAbstract)
                    {
                        Trace.TraceInformation("Initializing: {0}", tpeType.FullName);
                        Trace.Indent();

                        ConstructorInfo cifConstructor = tpeType.GetConstructor(new Type[] { typeof(IModCacheManager), typeof(IScriptTypeRegistry) });
                        IModFormat      mftModFormat   = null;
                        if (cifConstructor != null)
                        {
                            mftModFormat = (IModFormat)cifConstructor.Invoke(new object[] { p_mcmModCacheManager, p_stgScriptTypeRegistry });
                        }
                        else
                        {
                            cifConstructor = tpeType.GetConstructor(new Type[] { });
                            if (cifConstructor != null)
                            {
                                mftModFormat = (IModFormat)cifConstructor.Invoke(null);
                            }
                        }
                        if (mftModFormat != null)
                        {
                            mfrRegistry.RegisterFormat(mftModFormat);
                        }

                        Trace.Unindent();
                    }
                }
                Trace.Unindent();
            }
            Trace.Unindent();
            return(mfrRegistry);
        }
		/// <summary>
		/// A siple constructor that initializes the object with the given dependencies.
		/// </summary>
		/// <param name="p_stgScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> of available <see cref="IScriptType"/>s.</param>
		public ModScriptEditorVM(IScriptTypeRegistry p_stgScriptTypeRegistry)
		{
			IScriptTypeRegistry = p_stgScriptTypeRegistry;

			foreach (IScriptType stpScriptType in IScriptTypeRegistry.Types)
				m_dicScriptEditors[stpScriptType] = stpScriptType.CreateEditor(null);
		}
Example #12
0
		/// <summary>
		/// Initializes an OMod in packed format.
		/// </summary>
		/// <param name="p_stgScriptTypeRegistry">The registry of supported script types.</param>
		private void InitializePackedOmod(IScriptTypeRegistry p_stgScriptTypeRegistry)
		{
			using (SevenZipExtractor szeOmod = new SevenZipExtractor(m_strFilePath))
			{
				ExtractConfig(szeOmod);
				ExtractPluginList(szeOmod);
				ExtractDataFileList(szeOmod);

				if (szeOmod.ArchiveFileNames.Contains("plugins.crc"))
					m_intReadOnlyInitFileBlockExtractionStages++;
				if (szeOmod.ArchiveFileNames.Contains("data.crc"))
					m_intReadOnlyInitFileBlockExtractionStages++;

				//check for script
				m_booHasInstallScript = false;
				foreach (IScriptType stpScript in p_stgScriptTypeRegistry.Types)
				{
					foreach (string strScriptName in stpScript.FileNames)
					{
						if (szeOmod.ArchiveFileNames.Contains(strScriptName))
						{
							using (MemoryStream stmScript = new MemoryStream())
							{
								szeOmod.ExtractFile(strScriptName, stmScript);
								string strCode = System.Text.Encoding.Default.GetString(stmScript.ToArray());
								if (stpScript.ValidateScript(stpScript.LoadScript(strCode)))
								{
									m_booHasInstallScript = true;
									m_stpInstallScriptType = stpScript;
									break;
								}
							}
						}
					}
					if (m_booHasInstallScript)
						break;
				}

				//check for readme
				m_booHasReadme = szeOmod.ArchiveFileNames.Contains("readme");

				//check for screenshot
				m_booHasScreenshot = szeOmod.ArchiveFileNames.Contains("image");
			}
		}
Example #13
0
		/// <summary>
		/// Initializes an OMod in OMod-ready archive format.
		/// </summary>
		/// <param name="p_booUseCache">Whether to use the mod cache.</param>
		/// <param name="p_mcmModCacheManager">The manager for the current game mode's mod cache.</param>
		/// <param name="p_stgScriptTypeRegistry">The registry of supported script types.</param>
		private void InitializeUnpackedOmod(bool p_booUseCache, IModCacheManager p_mcmModCacheManager, IScriptTypeRegistry p_stgScriptTypeRegistry)
		{
			if (p_booUseCache)
			{
				m_arcCacheFile = p_mcmModCacheManager.GetCacheFile(this);
				//check to make sure the cache isn't bad
				if ((m_arcCacheFile != null) && (!m_arcCacheFile.ContainsFile(GetRealPath(Path.Combine(CONVERSION_FOLDER, "config"))) || !ValidateConfig(GetSpecialFile("config"))))
				{
					//bad cache - clear it
					m_arcCacheFile.Dispose();
					m_arcCacheFile = null;
				}
			}

			//check for script
			m_booHasInstallScript = false;
			foreach (IScriptType stpScript in p_stgScriptTypeRegistry.Types)
			{
				foreach (string strScriptName in stpScript.FileNames)
				{
					if (ContainsFile(Path.Combine(CONVERSION_FOLDER, strScriptName)))
					{
						StreamReader sreScript = null;
						string strCode = String.Empty;

						if (File.Exists(Path.Combine(CONVERSION_FOLDER, strScriptName)))
						{
							sreScript = new StreamReader(Path.Combine(CONVERSION_FOLDER, strScriptName));
							strCode = sreScript.ReadToEnd();
							sreScript.Close();
						}
						else
							strCode = TextUtil.ByteToString(GetFile(Path.Combine(CONVERSION_FOLDER, strScriptName))).Trim('\0');

						if (!String.IsNullOrEmpty(strCode))
						{
							if (stpScript.ValidateScript(stpScript.LoadScript(strCode)))
							{
								m_booHasInstallScript = true;
								m_stpInstallScriptType = stpScript;
								break;
							}
						}
					}
				}
				if (m_booHasInstallScript)
					break;
			}

			//check for readme
			m_booHasReadme = ContainsFile(Path.Combine(CONVERSION_FOLDER, "readme"));

			//check for screenshot
			m_booHasScreenshot = ContainsFile(Path.Combine(CONVERSION_FOLDER, "screenshot"));

			if (p_booUseCache && (m_arcCacheFile == null))
			{
				string strTmpInfo = p_mcmModCacheManager.FileUtility.CreateTempDirectory();
				try
				{
					FileUtil.WriteAllBytes(Path.Combine(strTmpInfo, GetRealPath(Path.Combine(CONVERSION_FOLDER, "config"))), GetSpecialFile("config"));

					if (m_booHasReadme)
						FileUtil.WriteAllBytes(Path.Combine(strTmpInfo, GetRealPath(Path.Combine(CONVERSION_FOLDER, "readme"))), GetSpecialFile("readme"));

					if (m_booHasScreenshot)
						FileUtil.WriteAllBytes(Path.Combine(strTmpInfo, GetRealPath(Path.Combine(CONVERSION_FOLDER, ScreenshotPath))), GetSpecialFile(ScreenshotPath));

					m_arcCacheFile = p_mcmModCacheManager.CreateCacheFile(this, strTmpInfo);
				}
				finally
				{
					FileUtil.ForceDelete(strTmpInfo);
				}
			}

			LoadInfo(GetSpecialFile("config"));
		}
Example #14
0
		/// <summary>
		/// A simple constructor that initializes the OMod from the specified file.
		/// </summary>
		/// <param name="p_strFilePath">The mod file from which to create the OMod.</param>
		/// <param name="p_mftModFormat">The format of the mod.</param>
		/// <param name="p_mcmModCacheManager">The manager for the current game mode's mod cache.</param>
		/// <param name="p_stgScriptTypeRegistry">The registry of supported script types.</param>
		public OMod(string p_strFilePath, OModFormat p_mftModFormat, IModCacheManager p_mcmModCacheManager, IScriptTypeRegistry p_stgScriptTypeRegistry)
		{
			Format = p_mftModFormat;
			m_strFilePath = p_strFilePath;
			m_arcFile = new Archive(p_strFilePath);
			ModName = Path.GetFileNameWithoutExtension(Filename);
			bool p_booUseCache = true;

			PluginList = new List<FileInfo>();
			DataFileList = new List<FileInfo>();

			FindPathPrefix();
			IsPacked = !m_arcFile.ContainsFile(GetRealPath(Path.Combine(CONVERSION_FOLDER, "config")));
			if (!IsPacked)
				InitializeUnpackedOmod(p_booUseCache, p_mcmModCacheManager, p_stgScriptTypeRegistry);
			else
				InitializePackedOmod(p_stgScriptTypeRegistry);
			m_arcFile.FilesChanged += new EventHandler(Archive_FilesChanged);
		}
		/// <summary>
		/// A siple constructor that initializes the object with the given dependencies.
		/// </summary>
		/// <param name="p_stgScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> of available <see cref="IScriptType"/>s.</param>
		public InstallScriptEditorVM(IScriptTypeRegistry p_stgScriptTypeRegistry)
			: base(p_stgScriptTypeRegistry)
		{
		}
Example #16
0
 /// <summary>
 /// A simple constructor that initializes the object with the required dependencies.
 /// </summary>
 /// <param name="p_mcmModCacheManager">The manager for the current game mode's mod cache.</param>
 /// <param name="p_stgScriptTypeRegistry">The registry of supported script types.</param>
 public FOModFormat(IModCacheManager p_mcmModCacheManager, IScriptTypeRegistry p_stgScriptTypeRegistry)
 {
     ModCacheManager     = p_mcmModCacheManager;
     IScriptTypeRegistry = p_stgScriptTypeRegistry;
 }
 /// <summary>
 /// A siple constructor that initializes the object with the given dependencies.
 /// </summary>
 /// <param name="p_stgScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> of available <see cref="IScriptType"/>s.</param>
 public InstallScriptEditorVM(IScriptTypeRegistry p_stgScriptTypeRegistry)
     : base(p_stgScriptTypeRegistry)
 {
 }
Example #18
0
 /// <summary>
 /// A simple constructor that initializes the object with the required dependencies.
 /// </summary>
 /// <param name="p_strPath">The path from which to load saved project data.</param>
 /// <param name="p_strScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> contianing the list of available script types.</param>
 public Project(string p_strPath, IScriptTypeRegistry p_strScriptTypeRegistry)
     : this(p_strScriptTypeRegistry)
 {
     Load(p_strPath);
 }
Example #19
0
 /// <summary>
 /// A simple constructor that initializes the object with the required dependencies.
 /// </summary>
 /// <param name="p_strScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> contianing the list of available script types.</param>
 public Project(IScriptTypeRegistry p_strScriptTypeRegistry)
 {
     m_setFiles         = new ThreadSafeObservableList <VirtualFileSystemItem>();
     ModReadme          = new Readme(ReadmeFormat.PlainText, null);
     ScriptTypeRegistry = p_strScriptTypeRegistry;
 }
		/// <summary>
		/// A simple constructor that initializes the object with the given values.
		/// </summary>
		/// <param name="p_vmlScriptEditorVM">The <see cref="InstallScriptEditorVM"/> that encapsulates the data
		/// and operations for diaplying the <see cref="IScript"/> editor.</param>
		/// <param name="p_vmlInfoEditorVM">The <see cref="ModInfoEditorVM"/> that encapsulates the data
		/// and operations for diaplying the <see cref="IModInfo"/> editor.</param>
		/// <param name="p_prjModProject">The <see cref="Project"/> to edit.</param>
		/// <param name="p_srgScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> of available <see cref="IScriptType"/>s.</param>
		/// <param name="p_mpkModBuilder">he <see cref="ModPackager"/> to use to build mod files
		/// from <see cref="Project"/>s.</param>
		public ModPackagingFormVM(InstallScriptEditorVM p_vmlScriptEditorVM, ModInfoEditorVM p_vmlInfoEditorVM, Project p_prjModProject, IScriptTypeRegistry p_srgScriptTypeRegistry, ModPackager p_mpkModBuilder)
		{
			Errors = new ErrorContainer();
			Warnings = new ErrorContainer();

			ScriptEditorVM = p_vmlScriptEditorVM;
			InfoEditorVM = p_vmlInfoEditorVM;
			IScriptTypeRegistry = p_srgScriptTypeRegistry;
			ModBuilder = p_mpkModBuilder;
			
			ModProject = p_prjModProject ?? new Project(p_srgScriptTypeRegistry);

			SaveCommand = new Command<string>("Save Project", "Save the project.", SaveProject, ModProject.IsDirty);
			OpenCommand = new Command("Open Project", "Open a project.", OpenProject);
			NewCommand = new Command("New Project", "Create a new project.", NewProject);
			BuildCommand = new Command<string>("Build Mod", "Builds the mod file.", BuildMod);
		}
Example #21
0
		/// <summary>
		/// A simple constructor that initializes the FOMod from the specified file.
		/// </summary>
		/// <param name="p_strFilePath">The mod file from which to create the FOMod.</param>
		/// <param name="p_mftModFormat">The format of the mod.</param>
		/// <param name="p_strStopFolders">A list of folders names that indicate the root of the mod file structure.</param>
		/// <param name="p_strPluginsDirectoryName">The name of the folder that contains plugins.</param>
		/// <param name="p_mcmModCacheManager">The manager for the current game mode's mod cache.</param>
		/// <param name="p_stgScriptTypeRegistry">The registry of supported script types.</param>
		public FOMod(string p_strFilePath, FOModFormat p_mftModFormat, IEnumerable<string> p_enmStopFolders, string p_strPluginsDirectoryName, IEnumerable<string> p_enmPluginExtensions, IModCacheManager p_mcmModCacheManager, IScriptTypeRegistry p_stgScriptTypeRegistry, bool p_booUsePlugins)
		{
			StopFolders = new List<string>(p_enmStopFolders);
			if (!StopFolders.Contains("fomod", StringComparer.OrdinalIgnoreCase))
				StopFolders.Add("fomod");
			PluginsDirectoryName = p_strPluginsDirectoryName;
			PluginExtensions = new List<string>(p_enmPluginExtensions);

			Format = p_mftModFormat;
			ScriptTypeRegistry = p_stgScriptTypeRegistry;
			bool p_booUseCache = true;
			m_booUsesPlugins = p_booUsePlugins;
			bool booCheckNested = true;
			bool booCheckPrefix = true;
			bool booCheckScript = true;
			bool booUpdateCacheInfo = false;
			bool booDirtyCache = false;
			string strCheckPrefix = null;
			string strCheckScriptPath = null;
			string strCheckScriptType = null;

			m_strFilePath = p_strFilePath;
			m_arcFile = new Archive(p_strFilePath);

			#region Check for cacheInfo.txt file
			m_arcCacheFile = p_mcmModCacheManager.GetCacheFile(m_strFilePath);
			if (m_arcCacheFile != null)
			{
				if (m_arcCacheFile.ContainsFile("cacheInfo.txt"))
				{
					byte[] bCacheInfo = m_arcCacheFile.GetFileContents("cacheInfo.txt");
					string sCacheInfo = Encoding.UTF8.GetString(bCacheInfo, 0, bCacheInfo.Length);
					string[] strPref = sCacheInfo.Split(new string[] { "@@" }, StringSplitOptions.RemoveEmptyEntries);
					if (strPref.Length > 0)
					{
						booCheckNested = Convert.ToBoolean(strPref[0]);

						if (strPref.Length > 1)
						{
							strCheckPrefix = strPref[1];
							foreach (string Folder in IgnoreFolders)
							{
								if (strCheckPrefix.IndexOf(Folder, StringComparison.InvariantCultureIgnoreCase) >= 0)
								{
									booCheckNested = true;
									strCheckPrefix = String.Empty;
									booDirtyCache = true;
									break;
								}
							}
							
							if (!booDirtyCache)
							{

								if (strCheckPrefix.Equals("-"))
									strCheckPrefix = String.Empty;
								booCheckPrefix = false;

								if (strPref.Length > 2)
								{
									strCheckScriptPath = strPref[2];
									if (strCheckScriptPath.Equals("-"))
										strCheckScriptPath = String.Empty;
									strCheckScriptType = strPref[3];
									if (strCheckScriptType.Equals("-"))
										strCheckScriptType = String.Empty;
									booCheckScript = false;
								}
							}
						}
					}
				}
			}

			#endregion

			if (booCheckNested)
			{
				#region Temporary fix for nested .dazip files
				string[] strNested = m_arcFile.GetFiles("", "*.dazip", true);
				if (strNested.Length == 1)
				{
					string strFilePath = Path.Combine(Path.Combine(Path.GetTempPath(), "NMM"), strNested[0]);
					FileUtil.WriteAllBytes(strFilePath, GetFile(strNested[0]));
					if (File.Exists(strFilePath))
					{
						m_arcFile = new Archive(strFilePath);
						m_strNestedFilePath = strFilePath;
					}
				}
				#endregion
			}

			m_arcFile.ReadOnlyInitProgressUpdated += new CancelProgressEventHandler(ArchiveFile_ReadOnlyInitProgressUpdated);

			if (booCheckPrefix)
			{
				FindPathPrefix();
				booUpdateCacheInfo = true;
			}
			else
			{
				m_strPrefixPath = String.IsNullOrEmpty(strCheckPrefix) ? String.Empty : strCheckPrefix;
			}

			//check for script
			if (booCheckScript)
			{
				foreach (IScriptType stpScript in p_stgScriptTypeRegistry.Types)
				{
					foreach (string strScriptName in stpScript.FileNames)
					{
						string strScriptPath = Path.Combine("fomod", strScriptName);
						if (ContainsFile(strScriptPath))
						{
							m_strInstallScriptPath = strScriptPath;
							m_stpInstallScriptType = stpScript;
							break;
						}
					}
					if (!String.IsNullOrEmpty(m_strInstallScriptPath))
						break;
				}

				booUpdateCacheInfo = true;
			}
			else
			{
				m_strInstallScriptPath = strCheckScriptPath;
				m_stpInstallScriptType = String.IsNullOrEmpty(strCheckScriptType) ? null : p_stgScriptTypeRegistry.Types.FirstOrDefault(x => x.TypeName.Equals(strCheckScriptType));
			}

			if (p_booUseCache)
			{
				m_arcCacheFile = p_mcmModCacheManager.GetCacheFile(m_strFilePath);
				//check to make sure the cache isn't bad
				if ((m_arcCacheFile != null) && !m_arcCacheFile.ContainsFile(GetRealPath("fomod/info.xml")))
				{
					//bad cache - clear it
					m_arcCacheFile.Dispose();
					m_arcCacheFile = null;
				}
			}
			m_arcFile.FilesChanged += new EventHandler(Archive_FilesChanged);

			//check for readme
			string strBaseName = Path.GetFileNameWithoutExtension(p_strFilePath);
			for (int i = 0; i < Readme.ValidExtensions.Length; i++)
				if (ContainsFile("readme - " + strBaseName + Readme.ValidExtensions[i]))
				{
					m_strReadmePath = "Readme - " + strBaseName + Readme.ValidExtensions[i];
					break;
				}
			if (String.IsNullOrEmpty(m_strReadmePath))
				for (int i = 0; i < Readme.ValidExtensions.Length; i++)
					if (ContainsFile("docs/readme - " + strBaseName + Readme.ValidExtensions[i]))
					{
						m_strReadmePath = "docs/Readme - " + strBaseName + Readme.ValidExtensions[i];
						break;
					}

			//check for screenshot
			string[] strScreenshots;
			if (p_booUseCache && (m_arcCacheFile != null))
				strScreenshots = m_arcCacheFile.GetFiles(GetRealPath("fomod"), "screenshot*", false);
			else
				strScreenshots = m_arcFile.GetFiles(GetRealPath("fomod"), "screenshot*", false);
			//TODO make sure the file is a valid image
			if (strScreenshots.Length > 0)
				m_strScreenshotPath = strScreenshots[0];

			if (p_booUseCache && (m_arcCacheFile == null))
			{
				string strTmpInfo = p_mcmModCacheManager.FileUtility.CreateTempDirectory();
				try
				{
					Directory.CreateDirectory(Path.Combine(strTmpInfo, GetRealPath("fomod")));

					if (ContainsFile("fomod/info.xml"))
						FileUtil.WriteAllBytes(Path.Combine(strTmpInfo, GetRealPath("fomod/info.xml")), GetFile("fomod/info.xml"));
					else
						FileUtil.WriteAllText(Path.Combine(strTmpInfo, GetRealPath("fomod/info.xml")), "<fomod/>");

					if (!String.IsNullOrEmpty(m_strReadmePath))
						FileUtil.WriteAllBytes(Path.Combine(strTmpInfo, GetRealPath(m_strReadmePath)), GetFile(m_strReadmePath));

					if (!String.IsNullOrEmpty(m_strScreenshotPath))
						FileUtil.WriteAllBytes(Path.Combine(strTmpInfo, GetRealPath(m_strScreenshotPath)), GetFile(m_strScreenshotPath));

					m_arcCacheFile = p_mcmModCacheManager.CreateCacheFile(this, strTmpInfo);
				}
				finally
				{
					FileUtil.ForceDelete(strTmpInfo);
				}
			}

			if (booUpdateCacheInfo || (!m_arcCacheFile.ContainsFile("cacheInfo.txt")))
			{

				Byte[] bteText = new UTF8Encoding(true).GetBytes(String.Format("{0}@@{1}@@{2}@@{3}",
					(!String.IsNullOrEmpty(m_strNestedFilePath)).ToString(),
					String.IsNullOrEmpty(m_strPrefixPath) ? "-" : m_strPrefixPath,
					String.IsNullOrEmpty(m_strInstallScriptPath) ? "-" : m_strInstallScriptPath,
					(m_stpInstallScriptType == null) ? "-" : m_stpInstallScriptType.TypeName));

				if (bteText != null)
					m_arcCacheFile.ReplaceFile("cacheInfo.txt", bteText);
			}

			ModName = Path.GetFileNameWithoutExtension(m_strFilePath);
			LoadInfo();
		}
Example #22
0
		/// <summary>
		/// A simple constructor that initializes the object with the required dependencies.
		/// </summary>
		/// <param name="p_strScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> contianing the list of available script types.</param>
		public Project(IScriptTypeRegistry p_strScriptTypeRegistry)
		{
			m_setFiles = new ThreadSafeObservableList<VirtualFileSystemItem>();
			ModReadme = new Readme(ReadmeFormat.PlainText, null);
			ScriptTypeRegistry = p_strScriptTypeRegistry;
		}
Example #23
0
		/// <summary>
		/// A simple constructor that initializes the object with the required dependencies.
		/// </summary>
		/// <param name="p_strPath">The path from which to load saved project data.</param>
		/// <param name="p_strScriptTypeRegistry">The <see cref="IScriptTypeRegistry"/> contianing the list of available script types.</param>
		public Project(string p_strPath, IScriptTypeRegistry p_strScriptTypeRegistry)
			: this(p_strScriptTypeRegistry)
		{
			Load(p_strPath);
		}
		/// <summary>
		/// A simple constructor that initializes the object with the required dependencies.
		/// </summary>
		/// <param name="p_mcmModCacheManager">The manager for the current game mode's mod cache.</param>
		/// <param name="p_stgScriptTypeRegistry">The registry of supported script types.</param>
		public OModFormat(IModCacheManager p_mcmModCacheManager, IScriptTypeRegistry p_stgScriptTypeRegistry)
		{
			ModCacheManager = p_mcmModCacheManager;
			IScriptTypeRegistry = p_stgScriptTypeRegistry;
		}
        public async Task <IList <string> > GetRequirements(IList <string> modFiles, bool includeAssets, IList <string> allowedTypes)
        {
            CurrentScriptTypeRegistry = await ScriptTypeRegistry.DiscoverScriptTypes(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            // TODO: I don't think there is a good way to determine which image files are referenced by the installer script without
            //   unpacking it first, right?
            IList <string> RequiredFiles = includeAssets
                ? modFiles.Where(path => RequiredExtensions.Contains(Path.GetExtension(path))).ToList()
                : new List <string>();

            return(await Task.Run(() =>
            {
                bool HasFoundScriptType = false;
                foreach (IScriptType scriptType in CurrentScriptTypeRegistry.Types)
                {
                    if ((allowedTypes != null) && !allowedTypes.Contains(scriptType.TypeId))
                    {
                        continue;
                    }

                    if (scriptType.FileNames != null)
                    {
                        foreach (string scriptFile in scriptType.FileNames)
                        {
                            string omodMatch = modFiles.Where(x => x.Equals("script") || x.Equals("script.txt")).FirstOrDefault();
                            bool isOmod = false;
                            try
                            {
                                isOmod = (!string.IsNullOrEmpty(omodMatch) && scriptType.ValidateScript(scriptType.LoadScript(omodMatch)));
                            } catch (Exception) {
                                // don't care
                            }

                            if (isOmod)
                            {
                                HasFoundScriptType = true;
                                RequiredFiles.Add(omodMatch);
                            }
                            else
                            {
                                string fomodMatch = modFiles.Where(x => scriptMatch(x, scriptFile)).FirstOrDefault();
                                if (!string.IsNullOrEmpty(fomodMatch))
                                {
                                    HasFoundScriptType = true;
                                    RequiredFiles.Add(fomodMatch);
                                }
                            }
                        }
                    }

                    if (HasFoundScriptType)
                    {
                        break;
                    }
                }

                if (!HasFoundScriptType)
                {
                    throw new UnsupportedException();
                }

                return RequiredFiles;
            }));
        }
Example #26
0
        static int DoInstall(string game, string filename, string installationPath, string profilePath, string gamePath,
                             List <string> additionalSearchPaths, string seVersion, ref string errorString)
        {
            if (game == null)
            {
                errorString = "no game specified";
                return(1);
            }
            if (filename == null)
            {
                errorString = "no file specified";
                return(1);
            }
            if (profilePath == null)
            {
                errorString = "no profile path specified";
                return(1);
            }
            if (gamePath == null)
            {
                errorString = "no game path specified";
                return(1);
            }
            try
            {
                EnvironmentInfo environmentInfo = new EnvironmentInfo(Properties.Settings.Default);

                string   exeLocation = Assembly.GetExecutingAssembly().Location;
                string   exePath     = System.IO.Path.GetDirectoryName(exeLocation);
                string[] gameModes   = Directory.GetFiles(Path.Combine(exePath, "GameModes"), String.Format("{0}.dll", game));
                if (gameModes.Count() == 0)
                {
                    errorString = "unknown game";
                    return(1);
                }

                Assembly         gameAssembly    = Assembly.LoadFrom(gameModes[0]);
                IGameModeFactory gameModeFactory = null;
                Type[]           exportedTypes   = gameAssembly.GetExportedTypes();
                foreach (Type type in exportedTypes)
                {
                    if (typeof(IGameModeFactory).IsAssignableFrom(type) && !type.IsAbstract)
                    {
                        ConstructorInfo constructor = type.GetConstructor(new Type[] { typeof(EnvironmentInfo) });
                        gameModeFactory = (IGameModeFactory)constructor.Invoke(new Object[] { environmentInfo });
                    }
                }
                if (gameModeFactory == null)
                {
                    errorString = "invalid game";
                    return(1);
                }

                string str7zPath = Path.Combine(environmentInfo.ProgrammeInfoDirectory, environmentInfo.Is64BitProcess ? "7z-64bit.dll" : "7z-32bit.dll");
                SevenZipCompressor.SetLibraryPath(str7zPath);

                FileUtil fileUtil = new NexusFileUtil(environmentInfo);

                environmentInfo.Settings.InstallationPaths[gameModeFactory.GameModeDescriptor.ModeId] = installationPath;
                environmentInfo.Settings.ModFolder[gameModeFactory.GameModeDescriptor.ModeId]         = installationPath;
//                environmentInfo.Settings.InstallInfoFolder[gameModeFactory.GameModeDescriptor.ModeId] = environmentInfo.TemporaryPath;
                environmentInfo.Settings.InstallInfoFolder[gameModeFactory.GameModeDescriptor.ModeId] = Path.Combine(installationPath, "temp");
                if (environmentInfo.Settings.DelayedSettings[gameModeFactory.GameModeDescriptor.ModeId] == null)
                {
                    environmentInfo.Settings.DelayedSettings[gameModeFactory.GameModeDescriptor.ModeId] = new KeyedSettings <string>();
                }
                if (environmentInfo.Settings.DelayedSettings["ALL"] == null)
                {
                    environmentInfo.Settings.DelayedSettings["ALL"] = new KeyedSettings <string>();
                }

                ViewMessage warning = null;

                IGameMode gameMode = gameModeFactory.BuildGameMode(fileUtil, out warning);

                IModCacheManager cacheManager = new NexusModCacheManager(environmentInfo.TemporaryPath, gameMode.GameModeEnvironmentInfo.ModDirectory, fileUtil);

                IScriptTypeRegistry scriptTypeRegistry = ScriptTypeRegistry.DiscoverScriptTypes(Path.Combine(Path.GetDirectoryName(exeLocation), "ScriptTypes"), gameMode, new List <string>());
                if (scriptTypeRegistry.Types.Count == 0)
                {
                    errorString = "No script types were found.";
                    return(2);
                }

                // use a proxy so we can intercept accesses to the IGameMode interface. This allows us to make the additional search paths accessible from
                // the sandbox and feed in the script extender version even though the nmm lib won't find it.
                // This has to happen after DiscoverScriptTypes becaus that function tries to localize the assembly which fails for the dynamic assembly
                // of the proxy. Fortunately DiscoverScriptTypes has no side-effects on the gameMode.
                // This recreates the gamemode object so it's important no code above modifies gameMode
                ProxyGenerator      generator   = new ProxyGenerator();
                GameModeInterceptor interceptor = new GameModeInterceptor(additionalSearchPaths, seVersion != null ? new Version(seVersion) : null);

                gameMode = (IGameMode)generator.CreateClassProxy(gameMode.GetType(), new object[] { environmentInfo, fileUtil }, new IInterceptor[] { interceptor });

                IModFormatRegistry formatRegistry = ModFormatRegistry.DiscoverFormats(cacheManager, gameMode.SupportedFormats, scriptTypeRegistry, Path.Combine(Path.GetDirectoryName(exeLocation), "ModFormats"));
                if (formatRegistry.Formats.Count == 0)
                {
                    errorString = "No formats were found.";
                    return(2);
                }

                // we install the mod from the temporary path. Unfortunately this requires the archive to be copied, otherwise the sandbox will
                // prevent the installer script from accessing the archive in its original location
                string fileNameTemporary = Path.Combine(environmentInfo.TemporaryPath, Path.GetFileName(filename));
                File.Copy(filename, fileNameTemporary);
                IMod mod = CreateMod(fileNameTemporary, formatRegistry, gameMode);
                if (mod == null)
                {
                    errorString = "failed to initialize mod";
                    return(3);
                }

                System.IO.File.WriteAllText(installationPath + "/__installInfo.txt", mod.ModName + "\n" + mod.HumanReadableVersion + "\n" + mod.Id);

                if (mod.HasInstallScript)
                {
                    DummyDataFileUtilFactory dummyFactory = null;
                    IDataFileUtil            dataFileUtility;
                    Logger.Info("Detected C# script that relies on files in the actual data folder");

                    string modlistFile = Path.Combine(profilePath, "modlist.txt");
                    // ASSUMED mods path is the parent directory of the gameMode.InstallationPath
                    string modsPath = Directory.GetParent(gameMode.InstallationPath).FullName;
                    // Prepare dummy data directory
                    dummyFactory    = new DummyDataFileUtilFactory(gameMode.GameModeEnvironmentInfo.InstallationPath, modlistFile, modsPath, gamePath, additionalSearchPaths);
                    dataFileUtility = dummyFactory.CreateDummyDataFileUtil();

                    TxFileManager  fileManager     = new TxFileManager();
                    IInstallLog    installLog      = new DummyInstallLog();
                    IIniInstaller  iniIniInstaller = new IniInstaller(mod, installLog, fileManager, delegate { return(OverwriteResult.No); });
                    IPluginManager pluginManager   = new DummyPluginManager(Path.Combine(profilePath, "plugins.txt"), gameMode, mod);
                    IGameSpecificValueInstaller gameSpecificValueInstaller = gameMode.GetGameSpecificValueInstaller(mod, installLog, fileManager, new NexusFileUtil(environmentInfo), delegate { return(OverwriteResult.No); });
                    IModFileInstaller           fileInstaller = new ModFileInstaller(gameMode.GameModeEnvironmentInfo, mod, installLog, pluginManager, dataFileUtility, fileManager, delegate { return(OverwriteResult.No); }, false);
                    InstallerGroup       installers           = new InstallerGroup(dataFileUtility, fileInstaller, iniIniInstaller, gameSpecificValueInstaller, pluginManager);
                    IVirtualModActivator modActivator         = new DummyVirtualModActivator(gameMode, environmentInfo);
                    IScriptExecutor      executor             = mod.InstallScript.Type.CreateExecutor(mod, gameMode, environmentInfo, modActivator, installers, SynchronizationContext.Current);
                    // run the script in a second thread and start the main loop in the main thread to ensure we can handle message boxes and the like
                    ScriptRunner runner = new ScriptRunner(executor, mod.InstallScript);

                    runner.Execute();
                    runner.TaskEnded += delegate
                    {
                        iniIniInstaller.FinalizeInstall();
                        gameSpecificValueInstaller.FinalizeInstall();
                        mod.EndReadOnlyTransaction();

                        Application.Exit();
                    };

                    Application.Run();
                    switch (runner.Status)
                    {
                    case BackgroundTasks.TaskStatus.Cancelled: return(11);

                    case BackgroundTasks.TaskStatus.Error: return(6);

                    case BackgroundTasks.TaskStatus.Incomplete: return(10);

                    default: return(0);
                    }
                }
                else
                {
                    errorString = "no install script";
                    return(4);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("exception: " + e.Message);
                MessageBox.Show(e.Message, "Installation failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(5);
            }
        }