public void DeleteMod(ModDefinition def)
        {
            if (_modConfig.InstalledModIDs.Contains(def.ID))
            {
                var ops = GetUninstallModOps(def);
                ops.ForEach(x => _getEngine().OpManager.QueueOp(x));
                ops.WaitForFinish();
                if (ops.Any(x => x.Status == OpStatus.Failed))
                {
                    string err = "";
                    foreach (var failed in ops.Where(x => x.Status == OpStatus.Failed))
                    {
                        err += failed.GetType().Name + " failed! " + failed.Exception ?? " \n";
                    }
                    throw new Exception("Uninstall of mod failed, cannot delete it! " + err);
                }
            }
            var defPath = _config.ModsSourcePath.CombineFwdSlash(def.ID);

            if (!_config.RootFileProvider.DirectoryExists(defPath))
            {
                Log.LogErr($"Tried to delete mod ID {def.ID} but it doesn't seem to exist at {defPath}.  Going to count it as already uninstalled.");
                return;
            }

            var qfo = new QueuedFileOp()
            {
                Tag = def.id, Type = QueuedFileOperationType.DeleteFolder, TargetPath = defPath
            };

            _getEngine().QueuedFileOperations.Add(qfo);
            _deletedModIDs.Add(def.ID);
            ResetCache();
        }
        public void ModAdded(ModDefinition def)
        {
            if (_deletedModIDs.Contains(def.ID))
            {
                _deletedModIDs.Remove(def.ID);
            }
            var e = _getEngine();

            e.QueuedFileOperations.RemoveAll(x => x.Tag == def.id);
        }
        public List <AssetOp> GetInstallModOps(ModDefinition modDef)
        {
            List <AssetOp> ops = new List <AssetOp>();
            ModContext     mc  = new ModContext(_config.ModsSourcePath.CombineFwdSlash(modDef.ID), _config, _getEngine);

            if (modDef.Category.IsExclusiveMod())
            {
                var otherSabers = Mods.Where(x => x.Category == modDef.Category && x.ID != modDef.ID && x.Status == ModStatusType.Installed);
                foreach (var otherSaber in otherSabers)
                {
                    ops.AddRange(otherSaber.GetUninstallOps(mc));
                }
            }

            ops.AddRange(modDef.GetInstallOps(mc));
            return(ops);
        }
        private ModDefinition LoadModDef(IFileProvider provider, string path = "")
        {
            ModDefinition def = null;

            if (!provider.FileExists(path.CombineFwdSlash(MOD_FILE_NAME)))
            {
                throw new Exception($"ModDefinition can't load zip file becase it does not contain {MOD_FILE_NAME}");
            }
            using (JsonTextReader jr = new JsonTextReader(new StreamReader(provider.GetReadStream(path.CombineFwdSlash(MOD_FILE_NAME)))))
            {
                def = new JsonSerializer().Deserialize <ModDefinition>(jr);
            }
            if (def == null)
            {
                throw new Exception("ModDefinition failed to deserialize.");
            }

            return(def);
        }
        public void SetModStatus(ModDefinition definition, ModStatusType status)
        {
            lock (_cacheLock)
            {
                var def = Mods.FirstOrDefault(x => x.ID == definition.ID);
                if (def != null)
                {
                    switch (status)
                    {
                    case ModStatusType.Installed:
                        if (_modConfig.InstalledModIDs.Contains(definition.ID))
                        {
                            Log.LogErr($"ModStatusOp was supposed to install mod ID {definition.ID} but it is already listed as installed.");
                        }
                        else
                        {
                            _modConfig.InstalledModIDs.Add(definition.ID);
                        }
                        break;

                    case ModStatusType.NotInstalled:
                        if (!_modConfig.InstalledModIDs.Contains(definition.ID))
                        {
                            Log.LogErr($"ModStatusOp was supposed to uninstall mod ID {definition.ID} but it doesn't appear to be installed.");
                        }
                        else
                        {
                            _modConfig.InstalledModIDs.Remove(definition.ID);
                        }
                        break;
                    }
                    def.Status        = status;
                    definition.Status = status;
                }
                else
                {
                    Log.LogErr($"Mod ID was not found when trying to set its status to {status}!");
                }
            }
        }
        public List <AssetOp> GetUninstallModOps(ModDefinition modDef)
        {
            ModContext mc = new ModContext(_config.ModsSourcePath.CombineFwdSlash(modDef.ID), _config, _getEngine);

            return(modDef.GetUninstallOps(mc));
        }