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); }
/// <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; } }
/// <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); }
/// <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"); } }
/// <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")); }
/// <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) { }
/// <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 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_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); }
/// <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(); }
/// <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 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; })); }
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); } }