/// <summary> /// Finds the root folder of the mod that can be installed to the KSP install folder. /// </summary> /// <param name="node">Node to start the search from.</param> /// <returns>The root folder of the mod that can be installed to the KSP install folder.</returns> private static bool FindAndSetDestinationPaths(ModNode node) { List <ModNode> kspFolders = new List <ModNode>(); List <ModNode> craftFiles = new List <ModNode>(); ModSelectionTreeModel.GetAllKSPFolders(node, ref kspFolders, ref craftFiles); if (kspFolders.Count == 1) { SetDestinationPaths(kspFolders[0], false); } else if (kspFolders.Count > 1) { kspFolders.Sort((node1, node2) => { if (node2.Depth == node1.Depth) { return(node1.Text.CompareTo(node2.Text)); } else { return(node2.Depth - node1.Depth); } }); bool lastResult = false; foreach (ModNode kspFolder in kspFolders) { lastResult = SetDestinationPaths(kspFolder, lastResult); } } if (craftFiles.Count > 0) { foreach (ModNode craftNode in craftFiles) { string vab = KSPPathHelper.GetPath(KSPPaths.VAB); string sph = KSPPathHelper.GetPath(KSPPaths.SPH); if (!craftNode.HasDestination || (!craftNode.Destination.StartsWith(vab, StringComparison.CurrentCultureIgnoreCase) && !craftNode.Destination.StartsWith(sph, StringComparison.CurrentCultureIgnoreCase))) { SetCraftDestination(craftNode); } } } if (node.HasDestination || node.HasDestinationForChilds) { node.SetChecked(true); } return((kspFolders.Count > 0) || (craftFiles.Count > 0)); }
/// <summary> /// Checks the node and all parents. /// </summary> /// <param name="node">The node to check.</param> private static void CheckNodeAndParents(ModNode node) { // check node and parent nodes. node.SetChecked(true); if (node.Parent == null || node.Parent.Index == -1) { return; } Node parent = node.Parent; while (parent != null && parent.Index > -1) { ((ModNode)parent).SetChecked(true); parent = parent.Parent; } }
/// <summary> /// Removes the part from KSP and unchecks it in the mod selection. /// </summary> /// <param name="partNode">The part node to remove.</param> public static void RemovePart(PartNode partNode) { if (partNode == null) { return; } string partPath = Path.GetDirectoryName(KSPPathHelper.GetAbsolutePath(partNode.FilePath)); ModNode node = ModSelectionTreeModel.SearchNodeByDestination(partNode.FilePath, ModSelectionController.Model); DialogResult dlgResult = DialogResult.Cancel; if (node == null) { dlgResult = MessageBox.Show(View.ParentForm, Messages.MSG_PART_NOT_FROM_MOD_DELETE_WARNING, string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } if (partNode.Nodes != null && partNode.Nodes.Count > 0) { StringBuilder sb = new StringBuilder(); sb.AppendLine(Messages.MSG_PART_USED_DELETE_WARNING); foreach (PartNode tempNode in partNode.Nodes) { sb.AppendFormat("- {0}{1}", tempNode.Title, Environment.NewLine); } sb.AppendLine(); sb.AppendLine(Messages.MSG_DELETE_ANYWAY); dlgResult = MessageBox.Show(View.ParentForm, sb.ToString(), string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } if ((node != null || dlgResult == DialogResult.Yes) && Directory.Exists(partPath)) { Messenger.AddInfo(string.Format(Messages.MSG_DIR_0_OF_PART_1_DELETED, partPath, Path.GetFileName(partPath))); Directory.Delete(partPath, true); if (partNode.Nodes != null) { foreach (var n in partNode.Nodes) { var craft = n.Tag as CraftNode; if (craft == null) { continue; } craft.RemovePartRelation(partNode); } } if (node != null) { node = node.Parent as ModNode; node.SetChecked(false); node.IsInstalled = false; node.NodeType = NodeType.UnknownFolder; Messenger.AddInfo(string.Format(Messages.MSG_MODNODE_0_UNCHECKED, node.Name)); foreach (ModNode child in node.Nodes) { child.SetChecked(false); child.IsInstalled = false; child.NodeType = child.IsFile ? NodeType.UnknownFile : NodeType.UnknownFolder; Messenger.AddInfo(string.Format(Messages.MSG_MODNODE_0_UNCHECKED, child.Name)); } } model.Nodes.Remove(partNode); allNodes.Remove(partNode); } }
/// <summary> /// Creates a TreeNode for the XmlNode information. /// </summary> private static void FillModTreeNode(XmlNode mod, ref ModNode node) { string kspForumURL = string.Empty; string curseForgeURL = string.Empty; node.AddDate = DateTime.Now.ToString(); foreach (XmlAttribute att in mod.Attributes) { if (att.Name == Constants.NAME) { node.Name = att.Value; } else if (att.Name == Constants.KEY) { node.Key = att.Value; } else if (att.Name == Constants.ADDDATE) { node.AddDate = att.Value; } else if (att.Name == Constants.VERSION) { node.Version = att.Value; } else if (att.Name == Constants.GAMEVERSION) { node.KSPVersion = att.Value; } else if (att.Name == Constants.NOTE) { node.Note = att.Value; } else if (att.Name == Constants.PRODUCTID) { node.ProductID = att.Value; } else if (att.Name == Constants.CREATIONDATE) { node.CreationDate = att.Value; } else if (att.Name == Constants.CHANGEDATE) { node.ChangeDate = att.Value; } else if (att.Name == Constants.AUTHOR) { node.Author = att.Value; } else if (att.Name == Constants.RATING) { node.Rating = att.Value; } else if (att.Name == Constants.DOWNLOADS) { node.Downloads = att.Value; } else if (att.Name == Constants.MODURL) { node.ModURL = att.Value; } else if (att.Name == Constants.AVCURL) { node.AvcURL = att.Value; } else if (att.Name == Constants.ADDITIONALURL) { node.AdditionalURL = att.Value; } else if (att.Name == Constants.CHECKED) { node.SetChecked((att.Value.Equals(Constants.TRUE, StringComparison.CurrentCultureIgnoreCase)), true); } else if (att.Name == Constants.NODETYPE) { node.NodeType = (NodeType)int.Parse(att.Value); } else if (att.Name == Constants.DESTINATION) { node.Destination = att.Value; } else if (att.Name == Constants.FORUMURL) { kspForumURL = att.Value; } else if (att.Name == Constants.CURSEFORGEURL) { curseForgeURL = att.Value; } else if (att.Name == Constants.VERSIONCONTROLERNAME) { node.SiteHandlerName = att.Value; switch (att.Value) { case "KSPForum": // KSPForum if (string.IsNullOrEmpty(node.ModURL)) { node.ModURL = kspForumURL; } if (string.IsNullOrEmpty(node.AdditionalURL)) { node.AdditionalURL = curseForgeURL; } break; case "CurseForge": // CurseForge if (string.IsNullOrEmpty(node.ModURL)) { node.ModURL = curseForgeURL; } if (string.IsNullOrEmpty(node.AdditionalURL)) { node.AdditionalURL = kspForumURL; } break; } } } foreach (XmlNode modEntry in mod.ChildNodes) { ModNode newNode = new ModNode(); node.Nodes.Add(newNode); FillModTreeNode(modEntry, ref newNode); } }
/// <summary> /// Tries to find notes in the new mod, that matches to the outdated mod. /// If a matching node was found the destination and/or the checked state of the node will be copied. /// </summary> /// <param name="outdatedMod">The outdated mod.</param> /// <param name="newMod">The new (updated) mod.</param> /// <returns>True if matching files where found, otherwise false.</returns> public static bool TryCopyDestToMatchingNodes(ICopyModInfo outdatedMod, ModNode newMod) { // Get all files with destination. List <ICopyModInfo> outdatedFileNodes = outdatedMod.GetAllFileNodesAsICopyModInfo(); if (outdatedFileNodes.Count == 0) { Messenger.AddInfo("No files in outdated mod found!"); return(false); } // Get all files of the new mod List <ICopyModInfo> newModFileNodes = newMod.GetAllFileNodesAsICopyModInfo(); List <ICopyModInfo> matchingNewModFileNodes = new List <ICopyModInfo>(); if (newModFileNodes.Count == 0) { Messenger.AddInfo("No files in new mod found!"); return(false); } foreach (var file in outdatedFileNodes) { // Ignore mod folder cause it may contain version numbers var fullTreePath = file.GetFullTreePath().Remove(0, file.GetRoot().GetFullTreePath().Length); ModNode matchingNew = ModSelectionTreeModel.SearchNodeByPathNew(fullTreePath, newMod, '/'); if (matchingNew == null) { // ignore not matching old files continue; } if (newModFileNodes.Contains(matchingNew)) { newModFileNodes.Remove(matchingNew); } matchingNew.Destination = file.Destination; matchingNew.SetChecked(file.Checked, true); matchingNewModFileNodes.Add(matchingNew); // Copy infos for each parent up to root node. var parentNew = matchingNew.Parent as ModNode; var parentOld = file.GetParent(); while (parentNew != null && parentOld != null) { parentNew.Destination = parentOld.Destination; parentNew.SetChecked(parentOld.Checked || parentOld.HasCheckedChilds, true); parentNew = parentNew.Parent as ModNode; parentOld = parentOld.GetParent(); } } var unknownPaths = new List <ICopyModInfo>(); if (newModFileNodes.Count > 0) { unknownPaths = CheckForUnknownDestinationPaths(newModFileNodes, matchingNewModFileNodes, outdatedFileNodes); } if (unknownPaths.Count > 0) { Messenger.AddInfo("Invalid destination path found for:"); foreach (var file in unknownPaths) { Messenger.AddInfo(string.Format("File: {0}", file.Destination)); } Messenger.AddInfo("Manual update is required!"); return(false); } return(true); }