Пример #1
0
        /// <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));
        }
Пример #2
0
        /// <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));
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
        /// <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);
        }
Пример #11
0
        /// <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
        }
Пример #12
0
        /// <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);
        }
Пример #13
0
        /// <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);
        }
Пример #14
0
        /// <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);
        }
Пример #15
0
        /// <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);
        }
Пример #16
0
        /// <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);
        }