/// <summary> /// Upgrades the ini edits log entries. /// </summary> /// <remarks> /// This analyses the mods and determines, as best as possible, who edited which keys, and attempts /// to reconstruct the install order. The resulting information is then put in the new install log. /// </remarks> /// <param name="p_xmlModInstallLog">The current mod install log we are parsing to upgrade.</param> /// <param name="p_strModBaseName">The base name of the mod whose install log is being parsed.</param> private void UpgradeIniEdits(XmlDocument p_xmlModInstallLog, string p_strModBaseName) { var xnlIniEdits = p_xmlModInstallLog.SelectNodes("descendant::iniEdits/*"); foreach (XmlNode xndIniEdit in xnlIniEdits) { var strFile = xndIniEdit.Attributes.GetNamedItem("file").Value; var strSection = xndIniEdit.Attributes.GetNamedItem("section").Value; var strKey = xndIniEdit.Attributes.GetNamedItem("key").Value; string strOldIniEditor; var strOldValue = GetOldIniValue(strFile, strSection, strKey, out strOldIniEditor); if (p_strModBaseName.Equals(strOldIniEditor)) { //this mod owns the ini edit, so append it to the list of editing mods... InstallLog.Current.AddIniEdit(strFile, strSection, strKey, p_strModBaseName, NativeMethods.GetPrivateProfileString(strSection, strKey, "", strFile)); //...and backup the old value as the original value InstallLog.Current.PrependAfterOriginalIniEdit(strFile, strSection, strKey, InstallLog.ORIGINAL_VALUES, strOldValue); } else { //someone else made the ini edit // we don't know what value was overwritten, so we will just use what we have // which is the old value stored in the old install log InstallLog.Current.PrependAfterOriginalIniEdit(strFile, strSection, strKey, p_strModBaseName, strOldValue); } if (ProgressWorker.Cancelled()) { return; } ProgressWorker.StepItemProgress(); } }
/// <summary> /// Upgrades the sdp edits log entries. /// </summary> /// <remarks> /// This analyses the mods and determines, as best as possible, who edited which shaders, and attempts /// to reconstruct the install order. The resulting information is then put in the new install log. /// </remarks> /// <param name="p_xmlModInstallLog">The current mod install log we are parsing to upgrade.</param> /// <param name="p_strModBaseName">The base name of the mod whose install log is being parsed.</param> private void UpgradeSdpEdits(XmlDocument p_xmlModInstallLog, string p_strModBaseName) { var xnlSdpEdits = p_xmlModInstallLog.SelectNodes("descendant::sdpEdits/*"); foreach (XmlNode xndSdpEdit in xnlSdpEdits) { var intPackage = Int32.Parse(xndSdpEdit.Attributes.GetNamedItem("package").Value); var strShader = xndSdpEdit.Attributes.GetNamedItem("shader").Value; var strShaderKey = String.Format("sdp:{0}/{1}", intPackage, strShader); var bteOldValue = GetOldSdpValue(intPackage, strShader); //we have no way of knowing who last edited the shader - that information // was not tracked // so, let's just do first come first serve if (!m_lstSeenShader.Contains(intPackage + "~" + strShader.ToLowerInvariant())) { //this is the first mod we have encountered that edited this shader, // so let's assume it is the lastest mod to have made the edit... InstallLog.Current.AddGameSpecificValueEdit(p_strModBaseName, strShaderKey, SDPArchives.GetShader(intPackage, strShader)); //...and backup the old value as the original value InstallLog.Current.PrependAfterOriginalGameSpecificValueEdit(InstallLog.ORIGINAL_VALUES, strShaderKey, bteOldValue); m_lstSeenShader.Add(intPackage + "~" + strShader.ToLowerInvariant()); } else { //someone else made the shader edit // we don't know what value was overwritten, so we will just use what we have // which is the old value InstallLog.Current.PrependAfterOriginalGameSpecificValueEdit(p_strModBaseName, strShaderKey, bteOldValue); } if (ProgressWorker.Cancelled()) { return; } ProgressWorker.StepItemProgress(); } }
/// <summary> /// Upgrades the installed files log entries. /// </summary> /// <remarks> /// This analyses the mods and determines, as best as possible, who owns which files, and attempts /// to reconstruct the install order. It populates the overwrites folder with the files that, as far /// as can be determined, belong there. This resulting information is then put in the new install log. /// </remarks> /// <param name="p_xmlModInstallLog">The current mod install log we are parsing to upgrade.</param> /// <param name="p_strModInstallLogPath">The path to the current mod install log.</param> /// <param name="p_strModBaseName">The base name of the mod whose install log is being parsed.</param> private void UpgradeInstalledFiles(XmlDocument p_xmlModInstallLog, fomod p_fomodMod, string p_strModBaseName) { var intDataPathStartPos = Program.GameMode.PluginsPath.Trim(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar).Length + 1; var xnlFiles = p_xmlModInstallLog.SelectNodes("descendant::installedFiles/*"); foreach (XmlNode xndFile in xnlFiles) { var strFile = xndFile.InnerText; if (!File.Exists(strFile)) { continue; } var strDataRelativePath = strFile.Substring(intDataPathStartPos); var crcDiskFile = new Crc32(); var crcFomodFile = new Crc32(); crcDiskFile.Update(File.ReadAllBytes(strFile)); if (!p_fomodMod.ContainsFile(strDataRelativePath)) { //we don't know if this mod owns the file, so let's assume // it doesn't //put this mod's file into the overwrites directory. // we can't get the original file from the fomod, // so we'll use the existing file instead. this isn't // strictly correct, but it is inline with the behaviour // of the fomm version we are upgrading from var strDirectory = Path.GetDirectoryName(strDataRelativePath); var strBackupPath = Path.Combine(Program.GameMode.OverwriteDirectory, strDirectory); var strModKey = InstallLog.Current.GetModKey(p_strModBaseName); if (!Directory.Exists(strBackupPath)) { FileManager.CreateDirectory(strBackupPath); } strBackupPath = Path.Combine(strBackupPath, strModKey + "_" + Path.GetFileName(strDataRelativePath)); FileManager.Copy(Path.Combine(Program.GameMode.PluginsPath, strDataRelativePath), strBackupPath, true); InstallLog.Current.PrependDataFile(p_strModBaseName, strDataRelativePath); //however, it may own the file, so let's make it the default owner for now // unless we already know who the owner is if (!FileOwnerIsKnown(strDataRelativePath)) { m_dicDefaultFileOwners[strDataRelativePath] = p_strModBaseName; } continue; } var bteFomodFile = p_fomodMod.GetFileContents(strDataRelativePath); crcFomodFile.Update(bteFomodFile); if (!crcDiskFile.Value.Equals(crcFomodFile.Value) || FileOwnerIsKnown(strDataRelativePath)) { //either: // 1) another mod owns the file // 2) according to the crc we own this file, however we have already found // an owner. this could happen beacue two mods use the same version // of a file, or there is a crc collision. //either way, put this mod's file into // the overwrites directory var strDirectory = Path.GetDirectoryName(strDataRelativePath); var strBackupPath = Path.Combine(Program.GameMode.OverwriteDirectory, strDirectory); var strModKey = InstallLog.Current.GetModKey(p_strModBaseName); if (!Directory.Exists(strBackupPath)) { FileManager.CreateDirectory(strBackupPath); } strBackupPath = Path.Combine(strBackupPath, strModKey + "_" + Path.GetFileName(strDataRelativePath)); FileManager.WriteAllBytes(strBackupPath, bteFomodFile); InstallLog.Current.PrependDataFile(p_strModBaseName, strDataRelativePath); } else { //this mod owns the file, so append it to the list of installing mods InstallLog.Current.AddDataFile(p_strModBaseName, strDataRelativePath); //we also have to displace the mod that is currently the default owner if (m_dicDefaultFileOwners.ContainsKey(strDataRelativePath)) { m_dicDefaultFileOwners.Remove(strDataRelativePath); } } if (ProgressWorker.Cancelled()) { return; } ProgressWorker.StepItemProgress(); } }