/// <summary> /// Writes the file represented by the given byte array to the given path. /// </summary> /// <remarks> /// This method writes the given data as a file at the given path, if it is owned /// by the mod being upgraded. If the specified data file is not owned by the mod /// being upgraded, the file is instead written to the overwrites directory. /// /// If the file was not previously installed by the mod, then the normal install rules apply, /// including confirming overwrite if applicable. /// </remarks> /// <param name="p_strPath">The path where the file is to be created.</param> /// <param name="p_bteData">The data that is to make up the file.</param> /// <param name="p_booSecondaryInstallPath">Whether to use the secondary install path.</param> /// <returns><c>true</c> if the file was written; <c>false</c> if the user chose /// not to overwrite an existing file.</returns> /// <exception cref="IllegalFilePathException">Thrown if <paramref name="p_strPath"/> is /// not safe.</exception> public override bool GenerateDataFile(string p_strPath, byte[] p_bteData, bool p_booSecondaryInstallPath) { DataFileUtility.AssertFilePathIsSafe(p_strPath); string strInstallFilePath = Path.Combine(GameModeInfo.InstallationPath, p_strPath); IList <IMod> lstInstallers = InstallLog.GetFileInstallers(p_strPath); if (lstInstallers.Contains(Mod, ModComparer.Filename)) { string strWritePath = null; if (!ModComparer.Filename.Equals(lstInstallers[lstInstallers.Count - 1], Mod)) { string strDirectory = Path.GetDirectoryName(p_strPath); string strBackupPath = Path.Combine(GameModeInfo.OverwriteDirectory, strDirectory); string strOldModKey = InstallLog.GetModKey(Mod); string strFile = strOldModKey + "_" + Path.GetFileName(p_strPath); strWritePath = Path.Combine(strBackupPath, strFile); } else { strWritePath = strInstallFilePath; } TransactionalFileManager.WriteAllBytes(strWritePath, p_bteData); OriginallyInstalledFiles.Remove(p_strPath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)); return(true); } return(base.GenerateDataFile(p_strPath, p_bteData, false)); }
/// <summary> /// Edits the specified game specific value. /// </summary> /// <remarks> /// This method writes the given value in the specified game specific value, if it /// is owned by the mod being upgraded. If the specified edit is not owned by the /// mod being upgraded, the edit is archived in the install log. /// /// If the edit was not previously installed by the mod, then the normal install /// rules apply, including confirming overwrite if applicable. /// </remarks> /// <param name="p_strKey">The key of the edited Game Specific Value.</param> /// <param name="p_bteValue">The value to install.</param> /// <returns><c>true</c> if the value was set; <c>false</c> otherwise.</returns> public override bool EditGameSpecificValue(string p_strKey, byte[] p_bteValue) { IList <IMod> lstInstallers = InstallLog.GetGameSpecificValueEditInstallers(p_strKey); if (lstInstallers.Contains(Mod, ModComparer.Filename)) { if (!ModComparer.Filename.Equals(lstInstallers[lstInstallers.Count - 1], Mod)) { InstallLog.ReplaceGameSpecificValueEdit(Mod, p_strKey, p_bteValue); } else { ShaderEdit sedShader = new ShaderEdit(p_strKey); SDPArchives sdpManager = new SDPArchives(GameModeInfo, FileUtility); if (!TouchedFiles.Contains(sdpManager.GetPath(sedShader.Package))) { TouchedFiles.Add(sdpManager.GetPath(sedShader.Package)); TransactionalFileManager.Snapshot(sdpManager.GetPath(sedShader.Package)); } byte[] oldData; if (!sdpManager.EditShader(sedShader.Package, sedShader.ShaderName, p_bteValue, out oldData)) { throw new Exception("Failed to edit the shader"); } } OriginallyInstalledEdits.Remove(p_strKey); return(true); } return(base.EditGameSpecificValue(p_strKey, p_bteValue)); }
/// <summary> /// Sets the specified value in the specified Ini file to the given value. /// </summary> /// <remarks> /// This method writes the given value in the specified Ini value, if it is owned /// by the mod being upgraded. If the specified Ini edit is not owned by the mod /// being upgraded, the Ini edit is archived in the install log. /// /// If the Ini edit was not previously installed by the mod, then the normal install /// rules apply, including confirming overwrite if applicable. /// </remarks> /// <param name="p_strSettingsFileName">The name of the settings file to edit.</param> /// <param name="p_strSection">The section in the Ini file to edit.</param> /// <param name="p_strKey">The key in the Ini file to edit.</param> /// <param name="p_strValue">The value to which to set the key.</param> /// <returns><c>true</c> if the value was set; <c>false</c> /// if the user chose not to overwrite the existing value.</returns> public override bool EditIni(string p_strSettingsFileName, string p_strSection, string p_strKey, string p_strValue) { IList <IMod> lstInstallers = InstallLog.GetIniEditInstallers(p_strSettingsFileName, p_strSection, p_strKey); if (lstInstallers.Contains(Mod, ModComparer.Filename)) { if (!ModComparer.Filename.Equals(lstInstallers[lstInstallers.Count - 1], Mod)) { InstallLog.ReplaceIniEdit(Mod, p_strSettingsFileName, p_strSection, p_strKey, p_strValue); } else { if (!TouchedFiles.Contains(p_strSettingsFileName)) { TouchedFiles.Add(p_strSettingsFileName); TransactionalFileManager.Snapshot(p_strSettingsFileName); } IniMethods.WritePrivateProfileString(p_strSection, p_strKey, p_strValue, p_strSettingsFileName); } IniEdit iniEdit = new IniEdit(p_strSettingsFileName, p_strSection, p_strKey); OriginallyInstalledEdits.Remove(iniEdit); return(true); } return(base.EditIni(p_strSettingsFileName, p_strSection, p_strKey, p_strValue)); }
/// <summary> /// Undoes the edit made to the spcified key. /// </summary> /// <param name="p_strSettingsFileName">The name of the settings file to unedit.</param> /// <param name="p_strSection">The section in the Ini file to unedit.</param> /// <param name="p_strKey">The key in the Ini file to unedit.</param> public void UneditIni(string p_strSettingsFileName, string p_strSection, string p_strKey) { string strKey = InstallLog.GetModKey(Mod); string strCurrentOwnerKey = InstallLog.GetCurrentIniEditOwnerKey(p_strSettingsFileName, p_strSection, p_strKey); //if we didn't edit the value, then leave it alone if (!strKey.Equals(strCurrentOwnerKey)) { return; } if (!TouchedFiles.Contains(p_strSettingsFileName)) { TouchedFiles.Add(p_strSettingsFileName); TransactionalFileManager.Snapshot(p_strSettingsFileName); } //if we did edit the value, replace if with the value we overwrote. // if we didn't overwrite a value, then just delete it. // writing null effectively deletes the value, so if // strPreviousValue is null, indicating we didn't overwrite a value, // we still write it string strPreviousValue = InstallLog.GetPreviousIniValue(p_strSettingsFileName, p_strSection, p_strKey); IniMethods.WritePrivateProfileString(p_strSection, p_strKey, strPreviousValue, p_strSettingsFileName); InstallLog.RemoveIniEdit(Mod, p_strSettingsFileName, p_strSection, p_strKey); }
/// <summary> /// Sets the specified value in the specified Ini file to the given value. /// </summary> /// <param name="p_strSettingsFileName">The name of the settings file to edit.</param> /// <param name="p_strSection">The section in the Ini file to edit.</param> /// <param name="p_strKey">The key in the Ini file to edit.</param> /// <param name="p_strValue">The value to which to set the key.</param> /// <returns><c>true</c> if the value was set; <c>false</c> /// if the user chose not to overwrite the existing value.</returns> public virtual bool EditIni(string p_strSettingsFileName, string p_strSection, string p_strKey, string p_strValue) { if (m_booDontOverwriteAllIni) { return(false); } if (!TouchedFiles.Contains(p_strSettingsFileName)) { TouchedFiles.Add(p_strSettingsFileName); TransactionalFileManager.Snapshot(p_strSettingsFileName); } IMod modOldMod = InstallLog.GetCurrentIniEditOwner(p_strSettingsFileName, p_strSection, p_strKey); string strOldValue = IniMethods.GetPrivateProfileString(p_strSection, p_strKey, null, p_strSettingsFileName); if (!m_booOverwriteAllIni) { string strMessage = null; if (modOldMod != null) { strMessage = String.Format("Key '{{0}}' in section '{{1}}' of {{2}} has already been overwritten by '{0}'\n" + "Overwrite again with this mod?\n" + "Current value '{{3}}', new value '{{4}}'", modOldMod.ModName); } else { strMessage = "The mod wants to modify key '{0}' in section '{1}' of {2}.\n" + "Allow the change?\n" + "Current value '{3}', new value '{4}'"; } switch (m_dlgOverwriteConfirmationDelegate(String.Format(strMessage, p_strKey, p_strSection, p_strSettingsFileName, strOldValue, p_strValue), false, false)) { case OverwriteResult.YesToAll: m_booOverwriteAllIni = true; break; case OverwriteResult.NoToAll: m_booDontOverwriteAllIni = true; break; case OverwriteResult.Yes: break; default: return(false); } } //if we are overwriting an original value, back it up if ((modOldMod == null) && (strOldValue != null)) { InstallLog.LogOriginalIniValue(p_strSettingsFileName, p_strSection, p_strKey, strOldValue); } IniMethods.WritePrivateProfileString(p_strSection, p_strKey, p_strValue, p_strSettingsFileName); InstallLog.AddIniEdit(Mod, p_strSettingsFileName, p_strSection, p_strKey, p_strValue); return(true); }
/// <summary> /// This does the actual uninstallation; it removes the files and undoes any edits the /// fomod made. /// </summary> /// <returns> /// <lang langref="true" /> if the script work was completed successfully and needs to /// be committed; <lang langref="false" /> otherwise. /// </returns> /// <seealso cref="ModInstallScript.DoScript" /> protected override bool DoScript() { foreach (var strSettingsFile in Program.GameMode.SettingsFiles.Values) { TransactionalFileManager.Snapshot(strSettingsFile); } foreach (var strAdditionalFile in Program.GameMode.AdditionalPaths.Values) { if (File.Exists(strAdditionalFile)) { TransactionalFileManager.Snapshot(strAdditionalFile); } } TransactionalFileManager.Snapshot(InstallLog.Current.InstallLogPath); bool booIsActive; try { if (Fomod != null) { MergeModule = InstallLog.Current.GetMergeModule(Fomod.BaseName); if (Fomod.HasUninstallScript) { Fomod.IsActive = !RunCustomUninstallScript(); } else { Fomod.IsActive = !RunBasicUninstallScript(); } if (!Fomod.IsActive) { InstallLog.Current.UnmergeModule(Fomod.BaseName); } booIsActive = Fomod.IsActive; } else { MergeModule = InstallLog.Current.GetMergeModule(m_strBaseName); booIsActive = !RunBasicUninstallScript(); InstallLog.Current.UnmergeModule(m_strBaseName); } } catch (Exception e) { if (Fomod != null) { Fomod.IsActive = true; } throw e; } if (booIsActive) { return(false); } return(true); }
/// <summary> /// Edits the specified game specific value. /// </summary> /// <param name="p_strKey">The key of the edited Game Specific Value.</param> /// <param name="p_bteValue">The value to install.</param> /// <returns><c>true</c> if the value was set; <c>false</c> otherwise.</returns> public virtual bool EditGameSpecificValue(string p_strKey, byte[] p_bteValue) { if (m_booDontOverwriteAll) { return(false); } ShaderEdit sedShader = new ShaderEdit(p_strKey); SDPArchives sdpManager = new SDPArchives(GameModeInfo, FileUtility); if (!TouchedFiles.Contains(sdpManager.GetPath(sedShader.Package))) { TouchedFiles.Add(sdpManager.GetPath(sedShader.Package)); TransactionalFileManager.Snapshot(sdpManager.GetPath(sedShader.Package)); } IMod modOldMod = InstallLog.GetCurrentGameSpecificValueEditOwner(p_strKey); if (!m_booOverwriteAll && (modOldMod != null)) { string strMessage = String.Format("Shader '{0}' in package '{1}' has already been overwritten by '{2}'\n" + "Overwrite the changes?", sedShader.ShaderName, sedShader.Package, modOldMod.ModName); switch (m_dlgOverwriteConfirmationDelegate(strMessage, false, false)) { case OverwriteResult.YesToAll: m_booOverwriteAll = true; break; case OverwriteResult.NoToAll: m_booDontOverwriteAll = true; break; case OverwriteResult.Yes: break; default: return(false); } } byte[] oldData; if (!sdpManager.EditShader(sedShader.Package, sedShader.ShaderName, p_bteValue, out oldData)) { throw new Exception("Failed to edit the shader"); } //if we are overwriting an original shader, back it up if ((modOldMod == null) && (oldData != null)) { InstallLog.LogOriginalGameSpecificValue(p_strKey, oldData); } InstallLog.AddGameSpecificValueEdit(Mod, p_strKey, p_bteValue); return(true); }
/// <summary> /// Installs the mod and activates it. /// </summary> protected override bool DoScript() { foreach (var strSettingsFile in Program.GameMode.SettingsFiles.Values) { TransactionalFileManager.Snapshot(strSettingsFile); } foreach (var strAdditionalFile in Program.GameMode.AdditionalPaths.Values) { if (File.Exists(strAdditionalFile)) { TransactionalFileManager.Snapshot(strAdditionalFile); } } TransactionalFileManager.Snapshot(InstallLog.Current.InstallLogPath); try { MergeModule = new InstallLogMergeModule(); if (Fomod.HasInstallScript) { var fscInstallScript = Fomod.GetInstallScript(); switch (fscInstallScript.Type) { case FomodScriptType.CSharp: Fomod.IsActive = RunCustomInstallScript(); break; case FomodScriptType.XMLConfig: Fomod.IsActive = RunXmlInstallScript(); break; } } else { Fomod.IsActive = RunBasicInstallScript("Installing Fomod"); } if (Fomod.IsActive) { InstallLog.Current.Merge(Fomod, MergeModule); Script.CommitActivePlugins(); } } catch (Exception e) { Fomod.IsActive = false; throw e; } if (!Fomod.IsActive) { return(false); } return(true); }
/// <summary> /// This does the moving of files and log alteration. /// </summary> /// <returns> /// <lang langref="true" /> if the script work was completed successfully and needs to /// be committed; <lang langref="false" /> otherwise. /// </returns> /// <exception cref="InvalidOperationException"> /// Thrown if m_strFile or m_lstOrderedMods are /// <lang langref="null" />. /// </exception> /// <seealso cref="ModInstallScript.DoScript" /> protected override bool DoScript() { if ((m_strFile == null) || (m_lstOrderedMods == null)) { throw new InvalidOperationException( "The File and OrderedMods properties must be set before calling Run(); or Run(string, IList<string>) can be used instead."); } TransactionalFileManager.Snapshot(InstallLog.Current.InstallLogPath); var strOldOwner = InstallLog.Current.GetCurrentFileOwnerKey(m_strFile); InstallLog.Current.SetInstallingModsOrder(m_strFile, m_lstOrderedMods); var strNewOwner = InstallLog.Current.GetCurrentFileOwnerKey(m_strFile); if (!strNewOwner.Equals(strOldOwner)) { var strDataPath = Path.Combine(Program.GameMode.PluginsPath, m_strFile); strDataPath = Directory.GetFiles(Path.GetDirectoryName(strDataPath), Path.GetFileName(strDataPath))[0]; var strDirectory = Path.GetDirectoryName(m_strFile); var strBackupPath = Path.Combine(Program.GameMode.OverwriteDirectory, strDirectory); //the old backup file is becoming the new file var strOldBackupFile = strNewOwner + "_" + Path.GetFileName(strDataPath); //the old owner is becoming the new backup file var strNewBackupFile = strOldOwner + "_" + Path.GetFileName(strDataPath); var strNewBackupPath = Path.Combine(strBackupPath, strNewBackupFile); var strOldBackupPath = Path.Combine(strBackupPath, strOldBackupFile); if (!TransactionalFileManager.FileExists(strOldBackupPath)) { m_strFailMessage = "The version of the file for " + InstallLog.Current.GetModName(strNewOwner) + " does not exist. This is likely because files in the data folder have been altered manually."; return(false); } TransactionalFileManager.Copy(strDataPath, strNewBackupPath, true); var strOldBackupFileName = Path.GetFileName(Directory.GetFiles(strBackupPath, strOldBackupFile)[0]); var strCasedFileName = strOldBackupFileName.Substring(strOldBackupFileName.IndexOf('_') + 1); var strNewDataPath = Path.Combine(Path.GetDirectoryName(strDataPath), strCasedFileName); TransactionalFileManager.Delete(strNewDataPath); TransactionalFileManager.Move(strOldBackupPath, strNewDataPath); } return(true); }
/// <summary> /// Writes the file represented by the given file stream to the given path. /// </summary> /// <remarks> /// This method writes the given data as a file at the given path. If the file /// already exists the user is prompted to overwrite the file. /// </remarks> /// <param name="p_strPath">The path where the file is to be created.</param> /// <param name="p_fstData">The data that is to make up the file.</param> /// <returns><c>true</c> if the file was written; <c>false</c> if the user chose /// not to overwrite an existing file.</returns> public virtual bool GenerateDataFile(string p_strPath, FileStream p_fstData) { string strInstallFilePath = p_strPath; if (!Directory.Exists(Path.GetDirectoryName(strInstallFilePath))) { TransactionalFileManager.CreateDirectory(Path.GetDirectoryName(strInstallFilePath)); } else { if (!TestDoOverwrite(p_strPath)) { return(false); } } TransactionalFileManager.WriteFileStream(strInstallFilePath, p_fstData); InstallLog.AddDataFile(Mod, p_strPath); return(true); }
/// <summary> /// Undoes the edit made to the specified game specific value. /// </summary> /// <param name="p_strKey">The key of the edited Game Specific Value.</param> public void UnEditGameSpecificValue(string p_strKey) { ShaderEdit sedShader = new ShaderEdit(p_strKey); SDPArchives sdpManager = new SDPArchives(GameModeInfo, FileUtility); if (!TouchedFiles.Contains(sdpManager.GetPath(sedShader.Package))) { TouchedFiles.Add(sdpManager.GetPath(sedShader.Package)); TransactionalFileManager.Snapshot(sdpManager.GetPath(sedShader.Package)); } string strKey = InstallLog.GetModKey(Mod); string strCurrentOwnerKey = InstallLog.GetCurrentGameSpecificValueEditOwnerKey(p_strKey); //if we didn't edit the shader, then leave it alone if (!strKey.Equals(strCurrentOwnerKey)) { return; } //if we did edit the shader, replace it with the shader we overwrote // if we didn't overwrite the shader, then just delete it byte[] btePreviousData = InstallLog.GetPreviousGameSpecificValue(p_strKey); if (btePreviousData != null) { /*TODO (likely never): I'm not sure if this is the strictly correct way to unedit a shader * the original unedit code was: * * if (m_xelModInstallLogSdpEdits != null) * { * foreach (XmlNode node in m_xelModInstallLogSdpEdits.ChildNodes) * { * //TODO (likely never): Remove this workaround for the release version * if (node.Attributes.GetNamedItem("crc") == null) * { * InstallLog.UndoShaderEdit(int.Parse(node.Attributes.GetNamedItem("package").Value), node.Attributes.GetNamedItem("shader").Value, 0); * } * else * { * InstallLog.UndoShaderEdit(int.Parse(node.Attributes.GetNamedItem("package").Value), node.Attributes.GetNamedItem("shader").Value, * uint.Parse(node.Attributes.GetNamedItem("crc").Value)); * } * } * } * * where InstallLog.UndoShaderEdit was: * * public void UndoShaderEdit(int package, string shader, uint crc) * { * XmlNode node = sdpEditsNode.SelectSingleNode("sdp[@package='" + package + "' and @shader='" + shader + "']"); * if (node == null) return; * byte[] b = new byte[node.InnerText.Length / 2]; * for (int i = 0; i < b.Length; i++) * { * b[i] = byte.Parse("" + node.InnerText[i * 2] + node.InnerText[i * 2 + 1], System.Globalization.NumberStyles.AllowHexSpecifier); * } * if (SDPArchives.RestoreShader(package, shader, b, crc)) sdpEditsNode.RemoveChild(node); * } * * after looking at SDPArchives it is not clear to me why a crc was being used. * if ever it becomes evident that a crc is required, I will have to alter the log to store * a crc and pass it to the RestoreShader method. */ if (!sdpManager.RestoreShader(sedShader.Package, sedShader.ShaderName, btePreviousData, 0)) { throw new Exception("Failed to unedit the shader"); } } //TODO (likely never): how do we delete a shader? Right now, if there was no previous shader the current shader // remains }
/// <summary> /// Writes the file represented by the given byte array to the given path. /// </summary> /// <remarks> /// This method writes the given data as a file at the given path. If the file /// already exists the user is prompted to overwrite the file. /// </remarks> /// <param name="p_strPath">The path where the file is to be created.</param> /// <param name="p_bteData">The data that is to make up the file.</param> /// <returns><c>true</c> if the file was written; <c>false</c> if the user chose /// not to overwrite an existing file.</returns> /// <exception cref="IllegalFilePathException">Thrown if <paramref name="p_strPath"/> is /// not safe.</exception> public virtual bool GenerateDataFile(string p_strPath, byte[] p_bteData) { DataFileUtility.AssertFilePathIsSafe(p_strPath); string[] components = p_strPath.Split(Path.DirectorySeparatorChar); p_strPath = string.Join("" + Path.DirectorySeparatorChar, components.Skip(1).Take(components.Length - 1).ToArray()); string strInstallFilePath = installPath(p_strPath); //string strInstallFilePath = null; //strInstallFilePath = Path.Combine(GameModeInfo.InstallationPath, p_strPath); string installDirPath = Path.GetDirectoryName(strInstallFilePath); FileInfo Info = new FileInfo(strInstallFilePath); if (!Directory.Exists(installDirPath)) { CreateDirectory(installDirPath); } else { if (!TestDoOverwrite(p_strPath)) { return(false); } if (File.Exists(strInstallFilePath)) { if (Info.IsReadOnly == true) { File.SetAttributes(strInstallFilePath, File.GetAttributes(strInstallFilePath) & ~FileAttributes.ReadOnly); } string strInstallDirectory = Path.GetDirectoryName(p_strPath); string strBackupDirectory = Path.Combine(GameModeInfo.OverwriteDirectory, strInstallDirectory); string strOldModKey = InstallLog.GetCurrentFileOwnerKey(p_strPath); if (strOldModKey == null) { InstallLog.LogOriginalDataFile(p_strPath); strOldModKey = InstallLog.OriginalValuesKey; } string strInstallingModKey = InstallLog.GetModKey(Mod); //if this mod has installed this file already we just replace it and don't // need to back it up. if (!strOldModKey.Equals(strInstallingModKey)) { //back up the current version of the file if the current mod // didn't install it if (!Directory.Exists(strBackupDirectory)) { CreateDirectory(strBackupDirectory); } //we get the file name this way in order to preserve the file name's case string strFile = Path.GetFileName(Directory.GetFiles(installDirPath, Path.GetFileName(strInstallFilePath))[0]); strFile = strOldModKey + "_" + strFile; string strBackupFilePath = Path.Combine(strBackupDirectory, strFile); Info = new FileInfo(strBackupFilePath); if ((Info.IsReadOnly == true) && (File.Exists(strBackupFilePath))) { File.SetAttributes(strBackupFilePath, File.GetAttributes(strBackupFilePath) & ~FileAttributes.ReadOnly); } TransactionalFileManager.Copy(strInstallFilePath, strBackupFilePath, true); } TransactionalFileManager.Delete(strInstallFilePath); } } TransactionalFileManager.WriteAllBytes(strInstallFilePath, p_bteData); // Checks whether the file is a gamebryo plugin if (IsPlugin) { if (PluginManager.IsActivatiblePluginFile(strInstallFilePath)) { PluginManager.AddPlugin(strInstallFilePath); } } InstallLog.AddDataFile(Mod, p_strPath); return(IsPlugin); }
/// <summary> /// Performs an in-place upgrade of the <see cref="fomod" />. /// </summary> protected override bool DoScript() { foreach (var strSettingsFile in Program.GameMode.SettingsFiles.Values) { TransactionalFileManager.Snapshot(strSettingsFile); } foreach (var strAdditionalFile in Program.GameMode.AdditionalPaths.Values) { if (File.Exists(strAdditionalFile)) { TransactionalFileManager.Snapshot(strAdditionalFile); } } TransactionalFileManager.Snapshot(InstallLog.Current.InstallLogPath); var booUpgraded = false; try { MergeModule = new InstallLogMergeModule(); if (Fomod.HasInstallScript) { var fscInstallScript = Fomod.GetInstallScript(); switch (fscInstallScript.Type) { case FomodScriptType.CSharp: booUpgraded = RunCustomInstallScript(); break; case FomodScriptType.XMLConfig: booUpgraded = RunXmlInstallScript(); break; } } else { booUpgraded = RunBasicInstallScript(ProgressMessage); } if (booUpgraded) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(ReconcileDifferences)) { m_bwdProgress.OverallMessage = "Finalizing Upgrade"; m_bwdProgress.ItemProgressStep = 1; m_bwdProgress.OverallProgressStep = 1; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { return(false); } } var strOldBaseName = Fomod.BaseName; ((UpgradeFomod)Fomod).SetBaseName(((UpgradeFomod)Fomod).OriginalBaseName); InstallLog.Current.MergeUpgrade(Fomod, strOldBaseName, MergeModule); ((UpgradeFomod)Fomod).SetBaseName(strOldBaseName); Script.CommitActivePlugins(); } } catch (Exception e) { throw e; } m_fomodOriginalMod.IsActive = DetermineFomodActiveStatus(booUpgraded); return(booUpgraded); }
/// <summary> /// Uninstalls the specified file. /// </summary> /// <remarks> /// If the mod we are uninstalling doesn't own the file, then its version is removed /// from the overwrites directory. If the mod we are uninstalling overwrote a file when it /// installed the specified file, then the overwritten file is restored. Otherwise /// the file is deleted. /// </remarks> /// <param name="p_strPath">The path to the file that is to be uninstalled.</param> /// <param name="p_booSecondaryInstallPath">Whether to use the secondary install path.</param> public void UninstallDataFile(string p_strPath, bool p_booSecondaryInstallPath) { string strInstallFilePath = String.Empty; DataFileUtility.AssertFilePathIsSafe(p_strPath); string strUninstallingModKey = InstallLog.GetModKey(Mod); if (p_booSecondaryInstallPath && !(String.IsNullOrEmpty(GameModeInfo.SecondaryInstallationPath))) { strInstallFilePath = Path.Combine(GameModeInfo.SecondaryInstallationPath, p_strPath); } else { strInstallFilePath = Path.Combine(GameModeInfo.InstallationPath ?? "", p_strPath); } string strBackupDirectory = Path.Combine(GameModeInfo.OverwriteDirectory, Path.GetDirectoryName(p_strPath)); string strFile; string strRestoreFromPath = string.Empty; bool booRestoreFile = false; FileInfo fiInfo = null; if (File.Exists(strInstallFilePath)) { string strCurrentOwnerKey = InstallLog.GetCurrentFileOwnerKey(p_strPath); //if we didn't install the file, then leave it alone if (strUninstallingModKey.Equals(strCurrentOwnerKey)) { //if we did install the file, replace it with the file we overwrote // when we installed the file // if we didn't overwrite a file, then just delete the current file fiInfo = new FileInfo(strInstallFilePath); if (fiInfo.IsReadOnly) { m_lstErrorMods.Add(strInstallFilePath); } else { TransactionalFileManager.Delete(strInstallFilePath); } string strPreviousOwnerKey = InstallLog.GetPreviousFileOwnerKey(p_strPath); if (strPreviousOwnerKey != null) { strFile = strPreviousOwnerKey + "_" + Path.GetFileName(p_strPath); strRestoreFromPath = Path.Combine(strBackupDirectory, strFile); if (File.Exists(strRestoreFromPath)) { booRestoreFile = true; } } if (IsPlugin) { if ((PluginManager.IsActivatiblePluginFile(strInstallFilePath)) && !booRestoreFile) { PluginManager.RemovePlugin(strInstallFilePath); } } if (booRestoreFile) { //we get the file name this way in order to preserve the file name's case string strBackupFileName = Path.GetFileName(Directory.GetFiles(Path.GetDirectoryName(strRestoreFromPath), Path.GetFileName(strRestoreFromPath))[0]); strBackupFileName = strBackupFileName.Substring(strBackupFileName.IndexOf('_') + 1); string strNewDataPath = Path.Combine(Path.GetDirectoryName(strInstallFilePath), strBackupFileName); fiInfo = new FileInfo(strRestoreFromPath); try { TransactionalFileManager.Copy(strRestoreFromPath, strNewDataPath, true); } catch { } if (fiInfo.IsReadOnly) { m_lstErrorMods.Add(strInstallFilePath); } else { TransactionalFileManager.Delete(strRestoreFromPath); } } //remove any empty directories from the data folder we may have created TrimEmptyDirectories(Path.GetDirectoryName(strInstallFilePath), GameModeInfo.InstallationPath); } } //remove our version of the file from the backup directory string strOverwritePath = Path.Combine(strBackupDirectory, strUninstallingModKey + "_" + Path.GetFileName(p_strPath)); if (File.Exists(strOverwritePath)) { fiInfo = new FileInfo(strOverwritePath); if (((fiInfo.Attributes | FileAttributes.Hidden) == fiInfo.Attributes) || (fiInfo.IsReadOnly)) { m_lstErrorMods.Add(strInstallFilePath); } else { TransactionalFileManager.Delete(strOverwritePath); } } //remove any empty directories from the overwrite folder we may have created string strStopDirectory = GameModeInfo.OverwriteDirectory; string strFileName = Path.GetFileName(strOverwritePath); TrimEmptyDirectories(strOverwritePath.Replace(strFileName, ""), strStopDirectory); InstallLog.RemoveDataFile(Mod, p_strPath); }
/// <summary> /// Writes the file represented by the given byte array to the given path. /// </summary> /// <remarks> /// This method writes the given data as a file at the given path. If the file /// already exists the user is prompted to overwrite the file. /// </remarks> /// <param name="p_strPath">The path where the file is to be created.</param> /// <param name="p_bteData">The data that is to make up the file.</param> /// <param name="p_booSecondaryInstallPath">Whether to use the secondary install path.</param> /// <returns><c>true</c> if the file was written; <c>false</c> if the user chose /// not to overwrite an existing file.</returns> /// <exception cref="IllegalFilePathException">Thrown if <paramref name="p_strPath"/> is /// not safe.</exception> public virtual bool GenerateDataFile(string p_strPath, byte[] p_bteData, bool p_booSecondaryInstallPath) { DataFileUtility.AssertFilePathIsSafe(p_strPath); string strInstallFilePath = String.Empty; if (p_booSecondaryInstallPath && !(String.IsNullOrEmpty(GameModeInfo.SecondaryInstallationPath))) { strInstallFilePath = Path.Combine(GameModeInfo.SecondaryInstallationPath, p_strPath); } else { strInstallFilePath = Path.Combine(GameModeInfo.InstallationPath, p_strPath); } FileInfo Info = new FileInfo(strInstallFilePath); if (!Directory.Exists(Path.GetDirectoryName(strInstallFilePath))) { TransactionalFileManager.CreateDirectory(Path.GetDirectoryName(strInstallFilePath)); } else { if (!TestDoOverwrite(p_strPath)) { return(false); } if (File.Exists(strInstallFilePath)) { if (Info.IsReadOnly == true) { File.SetAttributes(strInstallFilePath, File.GetAttributes(strInstallFilePath) & ~FileAttributes.ReadOnly); } string strInstallDirectory = Path.GetDirectoryName(p_strPath); string strBackupDirectory = Path.Combine(GameModeInfo.OverwriteDirectory, strInstallDirectory); string strOldModKey = InstallLog.GetCurrentFileOwnerKey(p_strPath); if (strOldModKey == null) { InstallLog.LogOriginalDataFile(p_strPath); strOldModKey = InstallLog.OriginalValuesKey; } string strInstallingModKey = InstallLog.GetModKey(Mod); //if this mod has installed this file already we just replace it and don't // need to back it up. if (!strOldModKey.Equals(strInstallingModKey)) { //back up the current version of the file if the current mod // didn't install it if (!Directory.Exists(strBackupDirectory)) { TransactionalFileManager.CreateDirectory(strBackupDirectory); } //we get the file name this way in order to preserve the file name's case string strFile = Path.GetFileName(Directory.GetFiles(Path.GetDirectoryName(strInstallFilePath), Path.GetFileName(strInstallFilePath))[0]); strFile = strOldModKey + "_" + strFile; string strBackupFilePath = Path.Combine(strBackupDirectory, strFile); Info = new FileInfo(strBackupFilePath); if ((Info.IsReadOnly == true) && (File.Exists(strBackupFilePath))) { File.SetAttributes(strBackupFilePath, File.GetAttributes(strBackupFilePath) & ~FileAttributes.ReadOnly); } TransactionalFileManager.Copy(strInstallFilePath, strBackupFilePath, true); } TransactionalFileManager.Delete(strInstallFilePath); } } TransactionalFileManager.WriteAllBytes(strInstallFilePath, p_bteData); // Checks whether the file is a gamebryo plugin if (IsPlugin) { if (PluginManager.IsActivatiblePluginFile(strInstallFilePath)) { if (!PluginManager.CanActivatePlugins()) { string strTooManyPlugins = String.Format("The requested change to the active plugins list would result in over {0} plugins being active.", PluginManager.MaxAllowedActivePluginsCount); strTooManyPlugins += Environment.NewLine + String.Format("The current game doesn't support more than {0} active plugins, you need to disable at least one plugin to continue.", PluginManager.MaxAllowedActivePluginsCount); strTooManyPlugins += Environment.NewLine + Environment.NewLine + String.Format("NOTE: This is a game engine limitation.") + Environment.NewLine; throw new Exception(strTooManyPlugins); } PluginManager.AddPlugin(strInstallFilePath); } } InstallLog.AddDataFile(Mod, p_strPath); return(IsPlugin); }
/// <summary> /// Installs the specified file from the Mod to the file system. /// </summary> /// <param name="p_strModFilePath">The path of the file in the Mod to install.</param> /// <param name="p_strInstallPath">The path on the file system where the file is to be installed.</param> /// <returns><c>true</c> if the file was written; <c>false</c> if the user chose /// not to overwrite an existing file.</returns> public bool InstallFileFromMod(string p_strModFilePath, string p_strInstallPath, bool p_booSecondaryInstallPath) { Console.WriteLine("install " + p_strModFilePath + " to " + p_strInstallPath); string destinationPath = installPath(p_strInstallPath, p_booSecondaryInstallPath); if (!Directory.Exists(Path.GetDirectoryName(destinationPath))) { TransactionalFileManager.CreateDirectory(Path.GetDirectoryName(destinationPath)); } else { if (!TestDoOverwrite(p_strInstallPath)) { return(false); } if (File.Exists(destinationPath)) { FileInfo Info = new FileInfo(destinationPath); if (Info.IsReadOnly == true) { File.SetAttributes(destinationPath, File.GetAttributes(destinationPath) & ~FileAttributes.ReadOnly); } string strInstallDirectory = Path.GetDirectoryName(p_strInstallPath); string strBackupDirectory = Path.Combine(GameModeInfo.OverwriteDirectory, strInstallDirectory); string strOldModKey = InstallLog.GetCurrentFileOwnerKey(p_strInstallPath); if (strOldModKey == null) { InstallLog.LogOriginalDataFile(p_strInstallPath); strOldModKey = InstallLog.OriginalValuesKey; } string strInstallingModKey = InstallLog.GetModKey(Mod); //if this mod has installed this file already we just replace it and don't // need to back it up. if (!strOldModKey.Equals(strInstallingModKey)) { //back up the current version of the file if the current mod // didn't install it if (!Directory.Exists(strBackupDirectory)) { TransactionalFileManager.CreateDirectory(strBackupDirectory); } //we get the file name this way in order to preserve the file name's case string strFile = Path.GetFileName(Directory.GetFiles(Path.GetDirectoryName(destinationPath), Path.GetFileName(destinationPath))[0]); strFile = strOldModKey + "_" + strFile; string strBackupFilePath = Path.Combine(strBackupDirectory, strFile); Info = new FileInfo(strBackupFilePath); if ((Info.IsReadOnly == true) && (File.Exists(strBackupFilePath))) { File.SetAttributes(strBackupFilePath, File.GetAttributes(strBackupFilePath) & ~FileAttributes.ReadOnly); } TransactionalFileManager.Copy(destinationPath, strBackupFilePath, true); } TransactionalFileManager.Delete(destinationPath); } } try { using (FileStream stream = File.Create(destinationPath)) { Mod.ExtractFileTo(p_strModFilePath, stream); } } catch (FileNotFoundException e) { MessageBox.Show("File " + p_strModFilePath + " couldn't be extracted.\n" + "This probably means the mod is broken though you may still get partial functionality.\n" + "Please inform the mod author.\n" + "Detailed Error: " + e.Message, "File not found in FOMod", MessageBoxButtons.OK, MessageBoxIcon.Error); File.Delete(destinationPath); throw; } catch (Exception ex) { MessageBox.Show("Exception: " + ex.ToString()); throw; } // Checks whether the file is a gamebryo plugin if (IsPlugin) { if (PluginManager.IsActivatiblePluginFile(destinationPath)) { PluginManager.AddPlugin(destinationPath); } } InstallLog.AddDataFile(Mod, p_strInstallPath); return(IsPlugin); }