private async Task <HashSet <string> > GetChildrenRecursive(string file) { var files = new HashSet <string>(); files.Add(file); var baseChildren = await XivCache.GetChildFiles(file); if (baseChildren == null || baseChildren.Count == 0) { // No children, just us. return(files); } else { // We have child files. foreach (var child in baseChildren) { // Recursively get their children. var children = await GetChildrenRecursive(child); foreach (var subchild in children) { // Add the results to the list. files.Add(subchild); } } } return(files); }
public async Task AsyncInit() { var root = _item.GetRoot(); if (root == null) { return; } var gd = XivCache.GameInfo.GameDirectory; var lang = XivCache.GameInfo.GameLanguage; var df = IOUtil.GetDataFileFromPath(root.Info.GetRootFile()); var _index = new Index(gd); var _mtrl = new Mtrl(XivCache.GameInfo.GameDirectory); var _mdl = new Mdl(gd, df); var _imc = new Imc(gd); var raceRegex = new Regex("c([0-9]{4})[^b]"); ItemNameBox.Text = _item.Name; var setName = root.Info.GetBaseFileName(false); SetLabel.Text = "Set: " + setName; if (!String.IsNullOrWhiteSpace(root.Info.Slot)) { var niceSlot = Mdl.SlotAbbreviationDictionary.FirstOrDefault(x => x.Value == root.Info.Slot); if (niceSlot.Key != null) { SlotLabel.Text = "Slot: " + niceSlot.Key + " (" + root.Info.Slot + ")"; } else { SlotLabel.Text = "Slot: Unknown (" + root.Info.Slot + ")"; } } else { SlotLabel.Text = "Slot: --"; } var usesImc = Imc.UsesImc(_item); if (usesImc) { VariantLabel.Text = "Variant: " + _item.ModelInfo.ImcSubsetID; } else { VariantLabel.Text = "Variant: --"; } var mSet = await _imc.GetMaterialSetId(_item); if (mSet > 0) { MaterialSetLabel.Text = "Material Set: " + mSet; } else { MaterialSetLabel.Text = "Material Set: --"; } var races = XivRaces.PlayableRaces; var models = await root.GetModelFiles(); var materials = await root.GetMaterialFiles(mSet); #region Race Chart var rowIdx = 1; foreach (var race in races) { var rCode = race.GetRaceCode(); var row = new RowDefinition(); row.Height = new GridLength(30); RacialGrid.RowDefinitions.Add(row); var lBase = new Label(); lBase.Content = race.GetDisplayName(); lBase.SetValue(Grid.RowProperty, rowIdx); RacialGrid.Children.Add(lBase); XivRace?usedMdlRace = race; string usedMdl = null;; if (race != XivRace.All_Races) { // Check if the race has a model. var mdl = models.FirstOrDefault(x => x.Contains("c" + rCode)); if (mdl == null) { // Gotta see which race they're shared from. var node = XivRaceTree.GetNode(race); var parent = node.Parent; while (parent != null) { var code = parent.Race.GetRaceCode(); mdl = models.FirstOrDefault(x => x.Contains("c" + code)); if (mdl != null) { usedMdlRace = parent.Race; usedMdl = mdl; break; } parent = parent.Parent; } if (mdl == null) { // No model exists for this item. usedMdlRace = null; } } else { usedMdl = mdl; } } var mdlRaceString = "None"; if (usedMdlRace == race) { mdlRaceString = "Own"; } else { if (usedMdlRace != null) { mdlRaceString = ((XivRace)usedMdlRace).GetDisplayName(); } } XivRace?usedMtrlRace = usedMdlRace; if (race != XivRace.All_Races) { if (usedMdlRace == null) { usedMtrlRace = null; } else { // Get the materials used by this racial's model. var mdl = usedMdl; var mdlMaterials = await XivCache.GetChildFiles(mdl); var mtrl = mdlMaterials.FirstOrDefault(x => raceRegex.IsMatch(x)); if (mtrl == null) { usedMtrlRace = null; } else { var code = raceRegex.Match(mtrl).Groups[1].Value; usedMtrlRace = XivRaces.GetXivRace(code); if (usedMtrlRace == XivRace.All_Races) { usedMtrlRace = null; } } } } var mtrlRaceString = "None"; if (usedMtrlRace == race) { mtrlRaceString = "Own"; } else { if (usedMtrlRace != null) { mtrlRaceString = ((XivRace)usedMtrlRace).GetDisplayName(); } } var lMdl = new Label(); lMdl.Content = mdlRaceString; lMdl.SetValue(Grid.RowProperty, rowIdx); lMdl.SetValue(Grid.ColumnProperty, 1); RacialGrid.Children.Add(lMdl); var lMtrl = new Label(); lMtrl.Content = mtrlRaceString; lMtrl.SetValue(Grid.RowProperty, rowIdx); lMtrl.SetValue(Grid.ColumnProperty, 2); RacialGrid.Children.Add(lMtrl); rowIdx++; } #endregion if (Imc.UsesImc(_item) && _item.ModelInfo != null) { var myImcSubsetId = _item.ModelInfo.ImcSubsetID; var allItems = await root.GetAllItems(); var fInfo = await _imc.GetFullImcInfo(_item); var entries = fInfo.GetAllEntries(_item.GetItemSlotAbbreviation(), true); foreach (var item in allItems) { SameModelItems.Add(new KeyValuePair <string, IItem>(item.Name, item)); if (entries.Count > item.ModelInfo.ImcSubsetID) { var imSet = entries[item.ModelInfo.ImcSubsetID].MaterialSet; if (mSet == imSet) { SameMSetItems.Add(new KeyValuePair <string, IItem>(item.Name, item)); } } if (item.ModelInfo.ImcSubsetID == myImcSubsetId) { SameVariantItems.Add(new KeyValuePair <string, IItem>(item.Name, item)); } } } }
public async Task SetFile(string filePath) { await LockUi(); WarningLabel.Text = ""; _path = filePath; ChildFilesBox.Items.Clear(); ParentFilesBox.Items.Clear(); SiblingFilesBox.Items.Clear(); AffectedItemsBox.Items.Clear(); ModelLevelBox.Text = ""; MaterialLevelBox.Text = ""; FilePathLabel.Text = filePath; FileNameBox.Text = Path.GetFileName(filePath); var root = await XivCache.GetFirstRoot(filePath); if (root == null) { RootNameBox.Text = "NULL"; WarningLabel.Text = "File dependency information not supported for this item."; await UnlockUi(); return; } RootNameBox.Text = root.ToRawItem().Name; var ext = Path.GetExtension(filePath).Substring(1); var allItems = (await root.GetAllItems()); if (allItems.Count == 0) { WarningLabel.Text = "File dependency information not supported for this item."; await UnlockUi(); return; } if (root.Info.PrimaryType == XivItemType.human) { WarningLabel.Text = "Parent file references & affected items lists \n may not be complete for this file. \n (Unknown cross-references may exist.)"; } var orderedItems = allItems.OrderBy((x => x.Name), new ItemNameComparer()).ToList(); var modelItem = orderedItems[0]; ModelLevelBox.Text = modelItem.Name; var children = await XivCache.GetChildFiles(filePath); var parents = await XivCache.GetParentFiles(filePath); var siblings = await XivCache.GetSiblingFiles(filePath); foreach (var s in children) { ChildFilesBox.Items.Add(s); } foreach (var s in parents) { ParentFilesBox.Items.Add(s); } foreach (var s in siblings) { SiblingFilesBox.Items.Add(s); } Dictionary <XivDependencyRoot, HashSet <int> > mVariants = new Dictionary <XivDependencyRoot, HashSet <int> >(); var affectedItems = new List <IItem>(); if (ext == "tex") { foreach (var parent in parents) { // Each of our parents has a root... var pRoot = await XivCache.GetFirstRoot(parent); if (pRoot == null) { continue; } // And each of these files also has a material set id. var match = _extractVariant.Match(parent); var mVariant = 0; if (match.Success) { mVariant = Int32.Parse(match.Groups[1].Value); } if (!mVariants.ContainsKey(pRoot)) { mVariants.Add(pRoot, new HashSet <int>()); } mVariants[pRoot].Add(mVariant); var pItems = (await pRoot.GetAllItems()); } } else if (ext == "mtrl") { var match = _extractVariant.Match(filePath); var mVariant = 0; if (match.Success) { mVariant = Int32.Parse(match.Groups[1].Value); } if (!mVariants.ContainsKey(root)) { mVariants.Add(root, new HashSet <int>()); } mVariants[root].Add(mVariant); } else { foreach (var item in allItems) { affectedItems.Add(item); } MaterialLevelBox.Text = ""; } Dictionary <XivDependencyRoot, HashSet <int> > sharedImcSubsets = new Dictionary <XivDependencyRoot, HashSet <int> >(); var _imc = new Imc(XivCache.GameInfo.GameDirectory); try { // We now have a dictionary of <Root>, <Material Set Id> that comprises all of our referencing material sets. // We now need to convert that into a list of <root> => <Imc Subset IDs>, for all IMC subsets in that root which use our material ID. foreach (var kv in mVariants) { var rt = kv.Key; sharedImcSubsets.Add(rt, new HashSet <int>()); var imcPath = rt.GetRawImcFilePath(); var fullImcInfo = await _imc.GetFullImcInfo(imcPath); var setCount = fullImcInfo.SubsetCount + 1; for (int i = 0; i < setCount; i++) { var info = fullImcInfo.GetEntry(i, rt.Info.Slot); // This IMC subset references the one of our material sets. if (kv.Value.Contains(info.Variant)) { sharedImcSubsets[rt].Add(i); } } } // We now have a dictionary of <root>, <imc subset ids>. At this point, we can compare this to our original alll items list. var sh = allItems.Where(x => { var iRoot = x.GetRoot(); // The root must be one of our roots we care about. if (!sharedImcSubsets.ContainsKey(iRoot)) { return(false); } var imcs = sharedImcSubsets[iRoot]; // The imc subset must be in the imc subsets that use this material. if (!imcs.Contains(x.ModelInfo.ImcSubsetID)) { return(false); } return(true); }); foreach (var i in sh) { affectedItems.Add(i); } } catch { // The item doesn't have a valid IMC entry. In that case, it affects all items in the tree. affectedItems.AddRange(allItems); } if (affectedItems.Count == 0) { MaterialLevelBox.Text = "Unknown"; } else { if (ext == "tex" || ext == "mtrl") { var ordered = affectedItems.OrderBy((x => x.Name), new ItemNameComparer()).ToList(); MaterialLevelBox.Text = ordered[0].Name; } } foreach (var item in affectedItems) { AffectedItemsBox.Items.Add(item); } await UnlockUi(); }