Пример #1
0
        /// <summary>
        /// Performs the most low-level mod enable/disable functions, without saving the modlist,
        /// ergo this should only be called by functions which will handle saving the modlist after
        /// they're done performing all modlist operations.
        ///
        /// If the Index and modlist are provided, the actions are only applied to those cached entries, rather
        /// than to the live files.
        /// </summary>
        /// <param name="enable"></param>
        /// <param name="mod"></param>
        /// <returns></returns>
        public async Task <bool> ToggleModUnsafe(bool enable, Mod mod, bool includeInternal, bool updateCache, IndexFile cachedIndex = null, ModList cachedModlist = null)
        {
            if (mod == null)
            {
                return(false);
            }
            if (string.IsNullOrEmpty(mod.name))
            {
                return(false);
            }
            if (string.IsNullOrEmpty(mod.fullPath))
            {
                return(false);
            }

            if (mod.data.originalOffset <= 0 && !enable)
            {
                throw new Exception("Cannot disable mod with invalid original offset.");
            }

            if (enable && mod.data.modOffset <= 0)
            {
                throw new Exception("Cannot enable mod with invalid mod offset.");
            }

            if (mod.IsInternal() && !includeInternal)
            {
                // Don't allow toggling internal mods unless we were specifically told to.
                return(false);
            }

            var index = new Index(_gameDirectory);
            var dat   = new Dat(_gameDirectory);

            // Added file.
            if (enable)
            {
                if (cachedIndex != null)
                {
                    cachedIndex.SetDataOffset(mod.fullPath, mod.data.modOffset);
                }
                else
                {
                    await index.UpdateDataOffset(mod.data.modOffset, mod.fullPath, false);
                }
                mod.enabled = true;

                if (cachedIndex == null)
                {
                    // Check if we're re-enabling a metadata mod.
                    var ext = Path.GetExtension(mod.fullPath);
                    if (ext == ".meta")
                    {
                        var df = IOUtil.GetDataFileFromPath(mod.fullPath);
                        // Retreive the uncompressed meta entry we just enabled.
                        var data = await dat.GetType2Data(mod.data.modOffset, df);

                        var meta = await ItemMetadata.Deserialize(data);

                        meta.Validate(mod.fullPath);

                        // And write that metadata to the actual constituent files.
                        await ItemMetadata.ApplyMetadata(meta, cachedIndex, cachedModlist);
                    }
                    else if (ext == ".rgsp")
                    {
                        await CMP.ApplyRgspFile(mod.fullPath, cachedIndex, cachedModlist);
                    }
                }
            }
            else if (!enable)
            {
                if (mod.IsCustomFile())
                {
                    // Delete file descriptor handles removing metadata as needed on its own.
                    if (cachedIndex != null)
                    {
                        cachedIndex.SetDataOffset(mod.fullPath, 0);
                    }
                    else
                    {
                        await index.DeleteFileDescriptor(mod.fullPath, IOUtil.GetDataFileFromPath(mod.fullPath), false);
                    }
                }
                else
                {
                    if (cachedIndex != null)
                    {
                        cachedIndex.SetDataOffset(mod.fullPath, mod.data.originalOffset);
                    }
                    else
                    {
                        await index.UpdateDataOffset(mod.data.originalOffset, mod.fullPath, false);
                    }
                }
                mod.enabled = false;
            }

            if (updateCache)
            {
                XivCache.QueueDependencyUpdate(mod.fullPath);
            }

            return(true);
        }