/// <summary> /// Loads the children of the given node. /// </summary> /// <param name="p_tndFolder">The node whose children are to be loaded.</param> protected void LoadChildren(FileSystemTreeNode p_tndFolder) { if (p_tndFolder.LastSource.IsLoaded || !p_tndFolder.IsDirectory && (!BrowseIntoArchives || !p_tndFolder.IsArchive)) return; Cursor crsOldCursor = Cursor; Cursor = Cursors.WaitCursor; try { p_tndFolder.LastSource.IsLoaded = true; string strPath = p_tndFolder.LastSource; if (BrowseIntoArchives && (Archive.IsArchivePath(strPath) || p_tndFolder.IsArchive)) { KeyValuePair<string, string> kvpPath = new KeyValuePair<string, string>(p_tndFolder.LastSource, Path.DirectorySeparatorChar.ToString()); if (Archive.IsArchivePath(strPath)) kvpPath = Archive.ParseArchivePath(strPath); Archive arcArchive = new Archive(kvpPath.Key); string[] strFolders = arcArchive.GetDirectories(kvpPath.Value); for (Int32 i = 0; i < strFolders.Length; i++) AddPath(p_tndFolder, Archive.GenerateArchivePath(kvpPath.Key, strFolders[i])); if (ShowFiles) { string[] strFiles = arcArchive.GetFiles(kvpPath.Value, false); for (Int32 i = 0; i < strFiles.Length; i++) AddPath(p_tndFolder, Archive.GenerateArchivePath(kvpPath.Key, strFiles[i])); } } else { try { string[] strFolders = Directory.GetDirectories(strPath); for (Int32 i = 0; i < strFolders.Length; i++) AddPath(p_tndFolder, strFolders[i]); if (ShowFiles) { string[] strFiles = Directory.GetFiles(strPath); for (Int32 i = 0; i < strFiles.Length; i++) AddPath(p_tndFolder, strFiles[i]); } } catch (UnauthorizedAccessException) { } } } finally { Cursor = crsOldCursor; } }
/// <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")); }
public Image GetImage(string p_strImagePath) { if (ModFiles == null) return null; VirtualFileSystemItem vfiItem = ModFiles.Find((f) => { return f.Path.Equals(p_strImagePath, StringComparison.OrdinalIgnoreCase); }); byte[] bteImage = null; if (vfiItem != null) { if (Archive.IsArchivePath(vfiItem.Source)) { KeyValuePair<string, string> kvpArchive = Archive.ParseArchivePath(vfiItem.Source); using (Archive arcMod = new Archive(kvpArchive.Key)) { bteImage = arcMod.GetFileContents(kvpArchive.Value); } } else if (File.Exists(vfiItem.Source)) { bteImage = File.ReadAllBytes(vfiItem.Source); } } if (bteImage == null) return null; using (MemoryStream msmImage = new MemoryStream(bteImage)) { try { Image imgTmp = Image.FromStream(msmImage); return new Bitmap(imgTmp); } catch (ArgumentException) { } } return null; }
/// <summary> /// Get the ReadMe file path if it exists. /// </summary> /// <param name="p_strFileName">The mod file name.</param> /// <param name="p_intReadmeFile">The index of the readme file to get.</param> public string GetModReadMe(string p_strModName, string p_strFileName) { string strReadMe = String.Empty; if (m_dicReadMeFiles.ContainsKey(p_strModName)) { string strModReadMeFile = p_strModName + ".7z"; strModReadMeFile = Path.Combine(m_strReadMePath, strModReadMeFile); if (File.Exists(strModReadMeFile)) { PurgeTempFolder(); Archive arcFile = new Archive(strModReadMeFile); byte[] bteData = arcFile.GetFileContents(p_strFileName); if ((bteData != null) && (bteData.Length > 0)) { TxFileManager tfmFileManager = new TxFileManager(); string strReadMeFile = Path.Combine(ReadMeTempPath, p_strFileName); tfmFileManager.WriteAllBytes(strReadMeFile, bteData); return strReadMeFile; } } } return strReadMe; }
/// <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> /// Retrieves the list of all files in the specified folder. /// </summary> /// <param name="p_arcArchive">The archive whose file is to be retrieved.</param> /// <param name="p_booRecurse">Whether to return files that are in subdirectories of the given directory.</param> /// <returns>The list of all files in the specified folder.</returns> private List<string> GetFileList(Archive p_arcArchive, bool p_booRecurse) { List<string> lstFiles = new List<string>(); foreach (string strFile in p_arcArchive.GetFiles("", "*.txt|*.doc|*.docx|*.htm|*.html|*.rtf|*.pdf", p_booRecurse)) if (!m_dicMovedArchiveFiles.ContainsValue(strFile)) if (!strFile.StartsWith("fomod", StringComparison.OrdinalIgnoreCase)) lstFiles.Add(strFile); string strPathPrefix = "" ?? ""; strPathPrefix = strPathPrefix.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); strPathPrefix = strPathPrefix.Trim(Path.DirectorySeparatorChar); if (strPathPrefix.Length > 0) strPathPrefix += Path.DirectorySeparatorChar; foreach (string strFile in m_dicMovedArchiveFiles.Keys) if (strFile.StartsWith(strPathPrefix, StringComparison.OrdinalIgnoreCase) && !strFile.StartsWith("fomod", StringComparison.OrdinalIgnoreCase)) lstFiles.Add(strFile); return lstFiles; }
/// <summary> /// Verifies if the readme file exists in the archive and saves it to the ReadMe folder. /// </summary> /// <param name="p_strArchivePath">The path to the mod archive.</param> public bool VerifyReadMeFile(TxFileManager p_tfmFileManager, string p_strArchivePath) { try { Archive arcFile = new Archive(p_strArchivePath); List<string> lstFiles = GetFileList(arcFile, true); string strReadMePath = m_strReadMePath; string strFileName = String.Empty; string strReadMeFile = String.Empty; string strModFile = Path.GetFileName(p_strArchivePath); string strArchiveFile = Path.GetFileNameWithoutExtension(strModFile) + ".7z"; byte[] bteData = null; PurgeTempFolder(); for (int i = 0; i < lstFiles.Count; i++) { strFileName = lstFiles[i].ToString(); if (Readme.IsValidReadme(strFileName)) { bteData = arcFile.GetFileContents(lstFiles[i]); if (bteData.Length > 0) { strReadMeFile = Path.GetFileName(strFileName); strReadMePath = Path.Combine(ReadMeTempPath, strReadMeFile); p_tfmFileManager.WriteAllBytes(strReadMePath, bteData); } } } string[] strFilesToCompress = Directory.GetFiles(ReadMeTempPath, "*.*", SearchOption.AllDirectories); if (strFilesToCompress.Length > 0) if (CreateReadMeArchive(strArchiveFile, strFilesToCompress)) { for (int i = 0; i < strFilesToCompress.Length; i++) { strFilesToCompress[i] = Path.GetFileName(strFilesToCompress[i]); } m_dicReadMeFiles.Add(Path.GetFileNameWithoutExtension(strArchiveFile), strFilesToCompress); } } catch { return false; } return true; }
/// <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> /// Determines if the specified file in a mod that conforms to the current format. /// </summary> /// <param name="p_strPath">The path of the file for which it is to be determined whether it confroms /// to the current format.</param> /// <returns>A <see cref="FormatConfidence"/> indicating how much the specified file conforms /// to the current format.</returns> public FormatConfidence CheckFormatCompliance(string p_strPath) { if (String.IsNullOrEmpty(p_strPath) || !File.Exists(p_strPath) || !Archive.IsArchive(p_strPath)) return FormatConfidence.Incompatible; using (Archive arcMod = new Archive(p_strPath)) { //full-on OMod if (arcMod.ContainsFile("config") && (arcMod.ContainsFile("plugins.crc") || arcMod.ContainsFile("data.crc") || arcMod.ContainsFile("image") || arcMod.ContainsFile("readme") || arcMod.ContainsFile("script"))) return FormatConfidence.Match; //OMod-ready archive string[] strFiles= arcMod.GetFiles(null, "omod conversion data/config", true); if (strFiles.Length > 0) return FormatConfidence.Match; } return FormatConfidence.Incompatible; }
/// <summary> /// Determines if the specified file in a mod that conforms to the current format. /// </summary> /// <param name="p_strPath">The path of the file for which it is to be determined whether it confroms /// to the current format.</param> /// <returns>A <see cref="FormatConfidence"/> indicating how much the specified file conforms /// to the current format.</returns> public FormatConfidence CheckFormatCompliance(string p_strPath) { if (String.IsNullOrEmpty(p_strPath) || !File.Exists(p_strPath) || !Archive.IsArchive(p_strPath)) return FormatConfidence.Incompatible; using (Archive arcMod = new Archive(p_strPath)) { if (arcMod.GetFiles("fomod", true).Length > 0) return FormatConfidence.Match; } return FormatConfidence.Compatible; }