Beispiel #1
0
 /// <summary>
 ///   A simple constructor that initializes the object.
 /// </summary>
 /// <param name="p_fomodMod">The <see cref="fomod" /> against which to run the script.</param>
 public Fallout3ModInstallScript(fomod p_fomodMod, ModInstallerBase p_mibInstaller)
     : base(p_fomodMod, p_mibInstaller)
 {
     //m_misScript = new ModInstallScript(p_fomodMod);
     BsaManager     = new BsaManager();
     TextureManager = new TextureManager();
 }
Beispiel #2
0
        /// <summary>
        /// Scans the mods folder for fomods that have versions that differ from their versions in the install log.
        /// </summary>
        /// <remarks>
        /// If fomods with versions that differ from those in the install log are found, the use is asked whether
        /// to replace or upgrade the fomod. Replacing the fomod merely changes the version in the install log,
        /// but makes no system changes. Upgrading the fomod performs an in-place upgrade.
        /// </remarks>
        public void Scan()
        {
            IList<FomodInfo> lstMods = InstallLog.Current.GetVersionedModList();
            fomod fomodMod = null;
            List<fomod> lstModsToUpgrade = new List<fomod>();
            List<fomod> lstModsToReplace = new List<fomod>();
            foreach (FomodInfo fifMod in lstMods)
            {
            #if TRACE
                Trace.WriteLine("Scanning " + Path.Combine(Program.GameMode.ModDirectory, fifMod.BaseName + ".fomod"));
            #endif
                fomodMod = new fomod(Path.Combine(Program.GameMode.ModDirectory, fifMod.BaseName + ".fomod"));
                if (!fomodMod.HumanReadableVersion.Equals(fifMod.Version))
                {
                    switch (MessageBox.Show(String.Format(m_strUpgradeMessage, fomodMod.ModName, fifMod.Version, fomodMod.HumanReadableVersion), "Upgrade", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                    {
                        case DialogResult.Yes:
                            lstModsToUpgrade.Add(fomodMod);
                            break;
                        case DialogResult.No:
                            lstModsToReplace.Add(fomodMod);
                            break;
                    }
                }
            }

            Replace(lstModsToReplace);
            Upgrade(lstModsToUpgrade);
        }
Beispiel #3
0
 /// <summary>
 ///   The factory method that returns the appropriate parser for the given configuration file.
 /// </summary>
 /// <param name="p_xmlConfig">The configuration file for which to return a parser.</param>
 /// <param name="p_fomodMod">The mod whose configuration file is being parsed.</param>
 /// <param name="p_dsmSate">The state of the install.</param>
 /// <returns>The appropriate parser for the given configuration file.</returns>
 /// <exception cref="ParserException">Thrown if no parser is found for the given configuration file.</exception>
 public static Parser GetParser(XmlDocument p_xmlConfig, fomod p_fomodMod, DependencyStateManager p_dsmSate)
 {
   var strConfigVersion = "1.0";
   var strSchemaName =
     p_xmlConfig.SelectSingleNode("config").Attributes["xsi:noNamespaceSchemaLocation"].InnerText.ToLowerInvariant();
   var intStartPos = strSchemaName.LastIndexOf("modconfig") + 9;
   if (intStartPos > 8)
   {
     var intLength = strSchemaName.Length - intStartPos - 4;
     if (intLength > 0)
     {
       strConfigVersion = strSchemaName.Substring(intStartPos, intLength);
     }
   }
   var pexParserExtension = Program.GameMode.GetParserExtension(strConfigVersion);
   switch (strConfigVersion)
   {
     case "1.0":
       return new Parser10(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension);
     case "2.0":
       return new Parser20(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension);
     case "3.0":
       return new Parser30(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension);
     case "4.0":
       return new Parser40(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension);
     case "5.0":
       return new Parser50(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension);
   }
   throw new ParserException("Unrecognized Module Configuration version (" + strConfigVersion +
                             "). Perhaps a newer version of FOMM is required.");
 }
Beispiel #4
0
        /// <summary>
        ///   Scans the mods folder for fomods that have versions that differ from their versions in the install log.
        /// </summary>
        /// <remarks>
        ///   If fomods with versions that differ from those in the install log are found, the use is asked whether
        ///   to replace or upgrade the fomod. Replacing the fomod merely changes the version in the install log,
        ///   but makes no system changes. Upgrading the fomod performs an in-place upgrade.
        /// </remarks>
        public void Scan()
        {
            var lstMods          = InstallLog.Current.GetVersionedModList();
            var lstModsToUpgrade = new List <fomod>();
            var lstModsToReplace = new List <fomod>();

            foreach (var fifMod in lstMods)
            {
                var fomodMod = new fomod(Path.Combine(Program.GameMode.ModDirectory, fifMod.BaseName + ".fomod"));
                if (!fomodMod.HumanReadableVersion.Equals(fifMod.Version))
                {
                    switch (
                        MessageBox.Show(
                            String.Format(m_strUpgradeMessage, fomodMod.ModName, fifMod.Version, fomodMod.HumanReadableVersion),
                            "Upgrade", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                    {
                    case DialogResult.Yes:
                        lstModsToUpgrade.Add(fomodMod);
                        break;

                    case DialogResult.No:
                        lstModsToReplace.Add(fomodMod);
                        break;
                    }
                }
            }

            Replace(lstModsToReplace);
            Upgrade(lstModsToUpgrade);
        }
Beispiel #5
0
 /// <summary>
 /// A simple constructor that initializes teh object with the given values.
 /// </summary>
 /// <param name="p_xmlConfig">The modules configuration file.</param>
 /// <param name="p_fomodMod">The mod whose configuration file we are parsing.</param>
 /// <param name="p_dsmSate">The state of the install.</param>
 /// <param name="p_pexParserExtension">The parser extension that provides game-specific config file parsing.</param>
 public Parser(XmlDocument p_xmlConfig, fomod p_fomodMod, DependencyStateManager p_dsmSate, ParserExtension p_pexParserExtension)
 {
     m_pexParserExtension = p_pexParserExtension;
     m_xmlConfig = p_xmlConfig;
     m_fomodMod = p_fomodMod;
     m_dsmSate = p_dsmSate;
     validateModuleConfig();
 }
Beispiel #6
0
 /// <summary>
 ///   A simple constructor that initializes teh object with the given values.
 /// </summary>
 /// <param name="p_xmlConfig">The modules configuration file.</param>
 /// <param name="p_fomodMod">The mod whose configuration file we are parsing.</param>
 /// <param name="p_dsmSate">The state of the install.</param>
 /// <param name="p_pexParserExtension">The parser extension that provides game-specific config file parsing.</param>
 public Parser(XmlDocument p_xmlConfig, fomod p_fomodMod, DependencyStateManager p_dsmSate,
               ParserExtension p_pexParserExtension)
 {
     m_pexParserExtension = p_pexParserExtension;
     XmlConfig            = p_xmlConfig;
     Fomod        = p_fomodMod;
     StateManager = p_dsmSate;
     validateModuleConfig();
 }
Beispiel #7
0
        /// <summary>
        ///   Called when the conflict detector has found a conflict.
        /// </summary>
        /// <remarks>
        ///   This adds a message to the appropriate plugin's info box, and changes the plugin's
        ///   node's background colour as appropriate.
        /// </remarks>
        /// <param name="sender">The object that trigger the event.</param>
        /// <param name="e">A <see cref="ConflictDetectedEventArgs" /> describing the event arguments.</param>
        private void cdrDetector_ConflictDetected(object sender, ConflictDetectedEventArgs e)
        {
            var stbMessage           = new StringBuilder();
            var lstBackgroundColours = new List <Color>
            {
                Color.LightSkyBlue,
                Color.Yellow,
                Color.Red
            };
            var intColourIndex = 0;

            switch (e.ConflictInfo.Severity)
            {
            case CriticalRecordInfo.ConflictSeverity.Conflict:
                stbMessage.Append(@"\b \cf1 CONFLICT\cf0 :\b0  ");
                intColourIndex = 2;
                break;

            case CriticalRecordInfo.ConflictSeverity.Warning:
                stbMessage.Append(@"\b \cf2 WARNING\cf0 :\b0  ");
                intColourIndex = 1;
                break;

            case CriticalRecordInfo.ConflictSeverity.Info:
                stbMessage.Append(@"\b \cf3 INFO\cf0 :\b0  ");
                intColourIndex = 0;
                break;
            }
            var clrHighlight = lstBackgroundColours[intColourIndex];

            if (m_pfpFormatProvider.HasFormat(e.ConflictedPlugin.Name))
            {
                var pftFormat = m_pfpFormatProvider.GetFormat(e.ConflictedPlugin.Name);
                if (pftFormat.Highlight.HasValue && (lstBackgroundColours.IndexOf(pftFormat.Highlight.Value) > intColourIndex))
                {
                    clrHighlight = pftFormat.Highlight.Value;
                }
            }

            if (InstallLog.Current.GetCurrentFileOwnerName(e.ConflictingPlugin.Name) == null)
            {
                stbMessage.AppendFormat(
                    "Form Id \\b {0:x8}\\b0  is overridden by \\b {1}\\b0 .\\par \\pard\\li720\\sl240\\slmult1 {2}\\par \\pard\\sl240\\slmult1 ",
                    e.FormId, e.ConflictingPlugin.Name, e.ConflictInfo.Reason);
            }
            else
            {
                var fomodMod =
                    new fomod(Path.Combine(Program.GameMode.ModDirectory,
                                           InstallLog.Current.GetCurrentFileOwnerName(e.ConflictingPlugin.Name) + ".fomod"));
                stbMessage.AppendFormat(
                    "Form Id \\b {0:x8}\\b0  is overridden by \\b {1}\\b0  in \\b {2}\\b0 .\\par \\pard\\li720\\sl240\\slmult1 {3}\\par \\pard\\sl240\\slmult1 ",
                    e.FormId, e.ConflictingPlugin.Name, fomodMod.ModName, e.ConflictInfo.Reason);
            }
            m_pfpFormatProvider.AddFormat(e.ConflictedPlugin.Name, clrHighlight, stbMessage.ToString());
        }
Beispiel #8
0
        /// <summary>
        ///   Upgrades the Install Log to the current version from version 0.1.0.0.
        /// </summary>
        /// <remarks>
        ///   This method is called by a background worker to perform the actual upgrade.
        /// </remarks>
        protected override void DoUpgrade()
        {
            var xmlInstallLog = new XmlDocument();

            xmlInstallLog.Load(InstallLog.Current.InstallLogPath);

            var xndRoot = xmlInstallLog.SelectSingleNode("installLog");

            if (xndRoot == null)
            {
                return;
            }
            var lstMods     = InstallLog.Current.GetModList();
            var xndSdpEdits = xndRoot.SelectSingleNode("sdpEdits");

            if (xndSdpEdits != null)
            {
                ProgressWorker.OverallProgressStep    = 1;
                ProgressWorker.OverallProgressMaximum = lstMods.Count + xndSdpEdits.ChildNodes.Count;
                ProgressWorker.ShowItemProgress       = false;

                //remove the sdp edit node...
                xndSdpEdits.ParentNode.RemoveChild(xndSdpEdits);
                //...and replace it with the game-specific edits node
                var xndGameSpecificsValueEdits = xndRoot.AppendChild(xmlInstallLog.CreateElement("gameSpecificEdits"));
                foreach (XmlNode xndSdpEdit in xndSdpEdits.ChildNodes)
                {
                    ProgressWorker.StepOverallProgress();
                    var xndGameSpecificsValueEdit = xndGameSpecificsValueEdits.AppendChild(xmlInstallLog.CreateElement("edit"));
                    var strValueKey = $"sdp:{xndGameSpecificsValueEdits.Attributes["package"].Value}/{xndGameSpecificsValueEdits.Attributes["shader"].Value}";
                    xndGameSpecificsValueEdit.Attributes.Append(xmlInstallLog.CreateAttribute("key")).Value = strValueKey;
                    xndGameSpecificsValueEdit.AppendChild(xndSdpEdit.FirstChild.Clone());
                }
            }

            xmlInstallLog.Save(InstallLog.Current.InstallLogPath);

            //now update the mod info
            foreach (var strMod in lstMods)
            {
                ProgressWorker.StepOverallProgress();
                if (strMod.Equals(InstallLog.ORIGINAL_VALUES) || strMod.Equals(InstallLog.FOMM))
                {
                    continue;
                }
                var strModPath = Path.Combine(Program.GameMode.ModDirectory, strMod + ".fomod");
                var fomodMod   = new fomod(strModPath);
                InstallLog.Current.UpdateMod(fomodMod);
            }

            InstallLog.Current.SetInstallLogVersion(InstallLog.CURRENT_VERSION);
            InstallLog.Current.Save();
        }
Beispiel #9
0
        /// <summary>
        ///   The factory method that returns the appropriate parser for the given configuration file.
        /// </summary>
        /// <param name="p_xmlConfig">The configuration file for which to return a parser.</param>
        /// <param name="p_fomodMod">The mod whose configuration file is being parsed.</param>
        /// <param name="p_dsmSate">The state of the install.</param>
        /// <returns>The appropriate parser for the given configuration file.</returns>
        /// <exception cref="ParserException">Thrown if no parser is found for the given configuration file.</exception>
        public static Parser GetParser(XmlDocument p_xmlConfig, fomod p_fomodMod, DependencyStateManager p_dsmSate)
        {
            var strConfigVersion = "1.0";
            var strSchemaName    =
                p_xmlConfig.SelectSingleNode("config").Attributes["xsi:noNamespaceSchemaLocation"].InnerText.ToLowerInvariant();
            var intStartPos = strSchemaName.LastIndexOf("modconfig") + 9;

            if (intStartPos > 8)
            {
                var intLength = strSchemaName.Length - intStartPos - 4;
                if (intLength > 0)
                {
                    strConfigVersion = strSchemaName.Substring(intStartPos, intLength);
                }
            }
            var pexParserExtension = Program.GameMode.GetParserExtension(strConfigVersion);

            switch (strConfigVersion)
            {
            case "1.0":
                return(new Parser10(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension));

            case "2.0":
                return(new Parser20(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension));

            case "3.0":
                return(new Parser30(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension));

            case "4.0":
                return(new Parser40(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension));

            case "5.0":
                return(new Parser50(p_xmlConfig, p_fomodMod, p_dsmSate, pexParserExtension));
            }
            throw new ParserException("Unrecognized Module Configuration version (" + strConfigVersion +
                                      "). Perhaps a newer version of FOMM is required.");
        }
Beispiel #10
0
        /// <summary>
        ///   Creates a fomod from a source.
        /// </summary>
        /// <remarks>
        ///   The source can be a folder or an archive.
        /// </remarks>
        /// <param name="p_strPath">The path to the source from which to create the fomod.</param>
        /// <returns>The path to the new fomod if it was successfully built; <lang langref="null" /> otherwise.</returns>
        public IList <string> BuildFomodFromSource(string p_strPath)
        {
            var strSource = p_strPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

            var lstPackedFOModPaths = new List <string>();

            var booCreateFromFolder = true;

            if (File.Exists(strSource))
            {
                booCreateFromFolder = false;
                if (!Archive.IsArchive(strSource))
                {
                    throw new ArgumentException("Unrecognized file format.", "p_strPath");
                }

                string[] strFOMods;
                using (var arcMod = new Archive(strSource))
                {
                    strFOMods = arcMod.GetFiles(null, "*.fomod");
                    if ((strFOMods.Length == 0) && (arcMod.VolumeFileNames.Length > 1))
                    {
                        if (
                            MessageBox.Show(
                                "This mod consists of " + arcMod.VolumeFileNames.Length +
                                " files. It needs to be extracted and repacked.", "Repack Required", MessageBoxButtons.OKCancel,
                                MessageBoxIcon.Warning) == DialogResult.Cancel)
                        {
                            return(lstPackedFOModPaths);
                        }
                        booCreateFromFolder = true;
                    }
                }

                if (!booCreateFromFolder)
                {
                    if (strFOMods.Length > 0)
                    {
                        foreach (var strFOMod in strFOMods)
                        {
                            var strNewPath = Path.Combine(Program.GameMode.ModDirectory, Path.GetFileName(strFOMod));
                            if (CheckFileName(ref strNewPath))
                            {
                                using (var szeExtractor = Archive.GetExtractor(strSource))
                                {
                                    using (var fsmFOMod = new FileStream(strNewPath, FileMode.Create))
                                    {
                                        szeExtractor.ExtractFile(strFOMod, fsmFOMod);
                                    }
                                }
                                lstPackedFOModPaths.Add(strNewPath);
                            }
                        }
                    }
                    else
                    {
                        var mof = new fomod(strSource, false);
                        if (!mof.HasInstallScript && mof.RequiresScript)
                        {
                            if (
                                MessageBox.Show(
                                    "This mod requires a script to install properly, but doesn't have one." + Environment.NewLine +
                                    "Would you like to continue?", "Missing Script", MessageBoxButtons.YesNo, MessageBoxIcon.Information) ==
                                DialogResult.No)
                            {
                                return(lstPackedFOModPaths);
                            }
                        }

                        //remove the file extension
                        var strPackedFomodPath = Path.GetFileNameWithoutExtension(strSource);

                        strPackedFomodPath = Path.Combine(Program.GameMode.ModDirectory, strPackedFomodPath);
                        if (!strPackedFomodPath.EndsWith(".fomod", StringComparison.OrdinalIgnoreCase))
                        {
                            strPackedFomodPath += ".fomod";
                        }
                        var strNewPath = strPackedFomodPath;
                        if (CheckFileName(ref strNewPath))
                        {
                            FileUtil.ForceDelete(strNewPath);
                            File.Copy(strSource, strNewPath, true);
                            lstPackedFOModPaths.Add(strNewPath);
                        }
                    }
                }
            }

            if (booCreateFromFolder)
            {
                string strFomodName;
                if (File.Exists(strSource))
                {
                    //remove the file extension
                    strFomodName = Path.GetFileNameWithoutExtension(strSource);
                }
                else
                {
                    var intLastSeparatorPos = strSource.LastIndexOfAny(new[]
                    {
                        Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar
                    });
                    strFomodName = strSource.Substring(intLastSeparatorPos + 1);
                }

                var strPackedFomodPath = Path.Combine(Program.GameMode.ModDirectory, strFomodName + ".fomod");
                strPackedFomodPath = GenerateFomod(new BuildFomodArgs(strFomodName, strSource, null, strPackedFomodPath));
                if (!String.IsNullOrEmpty(strPackedFomodPath))
                {
                    lstPackedFOModPaths.Add(strPackedFomodPath);
                }
            }

            return(lstPackedFOModPaths);
        }
Beispiel #11
0
 /// <summary>
 ///   A simple constructor that initializes the object.
 /// </summary>
 /// <param name="p_fomodMod">The <see cref="fomod" /> to be upgraded.</param>
 internal ModUpgrader(fomod p_fomodMod)
   : this(p_fomodMod, p_fomodMod.BaseName) {}
Beispiel #12
0
 /// <summary>
 ///   A simple constructor that initializes the object.
 /// </summary>
 /// <param name="p_fomodMod">The <see cref="fomod" /> to be upgraded.</param>
 internal ModUpgrader(fomod p_fomodMod, string p_strOldBaseName)
     : base(new UpgradeFomod(p_fomodMod.filepath))
 {
     m_fomodOriginalMod = p_fomodMod;
     ((UpgradeFomod)Fomod).SetBaseName(p_strOldBaseName);
 }
Beispiel #13
0
        /// <summary>
        /// Adds a mod to the install log.
        /// </summary>
        /// <remarks>
        /// Adding a mod to the install log assigns it a key. Keys are used to track file and
        /// edit versions.
        /// </remarks>
        /// <param name="p_fomodMod">The <see cref="fomod"/> being added.</param>
        protected internal void AddMod(fomod p_fomodMod)
        {
            if (!m_dicModList.ContainsKey(p_fomodMod.BaseName))
            {
                XmlNode xndMod = AddMod(p_fomodMod.BaseName);
                if (xndMod == null)
                    return;

                XmlNode xndVersion = xndMod.AppendChild(xmlDoc.CreateElement("version"));
                xndVersion.Attributes.Append(xmlDoc.CreateAttribute("machineVersion"));
                xndVersion.Attributes["machineVersion"].InnerText = p_fomodMod.MachineVersion.ToString();
                xndVersion.InnerText = p_fomodMod.HumanReadableVersion;
            }
        }
Beispiel #14
0
 /// <summary>
 /// Merges the installed and edited components in the given <see cref="InstallLogMergeModule"/>
 /// into the install log for the specified mod.
 /// </summary>
 /// <param name="p_fomodMod">The <see cref="fomod"/> for which the
 /// installs and edits where made.</param>
 /// <param name="p_ilmMergeModule">The installs and edits that where made as part of the
 /// <see cref="fomod"/>'s installation.</param>
 public void Merge(fomod p_fomodMod, InstallLogMergeModule p_ilmMergeModule)
 {
     AddMod(p_fomodMod);
     processMergeModule(p_fomodMod.BaseName, p_ilmMergeModule);
 }
Beispiel #15
0
        /// <summary>
        ///   Upgrades the installed files log entries.
        /// </summary>
        /// <remarks>
        ///   This analyses the mods and determines, as best as possible, who owns which files, and attempts
        ///   to reconstruct the install order. It populates the overwrites folder with the files that, as far
        ///   as can be determined, belong there. This resulting information is then put in the new install log.
        /// </remarks>
        /// <param name="p_xmlModInstallLog">The current mod install log we are parsing to upgrade.</param>
        /// <param name="p_strModInstallLogPath">The path to the current mod install log.</param>
        /// <param name="p_strModBaseName">The base name of the mod whose install log is being parsed.</param>
        private void UpgradeInstalledFiles(XmlDocument p_xmlModInstallLog, fomod p_fomodMod, string p_strModBaseName)
        {
            var intDataPathStartPos =
                Program.GameMode.PluginsPath.Trim(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar).Length + 1;
            var xnlFiles = p_xmlModInstallLog.SelectNodes("descendant::installedFiles/*");

            foreach (XmlNode xndFile in xnlFiles)
            {
                var strFile = xndFile.InnerText;
                if (!File.Exists(strFile))
                {
                    continue;
                }
                var strDataRelativePath = strFile.Substring(intDataPathStartPos);

                var crcDiskFile  = new Crc32();
                var crcFomodFile = new Crc32();
                crcDiskFile.Update(File.ReadAllBytes(strFile));
                if (!p_fomodMod.ContainsFile(strDataRelativePath))
                {
                    //we don't know if this mod owns the file, so let's assume
                    // it doesn't
                    //put this mod's file into the overwrites directory.
                    // we can't get the original file from the fomod,
                    // so we'll use the existing file instead. this isn't
                    // strictly correct, but it is inline with the behaviour
                    // of the fomm version we are upgrading from
                    var strDirectory  = Path.GetDirectoryName(strDataRelativePath);
                    var strBackupPath = Path.Combine(Program.GameMode.OverwriteDirectory, strDirectory);
                    var strModKey     = InstallLog.Current.GetModKey(p_strModBaseName);
                    if (!Directory.Exists(strBackupPath))
                    {
                        FileManager.CreateDirectory(strBackupPath);
                    }
                    strBackupPath = Path.Combine(strBackupPath, strModKey + "_" + Path.GetFileName(strDataRelativePath));
                    FileManager.Copy(Path.Combine(Program.GameMode.PluginsPath, strDataRelativePath), strBackupPath, true);
                    InstallLog.Current.PrependDataFile(p_strModBaseName, strDataRelativePath);

                    //however, it may own the file, so let's make it the default owner for now
                    // unless we already know who the owner is
                    if (!FileOwnerIsKnown(strDataRelativePath))
                    {
                        m_dicDefaultFileOwners[strDataRelativePath] = p_strModBaseName;
                    }
                    continue;
                }
                var bteFomodFile = p_fomodMod.GetFileContents(strDataRelativePath);
                crcFomodFile.Update(bteFomodFile);
                if (!crcDiskFile.Value.Equals(crcFomodFile.Value) || FileOwnerIsKnown(strDataRelativePath))
                {
                    //either:
                    // 1) another mod owns the file
                    // 2) according to the crc we own this file, however we have already found
                    //    an owner. this could happen beacue two mods use the same version
                    //    of a file, or there is a crc collision.
                    //either way, put this mod's file into
                    // the overwrites directory
                    var strDirectory  = Path.GetDirectoryName(strDataRelativePath);
                    var strBackupPath = Path.Combine(Program.GameMode.OverwriteDirectory, strDirectory);
                    var strModKey     = InstallLog.Current.GetModKey(p_strModBaseName);
                    if (!Directory.Exists(strBackupPath))
                    {
                        FileManager.CreateDirectory(strBackupPath);
                    }
                    strBackupPath = Path.Combine(strBackupPath, strModKey + "_" + Path.GetFileName(strDataRelativePath));
                    FileManager.WriteAllBytes(strBackupPath, bteFomodFile);
                    InstallLog.Current.PrependDataFile(p_strModBaseName, strDataRelativePath);
                }
                else
                {
                    //this mod owns the file, so append it to the list of installing mods
                    InstallLog.Current.AddDataFile(p_strModBaseName, strDataRelativePath);

                    //we also have to displace the mod that is currently the default owner
                    if (m_dicDefaultFileOwners.ContainsKey(strDataRelativePath))
                    {
                        m_dicDefaultFileOwners.Remove(strDataRelativePath);
                    }
                }

                if (ProgressWorker.Cancelled())
                {
                    return;
                }
                ProgressWorker.StepItemProgress();
            }
        }
        /// <summary>
        /// Creates a fomod from a source.
        /// </summary>
        /// <remarks>
        /// The source can be a folder or an archive.
        /// </remarks>
        /// <param name="p_strPath">The path to the source from which to create the fomod.</param>
        /// <param name="p_nxaNexus">An initialized website API from which to retireve mod info.</param>
        /// <returns>The path to the new fomod if it was successfully built; <lang cref="null"/> otherwise.</returns>
        public IList<string> BuildFomodFromSource(string p_strPath, NexusAPI p_nxaNexus)
        {
            string strSource = p_strPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

            List<string> lstPackedFOModPaths = new List<string>();

            bool booCreateFromFolder = true;

            if (File.Exists(strSource))
            {
                booCreateFromFolder = false;
                if (!Archive.IsArchive(strSource))
                    throw new ArgumentException("Unrecognized file format.", "p_strPath");

                string[] strFOMods = null;
                using (Archive arcMod = new Archive(strSource))
                {
                    strFOMods = arcMod.GetFiles(null, "*.fomod");
                    if ((strFOMods.Length == 0) && (arcMod.VolumeFileNames.Length > 1))
                    {
                        if (MessageBox.Show("This mod consists of " + arcMod.VolumeFileNames.Length + " files. It needs to be extracted and repacked.", "Repack Required", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.Cancel)
                            return lstPackedFOModPaths;
                        booCreateFromFolder = true;
                    }
                }

                if (!booCreateFromFolder)
                {
                    if (strFOMods.Length > 0)
                    {
                        foreach (string strFOMod in strFOMods)
                        {
                            string strNewPath = Path.Combine(Program.GameMode.ModDirectory, Path.GetFileName(strFOMod));
                            if (CheckFileName(ref strNewPath))
                            {
                                using (SevenZipExtractor szeExtractor = Archive.GetExtractor(strSource))
                                {
                                    using (FileStream fsmFOMod = new FileStream(strNewPath, FileMode.Create))
                                        szeExtractor.ExtractFile(strFOMod, fsmFOMod);
                                }
                                lstPackedFOModPaths.Add(strNewPath);
                            }
                        }
                    }
                    else
                    {
                        fomod mof = new fomod(strSource, false);
                        if (!mof.HasInstallScript && mof.RequiresScript)
                        {
                            if (MessageBox.Show("This mod requires a script to install properly, but doesn't have one." + Environment.NewLine + "Would you like to continue?", "Missing Script", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                                return lstPackedFOModPaths;
                        }
                        //remove the file extension
                        string strPackedFomodPath = Path.GetFileNameWithoutExtension(strSource);
                        //remove the .part1 or what have for multipart files
                        strPackedFomodPath = Path.GetFileNameWithoutExtension(strPackedFomodPath);
                        strPackedFomodPath = Path.Combine(Program.GameMode.ModDirectory, strPackedFomodPath);
                        if (!strPackedFomodPath.EndsWith(".fomod", StringComparison.OrdinalIgnoreCase))
                            strPackedFomodPath += ".fomod";
                        string strNewPath = strPackedFomodPath;
                        if (CheckFileName(ref strNewPath))
                        {
                            FileUtil.ForceDelete(strNewPath);
                            if (MessageBox.Show("Make a copy of the original file?", "", MessageBoxButtons.YesNo) != DialogResult.Yes)
                                File.Move(strSource, strNewPath);
                            else
                                File.Copy(strSource, strNewPath, true);
                            lstPackedFOModPaths.Add(strNewPath);
                        }
                    }
                }
            }

            if (booCreateFromFolder)
            {
                string strFomodName = null;
                if (File.Exists(strSource))
                {
                    //remove the file extension
                    strFomodName = Path.GetFileNameWithoutExtension(strSource);
                    //remove the .part1 or what have for multipart files
                    strFomodName = Path.GetFileNameWithoutExtension(strFomodName);
                }
                else
                {
                    Int32 intLastSeparatorPos = strSource.LastIndexOfAny(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
                    strFomodName = strSource.Substring(intLastSeparatorPos + 1);
                }

                string strPackedFomodPath = Path.Combine(Program.GameMode.ModDirectory, strFomodName + ".fomod");
                strPackedFomodPath = GenerateFomod(new BuildFomodArgs(strFomodName, strSource, null, strPackedFomodPath));
                if (!String.IsNullOrEmpty(strPackedFomodPath))
                    lstPackedFOModPaths.Add(strPackedFomodPath);
            }

            ModInfo mifInfo = null;
            if (Properties.Settings.Default.addMissingInfoToMods)
            {
                mifInfo = p_nxaNexus.GetFileInfoGuessVersion(strSource, true);
                if (mifInfo != null)
                {
                    foreach (string strFomod in lstPackedFOModPaths)
                    {
                        fomod fomodMod = new fomod(strFomod);
                        fomodMod.SetMissingInfo(mifInfo);
                    }
                }
            }

            return lstPackedFOModPaths;
        }
Beispiel #17
0
 /// <summary>
 ///   Creates a mod upgrade script for the given <see cref="fomod" />.
 /// </summary>
 /// <param name="p_fomodMod">The mod for which to create an installer script.</param>
 /// <param name="p_mibInstaller">The installer for which the script is being created.</param>
 /// <returns>A mod upgrade script for the given <see cref="fomod" />.</returns>
 public abstract ModInstallScript CreateUpgradeScript(fomod p_fomodMod, ModInstallerBase p_mibInstaller);
Beispiel #18
0
 /// <summary>
 /// Updates a mod's information in the install log.
 /// </summary>
 /// <remarks>
 /// This updates the given mod's version and base name in the install log without changing its key.
 /// </remarks>
 /// <param name="p_strOldBaseName">The old base name of the mod whose information is to be updated.</param>
 /// <param name="p_fomodMod">The <see cref="fomod"/> containing the new information.</param>
 /// <returns><lang cref="true"/> if the given fomod was found and it's information updated;
 /// <lang cref="false"/> otherwise.</returns>
 protected bool UpdateMod(string p_strOldBaseName, fomod p_fomodMod)
 {
     if (p_fomodMod.BaseName.Equals(p_strOldBaseName))
         return UpdateMod(p_fomodMod);
     if (m_dicModList.ContainsKey(p_strOldBaseName))
     {
         string strKey = GetModKey(p_strOldBaseName);
         XmlNode xndMod = m_xelModListNode.SelectSingleNode("mod[@key=\"" + strKey + "\"]");
         xndMod.Attributes["name"].InnerText = p_fomodMod.BaseName;
         m_dicModList.Remove(p_strOldBaseName);
         m_dicModList.Add(p_fomodMod.BaseName, strKey);
         return UpdateMod(p_fomodMod);
     }
     return false;
 }
Beispiel #19
0
        /// <summary>
        ///   Upgrades the Install Log to the current version from version 0.0.0.0.
        /// </summary>
        /// <remarks>
        ///   This method is called by a background worker to perform the actual upgrade.
        /// </remarks>
        protected override void DoUpgrade()
        {
            InstallLog.Current.Reset();

            var strModInstallFiles = Directory.GetFiles(Program.GameMode.ModDirectory, "*.XMl",
                                                        SearchOption.TopDirectoryOnly);

            ProgressWorker.OverallProgressStep    = 1;
            ProgressWorker.OverallProgressMaximum = strModInstallFiles.Length;
            ProgressWorker.ItemProgressStep       = 1;

            foreach (var strModInstallLog in strModInstallFiles)
            {
                if (ProgressWorker.Cancelled())
                {
                    return;
                }

                var strFomodPath = Path.ChangeExtension(strModInstallLog, ".fomod");
                if (File.Exists(strFomodPath))
                {
                    var xmlModInstallLog = new XmlDocument();
                    xmlModInstallLog.Load(strModInstallLog);
                    //figure out how much work we need to do for this mod
                    var xnlFiles     = xmlModInstallLog.SelectNodes("descendant::installedFiles/*");
                    var xnlIniEdits  = xmlModInstallLog.SelectNodes("descendant::iniEdits/*");
                    var xnlSdpEdits  = xmlModInstallLog.SelectNodes("descendant::sdpEdits/*");
                    var intItemCount = xnlFiles.Count + xnlIniEdits.Count + xnlSdpEdits.Count;
                    ProgressWorker.ItemMessage         = Path.GetFileNameWithoutExtension(strModInstallLog);
                    ProgressWorker.ItemProgress        = 0;
                    ProgressWorker.ItemProgressMaximum = intItemCount;

                    var fomodMod       = new fomod(strFomodPath);
                    var strModBaseName = fomodMod.BaseName;
                    InstallLog.Current.AddMod(fomodMod);

                    m_dicDefaultFileOwners = new Dictionary <string, string>();
                    UpgradeInstalledFiles(xmlModInstallLog, fomodMod, strModBaseName);
                    //we now have to tell all the remaining default owners that are are indeed
                    // the owners
                    foreach (var kvpOwner in m_dicDefaultFileOwners)
                    {
                        MakeOverwrittenModOwner(kvpOwner.Value, kvpOwner.Key);
                    }
                    if (ProgressWorker.Cancelled())
                    {
                        return;
                    }

                    UpgradeIniEdits(xmlModInstallLog, strModBaseName);
                    if (ProgressWorker.Cancelled())
                    {
                        return;
                    }

                    UpgradeSdpEdits(xmlModInstallLog, strModBaseName);
                    if (ProgressWorker.Cancelled())
                    {
                        return;
                    }

                    if (File.Exists(strModInstallLog + ".bak"))
                    {
                        FileManager.Delete(strModInstallLog + ".bak");
                    }
                    FileManager.Move(strModInstallLog, strModInstallLog + ".bak");
                }
                ProgressWorker.StepOverallProgress();
            }
            InstallLog.Current.SetInstallLogVersion(InstallLog.CURRENT_VERSION);
            InstallLog.Current.Save();
        }
Beispiel #20
0
        /// <summary>
        /// Merges the installed and edited components in the given <see cref="InstallLogMergeModule"/>
        /// into the install log for the specified mod, as an in-place upgrade.
        /// </summary>
        /// <remarks>
        /// When a <see cref="InstallLogMergeModule"/> is merged as an in-place upgrade, any files/changes
        /// that exist in the install log for the given fomod are replaced where they are in the install
        /// order, rather than being made the file/change owner (unless they already where the file/change
        /// owner). Note, however, that if the merge module contains new files/changes that the previous fomod
        /// version did not contain the fomods will become the owner of the new files/changes.
        /// 
        /// Also, changes that are logged for the speicifed fomod that are not in the given
        /// <see cref="InstallLogMergeModule"/> are removed from the install log.
        /// </remarks>
        /// <param name="p_fomodMod">The <see cref="fomod"/> for which the
        /// installs and edits where made.</param>
        /// <param name="p_strOldBaseName">The old base name of the fomod that is being upgraded. This is the
        /// base name that will be replaced with the base name of the given fomod.</param>
        /// <param name="p_ilmMergeModule">The installs and edits that where made as part of the
        /// <see cref="fomod"/>'s upgrade.</param>
        public void MergeUpgrade(fomod p_fomodMod, string p_strOldBaseName, InstallLogMergeModule p_ilmMergeModule)
        {
            if (!UpdateMod(p_strOldBaseName, p_fomodMod))
                AddMod(p_fomodMod);

            //remove changes that were not made in the upgrade
            InstallLogMergeModule ilmPreviousChanges = GetMergeModule(p_fomodMod.BaseName);
            foreach (string strFile in ilmPreviousChanges.DataFiles)
                if (!p_ilmMergeModule.ContainsFile(strFile))
                    RemoveDataFile(p_fomodMod.BaseName, strFile);
            foreach (InstallLogMergeModule.IniEdit iniEdit in ilmPreviousChanges.IniEdits)
                if (!p_ilmMergeModule.IniEdits.Contains(iniEdit))
                    RemoveIniEdit(p_fomodMod.BaseName, iniEdit.File, iniEdit.Section, iniEdit.Key);
            foreach (InstallLogMergeModule.GameSpecificValueEdit gsvEdit in ilmPreviousChanges.GameSpecificValueEdits)
                if (!p_ilmMergeModule.GameSpecificValueEdits.Contains(gsvEdit))
                    RemoveGameSpecificValueEdit(p_fomodMod.BaseName, gsvEdit.Key);

            //add/replace changes
            foreach (string strFile in p_ilmMergeModule.ReplacedOriginalDataFiles)
                AddDataFile(ORIGINAL_VALUES, strFile);
            foreach (string strFile in p_ilmMergeModule.DataFiles)
                ReplaceDataFile(p_fomodMod.BaseName, strFile);
            foreach (InstallLogMergeModule.IniEdit iniEdit in p_ilmMergeModule.ReplacedOriginalIniValues)
                AddIniEdit(iniEdit.File, iniEdit.Section, iniEdit.Key, ORIGINAL_VALUES, iniEdit.Value);
            foreach (InstallLogMergeModule.IniEdit iniEdit in p_ilmMergeModule.IniEdits)
                ReplaceIniEdit(iniEdit.File, iniEdit.Section, iniEdit.Key, p_fomodMod.BaseName, iniEdit.Value);
            foreach (InstallLogMergeModule.GameSpecificValueEdit gsvEdit in p_ilmMergeModule.ReplacedGameSpecificValueData)
                AddGameSpecificValueEdit(ORIGINAL_VALUES, gsvEdit.Key, gsvEdit.Data);
            foreach (InstallLogMergeModule.GameSpecificValueEdit gsvEdit in p_ilmMergeModule.GameSpecificValueEdits)
                ReplaceGameSpecificValueEdit(p_fomodMod.BaseName, gsvEdit.Key, gsvEdit.Data);

            Save();
        }
    /// <summary>
    ///   Creates a fomod from a source.
    /// </summary>
    /// <remarks>
    ///   The source can be a folder or an archive.
    /// </remarks>
    /// <param name="p_strPath">The path to the source from which to create the fomod.</param>
    /// <returns>The path to the new fomod if it was successfully built; <lang langref="null" /> otherwise.</returns>
    public IList<string> BuildFomodFromSource(string p_strPath)
    {
      var strSource = p_strPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

      var lstPackedFOModPaths = new List<string>();

      var booCreateFromFolder = true;

      if (File.Exists(strSource))
      {
        booCreateFromFolder = false;
        if (!Archive.IsArchive(strSource))
        {
          throw new ArgumentException("Unrecognized file format.", "p_strPath");
        }

        string[] strFOMods;
        using (var arcMod = new Archive(strSource))
        {
          strFOMods = arcMod.GetFiles(null, "*.fomod");
          if ((strFOMods.Length == 0) && (arcMod.VolumeFileNames.Length > 1))
          {
            if (
              MessageBox.Show(
                "This mod consists of " + arcMod.VolumeFileNames.Length +
                " files. It needs to be extracted and repacked.", "Repack Required", MessageBoxButtons.OKCancel,
                MessageBoxIcon.Warning) == DialogResult.Cancel)
            {
              return lstPackedFOModPaths;
            }
            booCreateFromFolder = true;
          }
        }

        if (!booCreateFromFolder)
        {
          if (strFOMods.Length > 0)
          {
            foreach (var strFOMod in strFOMods)
            {
              var strNewPath = Path.Combine(Program.GameMode.ModDirectory, Path.GetFileName(strFOMod));
              if (CheckFileName(ref strNewPath))
              {
                using (var szeExtractor = Archive.GetExtractor(strSource))
                {
                  using (var fsmFOMod = new FileStream(strNewPath, FileMode.Create))
                  {
                    szeExtractor.ExtractFile(strFOMod, fsmFOMod);
                  }
                }
                lstPackedFOModPaths.Add(strNewPath);
              }
            }
          }
          else
          {
            var mof = new fomod(strSource, false);
            if (!mof.HasInstallScript && mof.RequiresScript)
            {
              if (
                MessageBox.Show(
                  "This mod requires a script to install properly, but doesn't have one." + Environment.NewLine +
                  "Would you like to continue?", "Missing Script", MessageBoxButtons.YesNo, MessageBoxIcon.Information) ==
                DialogResult.No)
              {
                return lstPackedFOModPaths;
              }
            }

            //remove the file extension
            var strPackedFomodPath = Path.GetFileNameWithoutExtension(strSource);

            strPackedFomodPath = Path.Combine(Program.GameMode.ModDirectory, strPackedFomodPath);
            if (!strPackedFomodPath.EndsWith(".fomod", StringComparison.OrdinalIgnoreCase))
            {
              strPackedFomodPath += ".fomod";
            }
            var strNewPath = strPackedFomodPath;
            if (CheckFileName(ref strNewPath))
            {
              FileUtil.ForceDelete(strNewPath);
              File.Copy(strSource, strNewPath, true);
              lstPackedFOModPaths.Add(strNewPath);
            }
          }
        }
      }

      if (booCreateFromFolder)
      {
        string strFomodName;
        if (File.Exists(strSource))
        {
          //remove the file extension
          strFomodName = Path.GetFileNameWithoutExtension(strSource);
        }
        else
        {
          var intLastSeparatorPos = strSource.LastIndexOfAny(new[]
          {
            Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar
          });
          strFomodName = strSource.Substring(intLastSeparatorPos + 1);
        }

        var strPackedFomodPath = Path.Combine(Program.GameMode.ModDirectory, strFomodName + ".fomod");
        strPackedFomodPath = GenerateFomod(new BuildFomodArgs(strFomodName, strSource, null, strPackedFomodPath));
        if (!String.IsNullOrEmpty(strPackedFomodPath))
        {
          lstPackedFOModPaths.Add(strPackedFomodPath);
        }
      }

      return lstPackedFOModPaths;
    }
Beispiel #22
0
 /// <summary>
 /// Updates a mod's information in the install log.
 /// </summary>
 /// <remarks>
 /// This updates the given mod's version in the install log without changing its key.
 /// </remarks>
 /// <param name="p_fomodMod">The <see cref="fomod"/> being updated.</param>
 /// <returns><lang cref="true"/> if the given fomod was found and it's information updated;
 /// <lang cref="false"/> otherwise.</returns>
 protected internal bool UpdateMod(fomod p_fomodMod)
 {
     if (m_dicModList.ContainsKey(p_fomodMod.BaseName))
     {
         XmlNode xndMod = m_xelModListNode.SelectSingleNode("mod[@key=\"" + GetModKey(p_fomodMod.BaseName) + "\"]");
         XmlNode xndVersion = xndMod.SelectSingleNode("version");
         if (xndVersion == null)
         {
             xndVersion = xndMod.AppendChild(xmlDoc.CreateElement("version"));
             xndVersion.Attributes.Append(xmlDoc.CreateAttribute("machineVersion"));
         }
         xndVersion.Attributes["machineVersion"].InnerText = p_fomodMod.MachineVersion.ToString();
         xndVersion.InnerText = p_fomodMod.HumanReadableVersion;
         return true;
     }
     return false;
 }
Beispiel #23
0
 /// <summary>
 ///   A simple constructor that initializes the object.
 /// </summary>
 /// <param name="p_fomodMod">The <see cref="fomod" /> to be upgraded.</param>
 internal ModUpgrader(fomod p_fomodMod, string p_strOldBaseName)
   : base(new UpgradeFomod(p_fomodMod.filepath))
 {
   m_fomodOriginalMod = p_fomodMod;
   ((UpgradeFomod) Fomod).SetBaseName(p_strOldBaseName);
 }
Beispiel #24
0
 /// <summary>
 ///   A simple constructor that initializes teh object with the given values.
 /// </summary>
 /// <param name="p_xmlConfig">The modules configuration file.</param>
 /// <param name="p_fomodMod">The mod whose configuration file we are parsing.</param>
 /// <param name="p_dsmSate">The state of the install.</param>
 /// <param name="p_pexParserExtension">The parser extension that provides game-specific config file parsing.</param>
 public Parser50(XmlDocument p_xmlConfig, fomod p_fomodMod, DependencyStateManager p_dsmSate,
                 ParserExtension p_pexParserExtension)
   : base(p_xmlConfig, p_fomodMod, p_dsmSate, p_pexParserExtension) {}
 /// <summary>
 ///   A simple constructor that initializes the object.
 /// </summary>
 /// <param name="p_fomodMod">The <see cref="fomod" /> against which to run the script.</param>
 public FalloutNewVegasModInstallScript(fomod p_fomodMod, ModInstallerBase p_mibInstaller)
     : base(p_fomodMod, p_mibInstaller)
 {
 }
Beispiel #26
0
 /// <summary>
 ///   A simple constructor that initializes the object.
 /// </summary>
 /// <param name="p_fomodMod">The <see cref="fomod" /> to be upgraded.</param>
 internal ModUpgrader(fomod p_fomodMod)
     : this(p_fomodMod, p_fomodMod.BaseName)
 {
 }
Beispiel #27
0
 /// <summary>
 ///   Creates a mod upgrade script for the given <see cref="fomod" />.
 /// </summary>
 /// <param name="p_fomodMod">The mod for which to create an installer script.</param>
 /// <param name="p_mibInstaller">The installer for which the script is being created.</param>
 /// <returns>A mod upgrade script for the given <see cref="fomod" />.</returns>
 public override ModInstallScript CreateUpgradeScript(fomod p_fomodMod, ModInstallerBase p_mibInstaller)
 {
     return(new FalloutNewVegasModUpgradeScript(p_fomodMod, p_mibInstaller));
 }
Beispiel #28
0
 /// <summary>
 ///   A simple constructor that initializes teh object with the given values.
 /// </summary>
 /// <param name="p_xmlConfig">The modules configuration file.</param>
 /// <param name="p_fomodMod">The mod whose configuration file we are parsing.</param>
 /// <param name="p_dsmSate">The state of the install.</param>
 /// <param name="p_pexParserExtension">The parser extension that provides game-specific config file parsing.</param>
 public Parser10(XmlDocument p_xmlConfig, fomod p_fomodMod, DependencyStateManager p_dsmSate,
                 ParserExtension p_pexParserExtension)
     : base(p_xmlConfig, p_fomodMod, p_dsmSate, p_pexParserExtension)
 {
 }
Beispiel #29
0
 /// <summary>
 ///   A simple constructor that initializes the object.
 /// </summary>
 /// <param name="p_fomodMod">The <see cref="fomod" /> against which to run the script.</param>
 public Fallout3ModUpgradeScript(fomod p_fomodMod, ModInstallerBase p_mibInstaller)
     : base(p_fomodMod, p_mibInstaller)
 {
 }