Encapsulates the interactions with an archive file.
Inheritance: IDisposable
		/// <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;
			}
		}
示例#2
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"));
		}
		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;
		}
示例#5
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>
		/// 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;
		}
示例#8
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();
		}
		/// <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;
		}
示例#10
0
		/// <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;
		}