/// <seealso cref="Parser.GetHeaderInfo()" /> public override HeaderInfo GetHeaderInfo() { var xndTitle = XmlConfig.SelectSingleNode("/config/moduleName"); var strTitle = xndTitle.InnerText; var clrColour = Color.FromArgb( (Int32)(UInt32.Parse(xndTitle.Attributes["colour"].Value, NumberStyles.HexNumber, null) | 0xff000000)); var tpsPosition = (TextPosition)Enum.Parse(typeof(TextPosition), xndTitle.Attributes["position"].Value); var xndImage = XmlConfig.SelectSingleNode("/config/moduleImage"); if (xndImage != null) { var strImagePath = xndImage.Attributes["path"].Value; var imgImage = String.IsNullOrEmpty(strImagePath) ? Fomod.GetScreenshotImage() : new Bitmap(Fomod.GetImage(strImagePath)); var booShowImage = Boolean.Parse(xndImage.Attributes["showImage"].Value) && (imgImage != null); var booShowFade = Boolean.Parse(xndImage.Attributes["showFade"].Value); var intHeight = Int32.Parse(xndImage.Attributes["height"].Value); if ((intHeight == -1) && booShowImage) { intHeight = 75; } return(new HeaderInfo(strTitle, clrColour, tpsPosition, imgImage, booShowImage, booShowFade, intHeight)); } var imgScreenshot = Fomod.GetScreenshotImage(); return(new HeaderInfo(strTitle, clrColour, tpsPosition, imgScreenshot, imgScreenshot != null, true, (imgScreenshot != null) ? 75 : -1)); }
/// <summary> /// Performs a basic install of the mod. /// </summary> /// <remarks> /// A basic install installs all of the file in the mod to the Data directory /// or activates all esp and esm files. /// </remarks> public void PerformBasicInstall() { var chrDirectorySeperators = new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }; var lstFiles = Fomod.GetFileList(); if (ProgressDialog != null) { ProgressDialog.OverallProgressMaximum = lstFiles.Count; } foreach (var strFile in lstFiles) { if ((ProgressDialog != null) && ProgressDialog.Cancelled()) { return; } Script.InstallFileFromFomod(strFile); if (Program.GameMode.IsPluginFile(strFile) && strFile.IndexOfAny(chrDirectorySeperators) == -1) { Script.SetPluginActivation(strFile, true); } if (ProgressDialog != null) { ProgressDialog.StepOverallProgress(); } } }
/// <seealso cref="Parser.GetHeaderInfo()" /> public override HeaderInfo GetHeaderInfo() { var imgScreenshot = Fomod.GetScreenshotImage(); return(new HeaderInfo(XmlConfig.SelectSingleNode("/config/moduleName").InnerText, Color.FromKnownColor(KnownColor.ControlText), TextPosition.Left, imgScreenshot, imgScreenshot != null, true, (imgScreenshot != null) ? 75 : -1)); }
/// <summary> /// Reads a plugin's information from the configuration file. /// </summary> /// <param name="p_xndPlugin">The configuration file node corresponding to the plugin to read.</param> /// <returns>The plugin information.</returns> protected override PluginInfo parsePlugin(XmlNode p_xndPlugin) { var strName = p_xndPlugin.Attributes["name"].InnerText; var strDesc = p_xndPlugin.SelectSingleNode("description").InnerText.Trim(); IPluginType iptType; var xndTypeDescriptor = p_xndPlugin.SelectSingleNode("typeDescriptor").FirstChild; switch (xndTypeDescriptor.Name) { case "type": iptType = new StaticPluginType( (PluginType)Enum.Parse(typeof(PluginType), xndTypeDescriptor.Attributes["name"].InnerText)); break; case "dependencyType": var ptpDefaultType = (PluginType) Enum.Parse(typeof(PluginType), xndTypeDescriptor.SelectSingleNode("defaultType").Attributes["name"].InnerText); iptType = new DependencyPluginType(ptpDefaultType); var dptDependentType = (DependencyPluginType)iptType; var xnlPatterns = xndTypeDescriptor.SelectNodes("patterns/*"); foreach (XmlNode xndPattern in xnlPatterns) { var ptpType = (PluginType) Enum.Parse(typeof(PluginType), xndPattern.SelectSingleNode("type").Attributes["name"].InnerText); var cdpDependency = loadDependency(xndPattern.SelectSingleNode("dependencies")); dptDependentType.AddPattern(ptpType, cdpDependency); } break; default: throw new ParserException("Invalid plaug type descriptor node: " + xndTypeDescriptor.Name + ". At this point the config file has been validated against the schema, so there's something wrong with the parser."); } var xndImage = p_xndPlugin.SelectSingleNode("image"); Image imgImage = null; if (xndImage != null) { var strImageFilePath = xndImage.Attributes["path"].InnerText; imgImage = Fomod.GetImage(strImageFilePath); } var pifPlugin = new PluginInfo(strName, strDesc, imgImage, iptType); var xnlPluginFiles = p_xndPlugin.SelectNodes("files/*"); pifPlugin.Files.AddRange(readFileInfo(xnlPluginFiles)); var xnlPluginFlags = p_xndPlugin.SelectNodes("conditionFlags/*"); pifPlugin.Flags.AddRange(readFlagInfo(xnlPluginFlags)); return(pifPlugin); }
/// <summary> /// Runs the custom uninstall script included in the fomod. /// </summary> /// <returns> /// <lang langref="true" /> if the uninstallation was successful; /// <lang langref="false" /> otherwise. /// </returns> /// <exception cref="FileNotFoundException"> /// Thrown if the uninstall script /// cannot be found. /// </exception> protected bool RunCustomUninstallScript() { var strScript = Fomod.GetUninstallScript(); if (strScript == null) { throw new FileNotFoundException("No uninstall script found, even though fomod claimed to have one."); } return(false); }
/// <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); }
public bool InstallFile(string fnFrom, string fnTo = "") { var ret = false; string strDataPath; /* * There were two differences between InstallFileFromFomod and CopyDataFile * 1. IFFF checked permissions, CDF did not. * 2. IFFF used the same src and dst filenames, CDF used different names. */ PermissionsManager.CurrentPermissions.Assert(); if (fnTo == "") { fnTo = fnFrom; } FileManagement.AssertFilePathIsSafe(fnTo); #region refactor me #region original code // byte[] bteFomodFile = Fomod.GetFile(fnFrom); // ret = GenerateDataFile(fnTo, bteFomodFile); #endregion #region newcode /* * New code * 1. Extract the file from the archive to the temp file * 2. Copy the temp file to the destination * 3. Delete the temp file */ var tmpFN = Fomod.ExtractToTemp(fnFrom); if (GenerateDataFilePrep(fnTo, out strDataPath)) { Installer.TransactionalFileManager.Copy(tmpFN, strDataPath, true); Installer.MergeModule.AddFile(fnTo); ret = true; } #endregion #endregion return(ret); }
/// <summary> /// Reads a plugin's information from the configuration file. /// </summary> /// <param name="p_xndPlugin">The configuration file node corresponding to the plugin to read.</param> /// <returns>The plugin information.</returns> protected virtual PluginInfo parsePlugin(XmlNode p_xndPlugin) { var strName = p_xndPlugin.Attributes["name"].InnerText; var strDesc = p_xndPlugin.SelectSingleNode("description").InnerText.Trim(); IPluginType iptType = null; var xndTypeDescriptor = p_xndPlugin.SelectSingleNode("typeDescriptor").FirstChild; switch (xndTypeDescriptor.Name) { case "type": iptType = new StaticPluginType( (PluginType)Enum.Parse(typeof(PluginType), xndTypeDescriptor.Attributes["name"].InnerText)); break; case "dependancyType": var ptpDefaultType = (PluginType) Enum.Parse(typeof(PluginType), xndTypeDescriptor.SelectSingleNode("defaultType").Attributes["name"].InnerText); iptType = new DependencyPluginType(ptpDefaultType); var dptDependentType = (DependencyPluginType)iptType; var xnlPatterns = xndTypeDescriptor.SelectNodes("patterns/*"); foreach (XmlNode xndPattern in xnlPatterns) { var ptpType = (PluginType) Enum.Parse(typeof(PluginType), xndPattern.SelectSingleNode("type").Attributes["name"].InnerText); var cdpDependency = loadDependency(xndPattern.SelectSingleNode("dependancies")); dptDependentType.AddPattern(ptpType, cdpDependency); } break; } var xndImage = p_xndPlugin.SelectSingleNode("image"); Image imgImage = null; if (xndImage != null) { var strImageFilePath = xndImage.Attributes["path"].InnerText; imgImage = Fomod.GetImage(strImageFilePath); } var pifPlugin = new PluginInfo(strName, strDesc, imgImage, iptType); var xnlPluginFiles = p_xndPlugin.SelectNodes("files/*"); pifPlugin.Files.AddRange(readFileInfo(xnlPluginFiles)); return(pifPlugin); }
/// <summary> /// Displays a selection form to the user. /// </summary> /// <remarks> /// The items, previews, and descriptions are repectively ordered. In other words, /// the i-th item in <paramref name="p_strItems" /> uses the i-th preview in /// <paramref name="p_strPreviews" /> and the i-th description in <paramref name="p_strDescriptions" />. /// Similarly, the idices return as results correspond to the indices of the items in /// <paramref name="p_strItems" />. /// </remarks> /// <param name="p_strItems">The items from which to select.</param> /// <param name="p_strPreviews">The preview image file names for the items.</param> /// <param name="p_strDescriptions">The descriptions of the items.</param> /// <param name="p_strTitle">The title of the selection form.</param> /// <param name="p_booSelectMany">Whether more than one item can be selected.</param> /// <returns>The indices of the selected items.</returns> public int[] Select(string[] p_strItems, string[] p_strPreviews, string[] p_strDescriptions, string p_strTitle, bool p_booSelectMany) { PermissionsManager.CurrentPermissions.Assert(); Image[] imgPreviews = null; if (p_strPreviews != null) { imgPreviews = new Image[p_strPreviews.Length]; for (var i = 0; i < p_strPreviews.Length; i++) { if (p_strPreviews[i] == null) { continue; } try { imgPreviews[i] = Fomod.GetImage(p_strPreviews[i]); } catch (Exception e) { if (!((e is FileNotFoundException) || (e is DecompressionException))) { throw e; } } } //for now I don't think the user needs to be able to detect this. // i don't think it is severe enough to be an exception, as it may be // intentional, and if it is a bug it should be readily apparent // during testing. /*if (intMissingImages > 0) * { * m_strLastError = "There were " + intMissingImages + " filenames specified for preview images which could not be loaded"; * }*/ } var sfmSelectForm = new SelectForm(p_strItems, p_booSelectMany, imgPreviews, p_strDescriptions); sfmSelectForm.Text = p_strTitle; sfmSelectForm.ShowDialog(); var intResults = new int[sfmSelectForm.SelectedIndex.Length]; for (var i = 0; i < sfmSelectForm.SelectedIndex.Length; i++) { intResults[i] = sfmSelectForm.SelectedIndex[i]; } return(intResults); }
/// <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> /// Puts the FOMod into read-only mode. /// </summary> /// <remarks> /// This method is called by a <see cref="BackgroundWorkerProgressDialog" />. /// </remarks> private void BeginFOModReadOnlyTransaction() { Fomod.BeginReadOnlyTransaction(); }
/// <summary> /// Runs the install script. /// </summary> /// <remarks> /// This contains the boilerplate code that needs to be done for all install-type /// scripts. Implementers must override the <see cref="DoScript()" /> method to /// implement their script-specific functionality. /// </remarks> /// <param name="p_booSuppressSuccessMessage"> /// Indicates whether to /// supress the success message. This is useful for batch installs. /// </param> /// <seealso cref="DoScript()" /> protected bool Run(bool p_booSuppressSuccessMessage, bool p_booSetFOModReadOnly) { var booSuccess = false; if (CheckAlreadyDone()) { booSuccess = true; } if (!booSuccess) { try { //the install process modifies INI and config files. // if multiple sources (i.e., installs) try to modify // these files simultaneously the outcome is not well known // (e.g., one install changes SETTING1 in a config file to valueA // while simultaneously another install changes SETTING1 in the // file to value2 - after each install commits its changes it is // not clear what the value of SETTING1 will be). // as a result, we only allow one mod to be installed at a time, // hence the lock. lock (objInstallLock) { using (var tsTransaction = new TransactionScope()) { m_tfmFileManager = new TxFileManager(); using (Script = CreateInstallScript()) { var booCancelled = false; if (p_booSetFOModReadOnly && (Fomod != null)) { if (Fomod.ReadOnlyInitStepCount > 1) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(BeginFOModReadOnlyTransaction)) { m_bwdProgress.OverallMessage = "Preparing FOMod..."; m_bwdProgress.ShowItemProgress = false; m_bwdProgress.OverallProgressMaximum = Fomod.ReadOnlyInitStepCount; m_bwdProgress.OverallProgressStep = 1; try { Fomod.ReadOnlyInitStepStarted += Fomod_ReadOnlyInitStepStarted; Fomod.ReadOnlyInitStepFinished += Fomod_ReadOnlyInitStepFinished; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { booCancelled = true; } } finally { Fomod.ReadOnlyInitStepStarted -= Fomod_ReadOnlyInitStepStarted; Fomod.ReadOnlyInitStepFinished -= Fomod_ReadOnlyInitStepFinished; } } } else { Fomod.BeginReadOnlyTransaction(); } } if (!booCancelled) { booSuccess = DoScript(); if (booSuccess) { tsTransaction.Complete(); } } } } } } catch (Exception e) { var stbError = new StringBuilder(e.Message); if (e is FileNotFoundException) { stbError.Append(" (" + ((FileNotFoundException)e).FileName + ")"); } if (e is IllegalFilePathException) { stbError.Append(" (" + ((IllegalFilePathException)e).Path + ")"); } if (e.InnerException != null) { stbError.AppendLine().AppendLine(e.InnerException.Message); } if (e is RollbackException) { foreach (var erm in ((RollbackException)e).ExceptedResourceManagers) { stbError.AppendLine(erm.ResourceManager.ToString()); stbError.AppendLine(erm.Exception.Message); if (erm.Exception.InnerException != null) { stbError.AppendLine(erm.Exception.InnerException.Message); } } } var strMessage = String.Format(ExceptionMessage, stbError); MessageBox.Show(strMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } finally { m_tfmFileManager = null; m_ilmModInstallLog = null; if (Fomod != null) { Fomod.EndReadOnlyTransaction(); } } } if (booSuccess && !p_booSuppressSuccessMessage && !String.IsNullOrEmpty(SuccessMessage)) { MessageBox.Show(SuccessMessage, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (!booSuccess && !String.IsNullOrEmpty(FailMessage)) { MessageBox.Show(FailMessage, "Failure", MessageBoxButtons.OK, MessageBoxIcon.Error); } return(booSuccess); }
/// <summary> /// Runs the custom install script included in the fomod. /// </summary> /// <returns> /// <lang langref="true" /> if the installation was successful; /// <lang langref="false" /> otherwise. /// </returns> protected bool RunCustomInstallScript() { var strScript = Fomod.GetInstallScript().Text; return(ScriptCompiler.Execute(strScript, this)); }