/// <summary>
        /// Creates a new ItemMetaData entry from the constituent files around the FFXIV file system.
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        private static async Task <ItemMetadata> CreateFromRaw(XivDependencyRoot root, bool forceDefault = false)
        {
            var _eqp = new Eqp(XivCache.GameInfo.GameDirectory);
            var _imc = new Imc(XivCache.GameInfo.GameDirectory);

            // These functions generate the path::offset to each of our
            // contiguous metadata entries.
            var imcPaths = await root.GetImcEntryPaths();

            var ret = new ItemMetadata(root);

            if (imcPaths.Count > 0)
            {
                ret.ImcEntries = await _imc.GetEntries(imcPaths, forceDefault);
            }

            ret.EqpEntry = await _eqp.GetEqpEntry(root.Info, forceDefault);

            ret.EqdpEntries = await _eqp.GetEquipmentDeformationParameters(root.Info, forceDefault);

            ret.EstEntries = await Est.GetExtraSkeletonEntries(root, forceDefault);

            ret.GmpEntry = await _eqp.GetGimmickParameter(root, forceDefault);

            return(ret);
        }
Beispiel #2
0
        public async Task <List <IItemModel> > GetSameVariantList(IItemModel item)
        {
            var sameModelItems = new List <IItemModel>();

            if (!item.PrimaryCategory.Equals(XivStrings.Gear))

            {
                sameModelItems.Add((IItemModel)item.Clone());
                return(sameModelItems);
            }
            sameModelItems = await GetSameModelList(item);

            var imc          = new Imc(_gameDirectory, XivDataFile._04_Chara);
            var originalInfo = await imc.GetImcInfo(item);

            var sameMaterialItems = new List <IItemModel>();

            foreach (var i in sameModelItems)
            {
                var info = await imc.GetImcInfo(i);

                if (info.Variant == originalInfo.Variant)
                {
                    sameMaterialItems.Add(i);
                }
            }

            return(sameMaterialItems);
        }
Beispiel #3
0
        public Imc Post(Imc values)
        {
            Imc imcCalc = values;

            imcCalc.ImcValue = imcCalc.Weight / (imcCalc.Height * imcCalc.Height);
            return(imcCalc);
        }
Beispiel #4
0
        public async Task <Dictionary <string, char[]> > GetDemiHumanMountTextureEquipPartList(IItemModel itemModel)
        {
            var parts = new[] { 'a', 'b', 'c', 'd', 'e', 'f' };

            var equipPartDictionary = new Dictionary <string, char[]>();

            var index   = new Index(_gameDirectory);
            var imc     = new Imc(_gameDirectory, XivDataFile._04_Chara);
            var version = (await imc.GetImcInfo(itemModel, itemModel.ModelInfo)).Version.ToString().PadLeft(4, '0');

            var id      = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0');

            var mtrlFolder = $"chara/demihuman/d{id}/obj/equipment/e{bodyVer}/material/v{version}";

            var files = await index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), XivDataFile._04_Chara);

            foreach (var slotAbr in SlotAbbreviationDictionary)
            {
                var charList =
                    (from part in parts
                     let mtrlFile = $"mt_d{id}e{bodyVer}_{slotAbr.Value}_{part}.mtrl"
                                    where files.Contains(HashGenerator.GetHash(mtrlFile))
                                    select part).ToList();

                if (charList.Count > 0)
                {
                    equipPartDictionary.Add(slotAbr.Key, charList.ToArray());
                }
            }

            return(equipPartDictionary);
        }
        private async Task LoadItems()
        {
            List <string> children = new List <string>();
            var           root     = _item.GetRoot();

            if (root != null)
            {
                if (_level == XivDependencyLevel.Model)
                {
                    children = await root.GetModelFiles();
                }
                else if (_level == XivDependencyLevel.Material)
                {
                    var imc = new Imc(XivCache.GameInfo.GameDirectory);
                    try
                    {
                        var entry = await imc.GetImcInfo((IItemModel)_item);

                        children = await root.GetMaterialFiles(entry.Variant);
                    } catch
                    {
                        children = await root.GetMaterialFiles(0);
                    }
                }
                else if (_level == XivDependencyLevel.Texture)
                {
                    try
                    {
                        var imc   = new Imc(XivCache.GameInfo.GameDirectory);
                        var entry = await imc.GetImcInfo((IItemModel)_item);

                        children = await root.GetTextureFiles(entry.Variant);
                    }
                    catch
                    {
                        children = await root.GetTextureFiles(0);
                    }
                }
                else
                {
                    // Invalid or root, nothing listed.
                }
            }

            var index = new Index(XivCache.GameInfo.GameDirectory);

            foreach (var file in children)
            {
                var exists = await index.FileExists(file);

                if (!exists)
                {
                    continue;
                }

                Files.Add(new FileEntry(file));
            }
        }
        public Imc CalcIMC(double weight, double height, string name)
        {
            var result = GetImc(weight, height);

            Imc objectImc = new Imc()
            {
                ImcValue = result,
                Text     = $"{name}, your IMC is: {result}"
            };

            return(objectImc);
        }
Beispiel #7
0
        /// <summary>
        /// Gets the avfx path
        /// </summary>
        /// <param name="itemModel">The item to get the avfx path for</param>
        /// <param name="itemType">The type of the item</param>
        /// <returns>A tuple containing the path folder and file</returns>
        public static async Task <(string Folder, string File)> GetVfxPath(IItemModel itemModel)
        {
            // get the vfx version from the imc file
            var imc     = new Imc(XivCache.GameInfo.GameDirectory);
            var imcInfo = await imc.GetImcInfo(itemModel);

            int vfx = imcInfo.Vfx;

            var root = itemModel.GetRootInfo();

            return(await GetVfxPath(root, vfx));
        }
Beispiel #8
0
 public SituationImcNameHelper(double imc)
 {
     Resposta = imc switch
     {
         (< 18.5) => Imc.AbaixoDoPeso,
         (< 25) => Imc.PesoNormal,
         (< 30) => Imc.Sobrepeso,
         (< 35) => Imc.ObesidadeGrau1,
         (< 40) => Imc.ObesidadeGrau2,
         _ => Imc.ObesidadeGrau3
     };
 }
        /// <summary>
        /// Deserializes the binary IMC data into a list of IMC entries.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static List <XivImc> DeserializeImcData(byte[] data, XivDependencyRoot root, uint dataVersion)
        {
            const int ImcSubEntrySize = 6;
            var       entries         = data.Length / ImcSubEntrySize;

            List <XivImc> ret = new List <XivImc>();

            for (int i = 0; i < entries; i++)
            {
                var entryData = data.Skip(i * ImcSubEntrySize).Take(ImcSubEntrySize).ToArray();
                ret.Add(Imc.DeserializeEntry(entryData));
            }

            return(ret);
        }
        public async Task ShowConversionStats()
        {
            if (!DestinationOk(Destination))
            {
                return;
            }

            var imc = new Imc(XivCache.GameInfo.GameDirectory);


            SourceBox.Text      = Source.Info.GetBaseFileName() + " (" + SourceItem.Name + ")";
            DestinationBox.Text = Destination.Info.GetBaseFileName() + " (" + DestinationItem.Name + ")";

            if (Imc.UsesImc(Source))
            {
                try
                {
                    var sourceInfo = await imc.GetFullImcInfo(Source.GetRawImcFilePath());

                    var destInfo = await imc.GetFullImcInfo(Destination.GetRawImcFilePath());

                    SourceVariantsBox.Text      = (sourceInfo.SubsetCount + 1).ToString();
                    DestinationVariantsBox.Text = (destInfo.SubsetCount + 1).ToString();
                    SameVariantBox.IsEnabled    = true;
                    SameVariantBox.IsChecked    = true;
                }
                catch
                {
                    SameVariantBox.IsEnabled = true;
                    SameVariantBox.IsChecked = true;
                }
            }
            else
            {
                SameVariantBox.IsEnabled    = false;
                SameVariantBox.IsChecked    = false;
                SourceVariantsBox.Text      = "1";
                DestinationVariantsBox.Text = "1";
            }

            var items = await Destination.GetAllItems();

            AffectedItemsBox.Items.Clear();
            foreach (var item in items)
            {
                AffectedItemsBox.Items.Add(item.Name);
            }
        }
        /// <summary>
        /// Serializes the IMC data entries for the given meta file.
        /// </summary>
        /// <param name="meta"></param>
        /// <returns></returns>
        private static byte[] SerializeImcData(ItemMetadata meta)
        {
            // IMC Serialization is pretty straight forward, it's just
            // write the binary data from the IMC entries in sequence.

            // IMC entries are a static 6 bytes long, and ordered in simple
            // straight consecutive order, so our index order matches subeset ID.

            List <byte> bytes = new List <byte>();

            foreach (var entry in meta.ImcEntries)
            {
                bytes.AddRange(Imc.SerializeEntry(entry));
            }

            return(bytes.ToArray());
        }
Beispiel #12
0
        /// <summary>
        /// Gets the avfx path
        /// </summary>
        /// <param name="itemModel">The item to get the avfx path for</param>
        /// <param name="itemType">The type of the item</param>
        /// <returns>A tuple containing the path folder and file</returns>
        private async Task <(string Folder, string File)> GetVfxPath(IItemModel itemModel, XivItemType itemType)
        {
            // get the vfx version from the imc file
            var imc     = new Imc(_modding, _dataFile);
            var imcInfo = await imc.GetImcInfo(itemModel, itemModel.ModelInfo);

            int vfx = imcInfo.Vfx;

            var id      = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0');

            string vfxFolder, vfxFile;

            switch (itemType)
            {
            case XivItemType.equipment:
                vfxFolder = $"chara/{itemType}/e{id}/vfx/eff";
                vfxFile   = $"ve{vfx.ToString().PadLeft(4, '0')}.avfx";
                break;

            case XivItemType.weapon:
                vfxFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/vfx/eff";
                vfxFile   = $"vw{vfx.ToString().PadLeft(4, '0')}.avfx";
                break;

            case XivItemType.monster:
                vfxFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/vfx/eff";
                vfxFile   = $"vm{vfx.ToString().PadLeft(4, '0')}.avfx";
                break;

            case XivItemType.demihuman:
                vfxFolder = $"chara/{itemType}/d{id}/obj/equipment/e{bodyVer}/vfx/eff";
                vfxFile   = $"ve{vfx.ToString().PadLeft(4, '0')}.avfx";
                break;

            default:
                vfxFolder = "";
                vfxFile   = "";
                break;
            }

            return(vfxFolder, vfxFile);
        }
Beispiel #13
0
        /// <summary>
        /// Gets the mtrl path for a given item
        /// </summary>
        /// <param name="itemModel">Item that contains model data</param>
        /// <param name="xivRace">The race for the requested data</param>
        /// <param name="part">The mtrl part <see cref="GearInfo.GetPartList(IItemModel, XivRace)"/></param>
        /// <param name="itemType">The type of the item</param>
        /// <returns>A tuple containing the mtrl folder and file, and whether it has a vfx</returns>
        private (string Folder, string File, bool HasVfx) GetMtrlPath(IItemModel itemModel, XivRace xivRace, char part, XivItemType itemType)
        {
            // The default version number
            var version = "0001";

            var hasVfx = false;

            if (itemType != XivItemType.human && itemType != XivItemType.furniture)
            {
                // get the items version from the imc file
                var imc     = new Imc(_gameDirectory, _dataFile);
                var imcInfo = imc.GetImcInfo(itemModel, itemModel.ModelInfo);
                version = imcInfo.Version.ToString().PadLeft(4, '0');

                if (imcInfo.Vfx > 0)
                {
                    hasVfx = true;
                }
            }

            var id      = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0');
            var race    = xivRace.GetRaceCode();

            string mtrlFolder = "", mtrlFile = "";

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}e{id}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_{part}{MtrlExtension}";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}a{id}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_{part}{MtrlExtension}";
                break;

            case XivItemType.weapon:
                mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_w{id}b{bodyVer}_{part}{MtrlExtension}";
                break;

            case XivItemType.monster:
                mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_m{id}b{bodyVer}_{part}{MtrlExtension}";
                break;

            case XivItemType.demihuman:
                mtrlFolder = $"chara/{itemType}/d{id}/obj/equipment/e{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_d{id}e{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemSubCategory]}_{part}{MtrlExtension}";
                break;

            case XivItemType.human:
                if (itemModel.ItemCategory.Equals(XivStrings.Body))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/body/b{bodyVer}/material";
                    mtrlFile   = $"mt_c{race}b{bodyVer}_{part}{MtrlExtension}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Hair))
                {
                    // Hair has a version number, but no IMC, so we leave it at the default 0001
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/hair/h{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{race}h{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemSubCategory]}_{part}{MtrlExtension}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Face))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/face/f{bodyVer}/material";
                    mtrlFile   = $"mt_c{race}f{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemSubCategory]}_{part}{MtrlExtension}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Tail))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/tail/t{bodyVer}/material";
                    mtrlFile   = $"mt_c{race}t{bodyVer}_{part}{MtrlExtension}";
                }
                break;

            case XivItemType.furniture:
                if (itemModel.ItemCategory.Equals(XivStrings.Furniture_Indoor))
                {
                    mtrlFolder = $"bgcommon/hou/indoor/general/{id}/material";
                    mtrlFile   = $"fun_b0_m{id}_0{part}{MtrlExtension}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Furniture_Outdoor))
                {
                    mtrlFolder = $"bgcommon/hou/outdoor/general/{id}/material";
                    mtrlFile   = $"gar_b0_m{id}_0{part}{MtrlExtension}";
                }
                break;

            default:
                mtrlFolder = "";
                mtrlFile   = "";
                break;
            }

            return(mtrlFolder, mtrlFile, hasVfx);
        }
Beispiel #14
0
        private void ItemList_ItemSelected(object sender, IItem item)
        {
            if (item == null)
            {
                return;
            }

            SelectedItem = item;

            var root = item.GetRoot();

            TextureMapComboBox.Items.Clear();
            ModelTypeComboBox.Items.Clear();
            MaterialComboBox.Items.Clear();

            if (OptionList.SelectedItem == null)
            {
                return;
            }


            var modding = new Modding(_gameDirectory);
            //var modList = modding.GetModList();
            var _imc = new Imc(_gameDirectory);

            int    mSet         = -1;
            string metadataFile = null;
            var    models       = new List <string>();
            var    materials    = new List <string>();
            var    textures     = new List <string>();

            Task.Run(async() =>
            {
                if (root != null)
                {
                    // Get ALL THE THINGS
                    // Meta Entries, Models, Materials, Textures, Icons, and VFX Elements.
                    var im = (IItemModel)item;
                    var df = IOUtil.GetDataFileFromPath(root.Info.GetRootFile());

                    metadataFile = root.Info.GetRootFile();
                    mSet         = await _imc.GetMaterialSetId(im);
                    models       = await root.GetModelFiles();
                    materials    = await root.GetMaterialFiles(mSet);
                    textures     = await root.GetTextureFiles(mSet);

                    var _tex  = new Tex(XivCache.GameInfo.GameDirectory);
                    var icons = await _tex.GetItemIcons(im);

                    foreach (var icon in icons)
                    {
                        textures.Add(icon.Path);
                    }

                    var _atex = new ATex(XivCache.GameInfo.GameDirectory, df);
                    var paths = await _atex.GetAtexPaths(im);
                    foreach (var path in paths)
                    {
                        textures.Add(path.Path);
                    }
                }
                else
                {
                    if (item.GetType() == typeof(XivCharacter))
                    {
                        // Face Paint/Equipment Decals jank-items.  Ugh.
                        if (item.SecondaryCategory == XivStrings.Face_Paint)
                        {
                            var _character = new Character(XivCache.GameInfo.GameDirectory, XivCache.GameInfo.GameLanguage);

                            var paths = await _character.GetDecalPaths(Character.XivDecalType.FacePaint);

                            foreach (var path in paths)
                            {
                                textures.Add(path);
                            }
                        }
                        else if (item.SecondaryCategory == XivStrings.Equipment_Decals)
                        {
                            var _character = new Character(XivCache.GameInfo.GameDirectory, XivCache.GameInfo.GameLanguage);
                            var paths      = await _character.GetDecalPaths(Character.XivDecalType.Equipment);
                            foreach (var path in paths)
                            {
                                textures.Add(path);
                            }
                        }
                    }
                    else
                    {
                        // This is a UI item or otherwise an item which has no root, and only has textures.
                        var uiItem = (XivUi)item;
                        var paths  = await uiItem.GetTexPaths();
                        foreach (var kv in paths)
                        {
                            textures.Add(kv.Value);
                        }
                    }
                }
            }).Wait();

            MetadataPathBox.Text = metadataFile;

            foreach (var file in models)
            {
                var fe = new FileEntry();
                fe.Path = file;
                fe.Name = MakeFriendlyFileName(file);

                ModelTypeComboBox.Items.Add(fe);
            }

            foreach (var file in materials)
            {
                var fe = new FileEntry();
                fe.Path = file;
                fe.Name = MakeFriendlyFileName(file);

                MaterialComboBox.Items.Add(fe);
            }

            foreach (var file in textures)
            {
                var fe = new FileEntry();
                fe.Path = file;
                fe.Name = MakeFriendlyFileName(file);

                TextureMapComboBox.Items.Add(fe);
            }

            if (String.IsNullOrEmpty(metadataFile))
            {
                AddMetadataButton.IsEnabled = false;
            }
            else
            {
                AddMetadataButton.IsEnabled = true;
            }

            if (TextureMapComboBox.Items.Count > 0)
            {
                AddCurrentTextureButton.IsEnabled = true;
                AddCustomTextureButton.IsEnabled  = true;
                TextureMapComboBox.SelectedIndex  = 0;
            }
            else
            {
                AddCurrentTextureButton.IsEnabled = false;
                AddCustomTextureButton.IsEnabled  = false;
            }

            if (ModelTypeComboBox.Items.Count > 0)
            {
                AddCurrentModelButton.IsEnabled = true;
                AdvOptionsButton.IsEnabled      = true;
                ModelTypeComboBox.SelectedIndex = 0;
            }
            else
            {
                AddCurrentModelButton.IsEnabled = false;
                AdvOptionsButton.IsEnabled      = false;
            }

            if (MaterialComboBox.Items.Count > 0)
            {
                AddCurrentMaterialButton.IsEnabled = true;
                MaterialComboBox.SelectedIndex     = 0;
            }
            else
            {
                AddCurrentMaterialButton.IsEnabled = false;
            }

            SelectModGroup.IsEnabled = true;
        }
Beispiel #15
0
        public async Task DisableMod()
        {
            _view.SaveButton.IsEnabled    = false;
            _view.CancelButton.IsEnabled  = false;
            _view.DisableButton.IsEnabled = false;
            _view.DisableButton.Content   = UIStrings.Working_Ellipsis;
            var files = new HashSet <string>();

            var root = _item.GetRoot();

            if (root == null || !Imc.UsesImc(root))
            {
                // This is the only copy of the material we know how to find.
                files.Add(_material.MTRLPath);
            }
            else
            {
                var imc  = new Imc(XivCache.GameInfo.GameDirectory);
                var info = await imc.GetFullImcInfo(_item);

                var entries      = info.GetAllEntries(root.Info.Slot);
                var materialSets = entries.Select(x => x.MaterialSet).ToHashSet();

                var extract = new Regex("(v[0-9]{4})");
                var rep     = extract.Match(_material.MTRLPath).Groups[1].Value;

                // Remove the material in all of the referenced material sets.
                foreach (var setId in materialSets)
                {
                    var newPath = _material.MTRLPath.Replace(rep, "v" + setId.ToString().PadLeft(4, '0'));
                    files.Add(newPath);
                }
            }

            try
            {
                foreach (var file in files)
                {
                    var modEntry = await _modding.TryGetModEntry(file);

                    if (modEntry == null)
                    {
                        continue;
                    }

                    // If the file is a custom addition, and not a modification.
                    if (modEntry.IsCustomFile())
                    {
                        await _modding.DeleteMod(file);
                    }
                    else
                    {
                        await _modding.ToggleModStatus(file, false);
                    }
                }
            } catch (Exception ex)
            {
                FlexibleMessageBox.Show("Unable to delete Mod.\n\nError: " + ex.Message, "Mod Delete Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            _view.Close(false);
        }
Beispiel #16
0
        /// <summary>
        /// Gets the available races that contain texture data for the given gear
        /// </summary>
        /// <remarks>
        /// This checks to see if the mtrl file for each race exists in the mtrl folder
        /// It creates a list of the races which do have an available mtrl folder
        /// </remarks>
        /// <param name="xivGear">A gear item</param>
        /// <returns>A list of XivRace data</returns>
        public async Task <List <XivRace> > GetRacesForTextures(XivGear xivGear, XivDataFile dataFile)
        {
            // Get the material version for the item from the imc file
            var imc         = new Imc(_gameDirectory);
            var gearVersion = (await imc.GetImcInfo(xivGear)).Variant.ToString().PadLeft(4, '0');

            var modelID = xivGear.ModelInfo.PrimaryID.ToString().PadLeft(4, '0');

            var raceList = new List <XivRace>();

            var    itemType = ItemType.GetPrimaryItemType(xivGear);
            string mtrlFolder;

            if (itemType == XivItemType.weapon)
            {
                return(new List <XivRace> {
                    XivRace.All_Races
                });
            }

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{modelID}/material/v{gearVersion}";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{modelID}/material/v{gearVersion}";
                break;

            default:
                mtrlFolder = "";
                break;
            }

            var testFilesDictionary = new Dictionary <int, string>();

            // loop through each race ID to create a dictionary containing [Hashed file name, race ID]
            foreach (var ID in IDRaceDictionary.Keys)
            {
                string mtrlFile;

                switch (itemType)
                {
                case XivItemType.equipment:
                    mtrlFile = $"mt_c{ID}e{modelID}_{xivGear.GetItemSlotAbbreviation()}_a.mtrl";
                    break;

                case XivItemType.accessory:
                    mtrlFile = $"mt_c{ID}a{modelID}_{xivGear.GetItemSlotAbbreviation()}_a.mtrl";
                    break;

                default:
                    mtrlFile = "";
                    break;
                }

                testFilesDictionary.Add(HashGenerator.GetHash(mtrlFile), ID);
            }

            // get the list of hashed file names from the mtrl folder
            var files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile);

            // Loop through each entry in the dictionary
            foreach (var testFile in testFilesDictionary)
            {
                // if the file in the dictionary entry is contained in the list of files from the folder
                // add that race to the race list
                if (files.Contains(testFile.Key))
                {
                    raceList.Add(IDRaceDictionary[testFile.Value]);
                }
            }

            return(raceList);
        }
        /// <summary>
        /// Exports the model
        /// </summary>
        /// <param name="fullModelName">The name chosen by the user for the full model export</param>
        private async Task Export(string fullModelName)
        {
            var pc = await this.ShowProgressAsync(UIMessages.ExportingFullModelTitle, UIMessages.PleaseStandByMessage);

            var fileFormat     = "fbx";
            var savePath       = new DirectoryInfo(Settings.Default.Save_Directory);
            var outputFilePath = $"{savePath}\\FullModel\\{fullModelName}\\{fullModelName}.{fileFormat}";

            // Create output directory
            Directory.CreateDirectory($"{savePath}\\FullModel\\{fullModelName}");

            var fmViewPortVM = viewport3DX.DataContext as FullModelViewport3DViewModel;

            var converterFolder = Directory.GetCurrentDirectory() + "\\converters\\" + fileFormat;

            Directory.CreateDirectory(converterFolder);
            var dbPath = converterFolder + "\\input.db";

            File.Delete(dbPath);

            // Create the DB where all models will be added and fill the metadata
            fmViewPortVM.shownModels.FirstOrDefault().Value.TtModel.SetFullModelDBMetaData(dbPath, fullModelName);

            // Export the materials for each model and save model to DB
            foreach (var model in fmViewPortVM.shownModels)
            {
                var mtrlVariant = 1;
                try
                {
                    var imc = new Imc(_gameDirectory);
                    mtrlVariant = (await imc.GetImcInfo(model.Value.ItemModel)).MaterialSet;
                }
                catch (Exception ex)
                {
                    // No-op, defaulted to 1.
                }

                await Mdl.ExportMaterialsForModel(model.Value.TtModel, outputFilePath, _gameDirectory, mtrlVariant, _fmvm.SelectedSkeleton.XivRace);

                // Save model to DB
            }

            TTModel.SaveFullToFile(dbPath, _fmvm.SelectedSkeleton.XivRace, fmViewPortVM.shownModels.Select(x => x.Value.TtModel).ToList());

            var proc = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName  = converterFolder + "\\converter.exe",
                    Arguments = "\"" + dbPath + "\"",
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    UseShellExecute        = false,
                    WorkingDirectory       = "" + converterFolder + "",
                    CreateNoWindow         = true
                }
            };

            proc.Start();
            proc.WaitForExit();
            var code = proc.ExitCode;

            if (code != 0)
            {
                throw new Exception("Exporter threw error code: " + proc.ExitCode);
            }

            var outputFile = converterFolder + "\\result." + fileFormat;

            // Just move the result file if we need to.
            if (!Path.Equals(outputFilePath, outputFile))
            {
                File.Delete(outputFilePath);
                File.Move(outputFile, outputFilePath);
            }

            await pc.CloseAsync();

            await this.ShowMessageAsync(UIMessages.FullModelExportSuccessTitle, string.Format(UIMessages.FullModelExportSuccessMessage, outputFilePath));
        }
        /// <summary>
        /// Applies multiple metadata mods simultaneously for performance gains.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="index"></param>
        /// <param name="modlist"></param>
        /// <returns></returns>
        internal static async Task ApplyMetadataBatched(List <ItemMetadata> data, IndexFile index, ModList modlist, bool save = true)
        {
            if (data == null || data.Count == 0)
            {
                return;
            }

            var _eqp     = new Eqp(XivCache.GameInfo.GameDirectory);
            var _modding = new Modding(XivCache.GameInfo.GameDirectory);
            var _index   = new Index(XivCache.GameInfo.GameDirectory);

            var dummyItem = new XivGenericItemModel();

            dummyItem.Name = Constants.InternalModSourceName;
            dummyItem.SecondaryCategory = Constants.InternalModSourceName;

            Dictionary <XivRace, List <(uint PrimaryId, string Slot, EquipmentDeformationParameter Entry)> > eqdpEntries = new Dictionary <XivRace, List <(uint PrimaryId, string Slot, EquipmentDeformationParameter Entry)> >();
            Dictionary <Est.EstType, List <ExtraSkeletonEntry> > estEntries = new Dictionary <Est.EstType, List <ExtraSkeletonEntry> >();
            List <(uint PrimaryId, EquipmentParameter EqpData)>  eqpEntries = new List <(uint PrimaryId, EquipmentParameter EqpData)>();
            List <(uint PrimaryId, GimmickParameter GmpData)>    gmpEntries = new List <(uint PrimaryId, GimmickParameter GmpData)>();

            foreach (var meta in data)
            {
                // Construct the parameter collections for each function call.
                foreach (var kv in meta.EqdpEntries)
                {
                    if (!eqdpEntries.ContainsKey(kv.Key))
                    {
                        eqdpEntries.Add(kv.Key, new List <(uint PrimaryId, string Slot, EquipmentDeformationParameter Entry)>());
                    }

                    eqdpEntries[kv.Key].Add(((uint)meta.Root.Info.PrimaryId, meta.Root.Info.Slot, kv.Value));
                }

                var estType = Est.GetEstType(meta.Root);
                foreach (var kv in meta.EstEntries)
                {
                    if (!estEntries.ContainsKey(estType))
                    {
                        estEntries.Add(estType, new List <ExtraSkeletonEntry>());
                    }

                    estEntries[estType].Add(kv.Value);
                }

                if (meta.EqpEntry != null)
                {
                    eqpEntries.Add(((uint)meta.Root.Info.PrimaryId, meta.EqpEntry));
                }

                if (meta.GmpEntry != null)
                {
                    gmpEntries.Add(((uint)meta.Root.Info.PrimaryId, meta.GmpEntry));
                }
            }


            if (index.DataFile == XivDataFile._04_Chara)
            {
                // Batch install functions for these three.
                await _eqp.SaveEqpEntries(eqpEntries, dummyItem, index, modlist);

                await _eqp.SaveEqdpEntries(eqdpEntries, dummyItem, index, modlist);

                await _eqp.SaveGmpEntries(gmpEntries, dummyItem, index, modlist);

                // The EST function already does batch applications by nature of how it works,
                // so just call it once for each of the four EST types represented.
                foreach (var kv in estEntries)
                {
                    await Est.SaveExtraSkeletonEntries(kv.Key, kv.Value, dummyItem, index, modlist);
                }
            }


            // IMC Files don't really overlap that often, so it's
            // not a significant loss generally to just write them individually.
            foreach (var meta in data)
            {
                if (meta.ImcEntries.Count > 0)
                {
                    var _imc    = new Imc(XivCache.GameInfo.GameDirectory);
                    var imcPath = meta.Root.GetRawImcFilePath();
                    await _imc.SaveEntries(imcPath, meta.Root.Info.Slot, meta.ImcEntries, null, index, modlist);
                }
            }

            if (save)
            {
                await _index.SaveIndexFile(index);

                await _modding.SaveModListAsync(modlist);
            }
        }
 public static void CadastrarImc(Imc p)
 {
     ctx.TAB_IMC.Add(p);
     ctx.SaveChanges();
 }
Beispiel #20
0
        /// <summary>
        /// Gets the mtrl folder for a given item
        /// </summary>
        /// <param name="itemModel">Item that contains model data</param>
        /// <param name="xivRace">The race for the requested data</param>
        /// <param name="itemType">The type of the item</param>
        /// <returns>The mtrl Folder</returns>
        private string GetMtrlFolder(IItemModel itemModel, XivRace xivRace, XivItemType itemType)
        {
            // The default version number
            var version = "0001";

            if (itemType != XivItemType.human && itemType != XivItemType.furniture)
            {
                // get the items version from the imc file
                var imc     = new Imc(_gameDirectory, _dataFile);
                var imcInfo = imc.GetImcInfo(itemModel, itemModel.ModelInfo);
                version = imcInfo.Version.ToString().PadLeft(4, '0');
            }

            if (version.Equals("0000"))
            {
                version = "0001";
            }

            var id      = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0');
            var race    = xivRace.GetRaceCode();

            var mtrlFolder = "";

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}";
                break;

            case XivItemType.weapon:
                mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}";
                break;

            case XivItemType.monster:
                mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}";
                break;

            case XivItemType.demihuman:
                mtrlFolder = $"chara/{itemType}/d{id}/obj/equipment/e{bodyVer}/material/v{version}";
                break;

            case XivItemType.human:
                if (itemModel.ItemCategory.Equals(XivStrings.Body))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/body/b{bodyVer}/material";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Hair))
                {
                    // Hair has a version number, but no IMC, so we leave it at the default 0001
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/hair/h{bodyVer}/material/v{version}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Face))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/face/f{bodyVer}/material";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Tail))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/tail/t{bodyVer}/material";
                }
                break;

            case XivItemType.furniture:
                if (itemModel.ItemCategory.Equals(XivStrings.Furniture_Indoor))
                {
                    mtrlFolder = $"bgcommon/hou/indoor/general/{id}/material";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Furniture_Outdoor))
                {
                    mtrlFolder = $"bgcommon/hou/outdoor/general/{id}/material";
                }
                break;

            default:
                mtrlFolder = "";
                break;
            }

            return(mtrlFolder);
        }
Beispiel #21
0
        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();
        }
        /// <summary>
        /// Updates the View/ViewModel with a new selected base item.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public async Task <bool> SetItem(IItem item, MainWindow mainWindow = null)
        {
            var gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory);

            _imc  = new Imc(gameDirectory, item.DataFile);
            _gear = new Gear(gameDirectory, XivLanguages.GetXivLanguage(Properties.Settings.Default.Application_Language));

            if (mainWindow != null)
            {
                _mainWindow = mainWindow;
            }
            _item = item;
            _tree.Items.Clear();
            IItemModel im = null;

            try
            {
                im = (IItemModel)item;
            } catch (Exception ex)
            {
                return(false);
            }

            if (im == null || im.ModelInfo == null)
            {
                return(false);
            }

            var topLevelItem = new TreeViewItem();

            topLevelItem.Header = "";
            if (im.ModelInfo.PrimaryID > 0)
            {
                topLevelItem.Header += CapFirst(item.GetPrimaryItemType().ToString()) + " #" + im.ModelInfo.PrimaryID.ToString().PadLeft(4, '0');
            }
            else
            {
                topLevelItem.Header += CapFirst(item.GetPrimaryItemType().ToString());
            }
            _tree.Items.Add(topLevelItem);


            var nextParent = topLevelItem;

            if (im.ModelInfo.SecondaryID > 0)
            {
                var nextNode = new TreeViewItem();
                nextNode.Header += CapFirst(item.GetSecondaryItemType().ToString()) + " #" + im.ModelInfo.SecondaryID.ToString().PadLeft(4, '0');
                nextParent.Items.Add(nextNode);
                nextParent.IsExpanded = true;
                nextParent            = nextNode;
            }

            var abbreviation = _item.GetItemSlotAbbreviation();

            if (abbreviation != "")
            {
                var nextNode = new TreeViewItem();
                nextNode.Header = Mdl.SlotAbbreviationDictionary.First(x => x.Value == abbreviation).Key;
                nextParent.Items.Add(nextNode);
                nextParent.IsExpanded = true;
                nextParent            = nextNode;
            }

            FullImcInfo fullInfo = null;

            try
            {
                fullInfo = await _imc.GetFullImcInfo(im);
            } catch (Exception ex)
            {
                // This item has no IMC file.
                var nextNode = new TreeViewItem();
                nextNode.Header      = im.Name;
                nextNode.DataContext = im;
                //nextNode.MouseDoubleClick += ItemNode_Activated;
                nextParent.Items.Add(nextNode);
                nextParent.IsExpanded = true;
                nextNode.IsSelected   = true;
                nextParent            = nextNode;

                // No shared items for things without IMC files, so just hide the view entirely?
                return(false);
            }
            var sharedList = await _gear.GetSameModelList(im);

            var myVariantNumber = fullInfo.GetEntry(im.ModelInfo.ImcSubsetID, im.GetItemSlotAbbreviation()).Variant;
            var myImcNumber     = im.ModelInfo.ImcSubsetID;

            var materialVariantHeaders = new Dictionary <int, TreeViewItem>();
            var imcVariantHeaders      = new Dictionary <int, TreeViewItem>();

            // TODO -
            // Add the Variant header nodes at the start, and only scan the IMC files when a

            TreeViewItem myMaterialHeader = null;
            TreeViewItem myImcHeader      = null;
            TreeViewItem myNode           = null;

            foreach (var i in sharedList)
            {
                // Get the Variant # information
                var info = fullInfo.GetEntry(i.ModelInfo.ImcSubsetID, i.GetItemSlotAbbreviation());
                if (info == null)
                {
                    // Invalid IMC Set ID for the item.
                    continue;
                }

                if (!materialVariantHeaders.ContainsKey(info.Variant))
                {
                    materialVariantHeaders.Add(info.Variant, new TreeViewItem());
                    materialVariantHeaders[info.Variant].Header      = "Material Variant #" + info.Variant;
                    materialVariantHeaders[info.Variant].DataContext = info.Variant;
                }

                if (!imcVariantHeaders.ContainsKey(i.ModelInfo.ImcSubsetID))
                {
                    imcVariantHeaders.Add(i.ModelInfo.ImcSubsetID, new TreeViewItem());
                    imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header      = "IMC Variant #" + i.ModelInfo.ImcSubsetID;
                    imcVariantHeaders[i.ModelInfo.ImcSubsetID].DataContext = i.ModelInfo.ImcSubsetID;

                    var hiddenParts = MaskToHidenParts(info.Mask);
                    imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += " - Hidden Parts: ";

                    if (hiddenParts.Count > 0)
                    {
                        imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += String.Join(",", hiddenParts);
                    }
                    else
                    {
                        imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += "None";
                    }

                    materialVariantHeaders[info.Variant].Items.Add(imcVariantHeaders[i.ModelInfo.ImcSubsetID]);

                    if (i.ModelInfo.ImcSubsetID == myImcNumber)
                    {
                        myImcHeader = imcVariantHeaders[i.ModelInfo.ImcSubsetID];
                    }
                }

                var nextNode = new TreeViewItem();
                nextNode.Header = i.Name;


                nextNode.DataContext = i;
                imcVariantHeaders[i.ModelInfo.ImcSubsetID].Items.Add(nextNode);


                if (myMaterialHeader == null && info.Variant == myVariantNumber)
                {
                    myMaterialHeader = materialVariantHeaders[info.Variant];
                }

                if (i.Name == im.Name)
                {
                    myNode = nextNode;
                }
                else
                {
                    nextNode.MouseDoubleClick += ItemNode_Activated;
                }
            }

            var ordered = materialVariantHeaders.OrderBy(x => x.Key);

            foreach (var kv in ordered)
            {
                nextParent.Items.Add(kv.Value);
            }
            nextParent.IsExpanded = true;

            if (myMaterialHeader != null)
            {
                myMaterialHeader.IsExpanded = true;
            }
            if (myImcHeader != null)
            {
                myImcHeader.IsExpanded = true;
            }
            if (myNode != null)
            {
                myNode.IsSelected = true;
            }

            return(true);
        }
Beispiel #23
0
        /// <summary>
        /// Gets the list of available mtrl parts for a given item
        /// </summary>
        /// <param name="itemModel">An item that contains model data</param>
        /// <param name="xivRace">The race for the requested data</param>
        /// <returns>A list of part characters</returns>
        public List <string> GetTexturePartList(IItemModel itemModel, XivRace xivRace, XivDataFile dataFile)
        {
            // Get the mtrl version for the given item from the imc file
            var imc     = new Imc(_gameDirectory, dataFile);
            var version = imc.GetImcInfo(itemModel, itemModel.PrimaryModelInfo).Version.ToString().PadLeft(4, '0');

            var id      = itemModel.PrimaryModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer = itemModel.PrimaryModelInfo.Body.ToString().PadLeft(4, '0');
            var parts   = new[] { 'a', 'b', 'c', 'd', 'e', 'f' };
            var race    = xivRace.GetRaceCode();

            var index = new Index(_gameDirectory);

            var    itemType = ItemType.GetItemType(itemModel);
            string mtrlFolder = "", mtrlFile = "";

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}e{id}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}a{id}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_";
                break;

            case XivItemType.weapon:
                mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_w{id}b{bodyVer}_";
                break;

            case XivItemType.monster:
                mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_m{id}b{bodyVer}_";
                break;

            case XivItemType.demihuman:
                mtrlFolder = $"chara/{itemType}/d{id}/obj/body/e{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_d{id}e{bodyVer}_";
                break;

            case XivItemType.human:
                if (itemModel.ItemCategory.Equals(XivStrings.Body))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/b{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}b{bodyVer}_";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Hair))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/h{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}h{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Face))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/f{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}f{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Tail))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/t{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}t{bodyVer}_";
                }
                break;

            default:
                mtrlFolder = "";
                break;
            }

            // Get a list of hashed mtrl files that are in the given folder
            var files = index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile);

            // append the part char to the mtrl file and see if its hashed value is within the files list
            // returns the list of parts that exist within the mtrl folder
            return((from part in parts let mtrlCheck = mtrlFile + part + ".mtrl" where files.Contains(HashGenerator.GetHash(mtrlCheck)) select part.ToString()).ToList());
        }
        private void btnCalcularImc_Click(object sender, RoutedEventArgs e)
        {
            txtImc.Text = "IMC= ";
            if (txtAltura.Text != "" && txtPeso.Text != "")
            {
                double altura    = Convert.ToDouble(txtAltura.Text);
                double peso      = Convert.ToDouble(txtPeso.Text);
                string resultado = "";

                altura       = altura * altura;
                peso         = peso / altura;
                txtImc.Text += peso.ToString("F2");

                if (peso >= 40)
                {
                    resultado = "Obesidade de nível 3";
                }
                else if (peso >= 35 && peso <= 39)
                {
                    resultado = "Obesidade de nível 2";
                }
                else if (peso >= 30 && peso <= 34)
                {
                    resultado = "Obesidade de nível 1";
                }
                else if (peso >= 25 && peso <= 29)
                {
                    resultado = "Sobrepeso";
                }
                else if (peso >= 18 && peso <= 24)
                {
                    resultado = "Peso normal";
                }
                else if (peso <= 17)
                {
                    resultado = "Magreza";
                }

                Aluno a = AlunoDAO.BuscarNomeSenha(Login.cpfLogin, Login.senhaLogin);

                Imc i = new Imc();
                i.altura = Convert.ToDouble(txtAltura.Text);
                i.peso   = Convert.ToDouble(txtPeso.Text);
                if (a != null)
                {
                    i.aluno = a;
                }
                else
                {
                    MessageBox.Show("Deu ruim");
                }
                i.imcResult = peso.ToString("F2");
                i.resultado = resultado;
                ImcDAO.CadastrarImc(i);

                int idImc = Convert.ToInt32(i.idImc);
                i = ImcDAO.BuscarId(idImc);
                dynamic d = new
                {
                    peso      = i.peso,
                    altura    = i.altura,
                    criadoEm  = i.criadoEm,
                    imcResult = i.imcResult,
                    resultado = i.resultado
                };
                imcGrid.Add(d);
                cboImc.ItemsSource = imcGrid;
                cboImc.Items.Refresh();
            }
            else
            {
                MessageBox.Show("Prencha os campos", "Erro");
            }
        }
Beispiel #25
0
        public async Task SaveMulti()
        {
            var _imc   = new Imc(XivCache.GameInfo.GameDirectory);
            var _index = new Index(XivCache.GameInfo.GameDirectory);

            // Get tokenized map info structs.
            // This will let us set them in the new Materials and
            // Detokenize them using the new paths.
            var mapInfos = _material.GetAllMapInfos(true);


            // Shader info likewise will be pumped into each new material.
            var shaderInfo = _material.GetShaderInfo();

            // Add new Materials for shared model items.
            var oldMaterialIdentifier = _material.GetMaterialIdentifier();
            var oldMtrlName           = Path.GetFileName(_material.MTRLPath);

            // Ordering these by name ensures that we create textures for the new variants in the first
            // item alphabetically, just for consistency's sake.
            var sameModelItems = (await _item.GetSharedModelItems()).OrderBy(x => x.Name, new ItemNameComparer());

            var oldVariantString = "/v" + _material.GetVariant().ToString().PadLeft(4, '0') + '/';
            var modifiedVariants = new List <int>();


            var mtrlReplacementRegex       = "_" + oldMaterialIdentifier + ".mtrl";
            var mtrlReplacementRegexResult = "_" + _newMaterialIdentifier + ".mtrl";

            if (_mode == MaterialEditorMode.NewRace)
            {
                mtrlReplacementRegexResult = mtrlReplacementRegex;
            }

            var newMtrlName = oldMtrlName.Replace(mtrlReplacementRegex, mtrlReplacementRegexResult);

            var root = _item.GetRootInfo();

            var imcEntries   = new List <XivImc>();
            var materialSets = new HashSet <byte>();

            try
            {
                var imcInfo = await _imc.GetFullImcInfo(_item);

                imcEntries   = imcInfo.GetAllEntries(root.Slot, true);
                materialSets = imcEntries.Select(x => x.MaterialSet).ToHashSet();
            } catch
            {
                // Item doesn't use IMC entries, and thus only has a single variant.
                materialSets.Clear();
                materialSets.Add(0);
            }


            // We need to save our non-existent base material once before we can continue.
            if (_mode == MaterialEditorMode.NewRace)
            {
                await _mtrl.ImportMtrl(_material, _item, XivStrings.TexTools);
            }

            var count = 0;

            var allItems = (await root.ToFullRoot().GetAllItems());

            var matNumToItems = new Dictionary <int, List <IItemModel> >();

            foreach (var i in allItems)
            {
                if (imcEntries.Count <= i.ModelInfo.ImcSubsetID)
                {
                    continue;
                }

                var matSet = imcEntries[i.ModelInfo.ImcSubsetID].MaterialSet;
                if (!matNumToItems.ContainsKey(matSet))
                {
                    matNumToItems.Add(matSet, new List <IItemModel>());
                }

                var saveItem = i;

                if (typeof(XivCharacter) == i.GetType())
                {
                    var temp = (XivCharacter)((XivCharacter)_item).Clone();
                    temp.Name = saveItem.SecondaryCategory;
                    saveItem  = temp;
                }

                matNumToItems[matSet].Add(saveItem);
            }

            var keys = matNumToItems.Keys.ToList();

            foreach (var key in keys)
            {
                var list = matNumToItems[key];
                matNumToItems[key] = list.OrderBy(x => x.Name, new ItemNameComparer()).ToList();
            }

            // Load and modify all the MTRLs.
            foreach (var materialSetId in materialSets)
            {
                var variantPath     = _mtrl.GetMtrlFolder(root, materialSetId);
                var oldMaterialPath = variantPath + "/" + oldMtrlName;
                var newMaterialPath = variantPath + "/" + newMtrlName;

                // Don't create materials for set 0.  (SE sets the material ID to 0 when that particular set-slot doesn't actually exist as an item)
                if (materialSetId == 0 && imcEntries.Count > 0)
                {
                    continue;
                }

                var     dxVersion = 11;
                XivMtrl itemXivMtrl;

                // Get mtrl path
                if (await _index.FileExists(oldMaterialPath))
                {
                    // Use the Material from this variant as a base?
                    itemXivMtrl = await _mtrl.GetMtrlData(_item, oldMaterialPath, dxVersion);
                }
                else
                {
                    itemXivMtrl = await _mtrl.GetMtrlData(_item, _material.MTRLPath, dxVersion);
                }

                // If we're an item that doesn't use IMC variants, make sure we don't accidentally move the material around.
                if (materialSetId != 0)
                {
                    // Shift the MTRL to the new variant folder.
                    itemXivMtrl.MTRLPath = Regex.Replace(itemXivMtrl.MTRLPath, oldVariantString, "/v" + materialSetId.ToString().PadLeft(4, '0') + "/");
                }

                if (_mode == MaterialEditorMode.NewMulti)
                {
                    // Change the MTRL part identifier.
                    itemXivMtrl.MTRLPath = Regex.Replace(itemXivMtrl.MTRLPath, mtrlReplacementRegex, mtrlReplacementRegexResult);
                }

                // Load the Shader Settings
                itemXivMtrl.SetShaderInfo(shaderInfo, true);

                // Loop our tokenized map infos and pump them back in
                // using the new modified material to detokenize them.
                foreach (var info in mapInfos)
                {
                    itemXivMtrl.SetMapInfo(info.Usage, (MapInfo)info.Clone());
                }


                IItem item;
                try
                {
                    item = matNumToItems[materialSetId].First();
                } catch
                {
                    item = (await XivCache.GetFirstRoot(itemXivMtrl.MTRLPath)).GetFirstItem();
                }

                count++;
                // Write the new Material
                await _mtrl.ImportMtrl(itemXivMtrl, item, XivStrings.TexTools);

                _view.SaveStatusLabel.Content = "Updated " + count + "/" + materialSets.Count + " Material Sets...";
            }
        }
Beispiel #26
0
        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));
                    }
                }
            }
        }
        /// <summary>
        /// Copies the entirety of a given root to a new root.
        /// </summary>
        /// <param name="Source">Original Root to copy from.</param>
        /// <param name="Destination">Destination root to copy to.</param>
        /// <param name="ApplicationSource">Application to list as the source for the resulting mod entries.</param>
        /// <returns>Returns a Dictionary of all the file conversion</returns>
        public static async Task <Dictionary <string, string> > CloneRoot(XivDependencyRoot Source, XivDependencyRoot Destination, string ApplicationSource, int singleVariant = -1, string saveDirectory = null, IProgress <string> ProgressReporter = null, IndexFile index = null, ModList modlist = null, ModPack modPack = null)
        {
            if (!IsSupported(Source) || !IsSupported(Destination))
            {
                throw new InvalidDataException("Cannot clone unsupported root.");
            }


            if (ProgressReporter != null)
            {
                ProgressReporter.Report("Stopping Cache Worker...");
            }
            var workerStatus = XivCache.CacheWorkerEnabled;

            XivCache.CacheWorkerEnabled = false;
            try
            {
                var df = IOUtil.GetDataFileFromPath(Source.ToString());

                var _imc     = new Imc(XivCache.GameInfo.GameDirectory);
                var _mdl     = new Mdl(XivCache.GameInfo.GameDirectory, df);
                var _dat     = new Dat(XivCache.GameInfo.GameDirectory);
                var _index   = new Index(XivCache.GameInfo.GameDirectory);
                var _mtrl    = new Mtrl(XivCache.GameInfo.GameDirectory);
                var _modding = new Modding(XivCache.GameInfo.GameDirectory);

                var doSave = false;
                if (index == null)
                {
                    doSave = true;
                    index  = await _index.GetIndexFile(df);

                    modlist = await _modding.GetModListAsync();
                }


                bool locked = _index.IsIndexLocked(df);
                if (locked)
                {
                    throw new Exception("Game files currently in use.");
                }


                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Analyzing items and variants...");
                }

                // First, try to get everything, to ensure it's all valid.
                ItemMetadata originalMetadata = await GetCachedMetadata(index, modlist, Source, df, _dat);


                var originalModelPaths = await Source.GetModelFiles(index, modlist);

                var originalMaterialPaths = await Source.GetMaterialFiles(-1, index, modlist);

                var originalTexturePaths = await Source.GetTextureFiles(-1, index, modlist);

                var originalVfxPaths = new HashSet <string>();
                if (Imc.UsesImc(Source))
                {
                    var avfxSets = originalMetadata.ImcEntries.Select(x => x.Vfx).Distinct();
                    foreach (var avfx in avfxSets)
                    {
                        var avfxStuff = await ATex.GetVfxPath(Source.Info, avfx);

                        if (String.IsNullOrEmpty(avfxStuff.Folder) || String.IsNullOrEmpty(avfxStuff.File))
                        {
                            continue;
                        }

                        var path = avfxStuff.Folder + "/" + avfxStuff.File;
                        if (index.FileExists(path))
                        {
                            originalVfxPaths.Add(path);
                        }
                    }
                }

                // Time to start editing things.

                // First, get a new, clean copy of the metadata, pointed at the new root.
                var newMetadata = await GetCachedMetadata(index, modlist, Source, df, _dat);

                newMetadata.Root = Destination.Info.ToFullRoot();
                ItemMetadata originalDestinationMetadata = null;
                try
                {
                    originalDestinationMetadata = await GetCachedMetadata(index, modlist, Destination, df, _dat);
                } catch
                {
                    originalDestinationMetadata = new ItemMetadata(Destination);
                }

                // Set 0 needs special handling.
                if (Source.Info.PrimaryType == XivItemType.equipment && Source.Info.PrimaryId == 0)
                {
                    var set1Root     = new XivDependencyRoot(Source.Info.PrimaryType, 1, null, null, Source.Info.Slot);
                    var set1Metadata = await GetCachedMetadata(index, modlist, set1Root, df, _dat);

                    newMetadata.EqpEntry = set1Metadata.EqpEntry;

                    if (Source.Info.Slot == "met")
                    {
                        newMetadata.GmpEntry = set1Metadata.GmpEntry;
                    }
                }
                else if (Destination.Info.PrimaryType == XivItemType.equipment && Destination.Info.PrimaryId == 0)
                {
                    newMetadata.EqpEntry = null;
                    newMetadata.GmpEntry = null;
                }


                // Now figure out the path names for all of our new paths.
                // These dictionarys map Old Path => New Path
                Dictionary <string, string> newModelPaths        = new Dictionary <string, string>();
                Dictionary <string, string> newMaterialPaths     = new Dictionary <string, string>();
                Dictionary <string, string> newMaterialFileNames = new Dictionary <string, string>();
                Dictionary <string, string> newTexturePaths      = new Dictionary <string, string>();
                Dictionary <string, string> newAvfxPaths         = new Dictionary <string, string>();

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Calculating files to copy...");
                }

                // For each path, replace any instances of our primary and secondary types.
                foreach (var path in originalModelPaths)
                {
                    newModelPaths.Add(path, UpdatePath(Source, Destination, path));
                }

                foreach (var path in originalMaterialPaths)
                {
                    var nPath = UpdatePath(Source, Destination, path);
                    newMaterialPaths.Add(path, nPath);
                    var fName = Path.GetFileName(path);

                    if (!newMaterialFileNames.ContainsKey(fName))
                    {
                        newMaterialFileNames.Add(fName, Path.GetFileName(nPath));
                    }
                }

                foreach (var path in originalTexturePaths)
                {
                    newTexturePaths.Add(path, UpdatePath(Source, Destination, path));
                }

                foreach (var path in originalVfxPaths)
                {
                    newAvfxPaths.Add(path, UpdatePath(Source, Destination, path));
                }

                var destItem = Destination.GetFirstItem();
                var srcItem  = (await Source.GetAllItems(singleVariant))[0];
                var iCat     = destItem.SecondaryCategory;
                var iName    = destItem.Name;


                var files = newModelPaths.Select(x => x.Value).Union(
                    newMaterialPaths.Select(x => x.Value)).Union(
                    newAvfxPaths.Select(x => x.Value)).Union(
                    newTexturePaths.Select(x => x.Value));
                var allFiles = new HashSet <string>();
                foreach (var f in files)
                {
                    allFiles.Add(f);
                }

                allFiles.Add(Destination.Info.GetRootFile());

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Getting modlist...");
                }

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Removing existing modifications to destination root...");
                }

                if (Destination != Source)
                {
                    var dPath   = Destination.Info.GetRootFolder();
                    var allMods = modlist.Mods.ToList();
                    foreach (var mod in allMods)
                    {
                        if (mod.fullPath.StartsWith(dPath) && !mod.IsInternal())
                        {
                            if (Destination.Info.SecondaryType != null || Destination.Info.Slot == null)
                            {
                                // If this is a slotless root, purge everything.
                                await _modding.DeleteMod(mod.fullPath, false, index, modlist);
                            }
                            else if (allFiles.Contains(mod.fullPath) || mod.fullPath.Contains(Destination.Info.GetBaseFileName(true)))
                            {
                                // Otherwise, only purge the files we're replacing, and anything else that
                                // contains our slot name.
                                await _modding.DeleteMod(mod.fullPath, false, index, modlist);
                            }
                        }
                    }
                }

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Copying models...");
                }

                // Load, Edit, and resave the model files.
                foreach (var kv in newModelPaths)
                {
                    var src    = kv.Key;
                    var dst    = kv.Value;
                    var offset = index.Get8xDataOffset(src);
                    var xmdl   = await _mdl.GetRawMdlData(src, false, offset);

                    var tmdl = TTModel.FromRaw(xmdl);

                    if (xmdl == null || tmdl == null)
                    {
                        continue;
                    }

                    tmdl.Source  = dst;
                    xmdl.MdlPath = dst;

                    // Replace any material references as needed.
                    foreach (var m in tmdl.MeshGroups)
                    {
                        foreach (var matKv in newMaterialFileNames)
                        {
                            m.Material = m.Material.Replace(matKv.Key, matKv.Value);
                        }
                    }

                    // Save new Model.
                    var bytes = await _mdl.MakeNewMdlFile(tmdl, xmdl, null);

                    await _dat.WriteModFile(bytes, dst, ApplicationSource, destItem, index, modlist);
                }

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Copying textures...");
                }

                // Raw Copy all Texture files to the new destinations to avoid having the MTRL save functions auto-generate blank textures.
                foreach (var kv in newTexturePaths)
                {
                    var src = kv.Key;
                    var dst = kv.Value;

                    await _dat.CopyFile(src, dst, ApplicationSource, true, destItem, index, modlist);
                }


                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Copying materials...");
                }
                HashSet <string> CopiedMaterials = new HashSet <string>();
                // Load every Material file and edit the texture references to the new texture paths.
                foreach (var kv in newMaterialPaths)
                {
                    var src = kv.Key;
                    var dst = kv.Value;
                    try
                    {
                        var offset = index.Get8xDataOffset(src);
                        if (offset == 0)
                        {
                            continue;
                        }
                        var xivMtrl = await _mtrl.GetMtrlData(offset, src, 11);

                        xivMtrl.MTRLPath = dst;

                        for (int i = 0; i < xivMtrl.TexturePathList.Count; i++)
                        {
                            foreach (var tkv in newTexturePaths)
                            {
                                xivMtrl.TexturePathList[i] = xivMtrl.TexturePathList[i].Replace(tkv.Key, tkv.Value);
                            }
                        }

                        await _mtrl.ImportMtrl(xivMtrl, destItem, ApplicationSource, index, modlist);

                        CopiedMaterials.Add(dst);
                    }
                    catch (Exception ex)
                    {
                        // Let functions later handle this mtrl then.
                    }
                }

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Copying VFX...");
                }
                // Copy VFX files.
                foreach (var kv in newAvfxPaths)
                {
                    var src = kv.Key;
                    var dst = kv.Value;

                    await _dat.CopyFile(src, dst, ApplicationSource, true, destItem, index, modlist);
                }

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Creating missing variants...");
                }
                // Check to see if we need to add any variants
                var cloneNum = newMetadata.ImcEntries.Count >= 2 ? 1 : 0;
                while (originalDestinationMetadata.ImcEntries.Count > newMetadata.ImcEntries.Count)
                {
                    // Clone Variant 1 into the variants we are missing.
                    newMetadata.ImcEntries.Add((XivImc)newMetadata.ImcEntries[cloneNum].Clone());
                }


                if (singleVariant >= 0)
                {
                    if (ProgressReporter != null)
                    {
                        ProgressReporter.Report("Setting single-variant data...");
                    }

                    if (singleVariant < newMetadata.ImcEntries.Count)
                    {
                        var v = newMetadata.ImcEntries[singleVariant];

                        for (int i = 0; i < newMetadata.ImcEntries.Count; i++)
                        {
                            newMetadata.ImcEntries[i] = (XivImc)v.Clone();
                        }
                    }
                }

                // Update Skeleton references to be for the correct set Id.
                var setId = Destination.Info.SecondaryId == null ? (ushort)Destination.Info.PrimaryId : (ushort)Destination.Info.SecondaryId;
                foreach (var entry in newMetadata.EstEntries)
                {
                    entry.Value.SetId = setId;
                }

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Copying metdata...");
                }

                // Poke through the variants and adjust any that point to null Material Sets to instead use a valid one.
                if (newMetadata.ImcEntries.Count > 0 && originalMetadata.ImcEntries.Count > 0)
                {
                    var valid = newMetadata.ImcEntries.FirstOrDefault(x => x.MaterialSet != 0).MaterialSet;
                    if (valid <= 0)
                    {
                        valid = originalMetadata.ImcEntries.FirstOrDefault(x => x.MaterialSet != 0).MaterialSet;
                    }

                    for (int i = 0; i < newMetadata.ImcEntries.Count; i++)
                    {
                        var entry = newMetadata.ImcEntries[i];
                        if (entry.MaterialSet == 0)
                        {
                            entry.MaterialSet = valid;
                        }
                    }
                }

                await ItemMetadata.SaveMetadata(newMetadata, ApplicationSource, index, modlist);

                // Save the new Metadata file via the batch function so that it's only written to the memory cache for now.
                await ItemMetadata.ApplyMetadataBatched(new List <ItemMetadata>() { newMetadata }, index, modlist, false);



                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Filling in missing material sets...");
                }
                // Validate all variants/material sets for valid materials, and copy materials as needed to fix.
                if (Imc.UsesImc(Destination))
                {
                    var mSets = newMetadata.ImcEntries.Select(x => x.MaterialSet).Distinct();
                    foreach (var mSetId in mSets)
                    {
                        var path = Destination.Info.GetRootFolder() + "material/v" + mSetId.ToString().PadLeft(4, '0') + "/";
                        foreach (var mkv in newMaterialFileNames)
                        {
                            // See if the material was copied over.
                            var destPath = path + mkv.Value;
                            if (CopiedMaterials.Contains(destPath))
                            {
                                continue;
                            }

                            string existentCopy = null;

                            // If not, find a material where one *was* copied over.
                            foreach (var mSetId2 in mSets)
                            {
                                var p2 = Destination.Info.GetRootFolder() + "material/v" + mSetId2.ToString().PadLeft(4, '0') + "/";
                                foreach (var cmat2 in CopiedMaterials)
                                {
                                    if (cmat2 == p2 + mkv.Value)
                                    {
                                        existentCopy = cmat2;
                                        break;
                                    }
                                }
                            }

                            // Shouldn't ever actually hit this, but if we do, nothing to be done about it.
                            if (existentCopy == null)
                            {
                                continue;
                            }

                            // Copy the material over.
                            await _dat.CopyFile(existentCopy, destPath, ApplicationSource, true, destItem, index, modlist);
                        }
                    }
                }

                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Updating modlist...");
                }

                if (modPack == null)
                {
                    modPack = new ModPack()
                    {
                        author = "System", name = "Item Copy - " + srcItem.Name + " to " + iName, url = "", version = "1.0"
                    };
                }

                List <Mod> mods = new List <Mod>();
                foreach (var mod in modlist.Mods)
                {
                    if (allFiles.Contains(mod.fullPath))
                    {
                        // Ensure all of our modified files are attributed correctly.
                        mod.name     = iName;
                        mod.category = iCat;
                        mod.source   = ApplicationSource;
                        mod.modPack  = modPack;

                        mods.Add(mod);
                    }
                }

                if (!modlist.ModPacks.Any(x => x.name == modPack.name))
                {
                    modlist.ModPacks.Add(modPack);
                }

                if (doSave)
                {
                    // Save everything.
                    await _index.SaveIndexFile(index);

                    await _modding.SaveModListAsync(modlist);
                }

                XivCache.QueueDependencyUpdate(allFiles.ToList());

                if (saveDirectory != null)
                {
                    ProgressReporter.Report("Creating TTMP File...");
                    var desc = "Item Converter Modpack - " + srcItem.Name + " -> " + iName + "\nCreated at: " + DateTime.Now.ToString();
                    // Time to save the modlist to file.
                    var dir   = new DirectoryInfo(saveDirectory);
                    var _ttmp = new TTMP(dir, ApplicationSource);
                    var smpd  = new SimpleModPackData()
                    {
                        Author            = modPack.author,
                        Description       = desc,
                        Url               = modPack.url,
                        Version           = new Version(1, 0, 0),
                        Name              = modPack.name,
                        SimpleModDataList = new List <SimpleModData>()
                    };

                    foreach (var mod in mods)
                    {
                        var size = await _dat.GetCompressedFileSize(mod.data.modOffset, df);

                        var smd = new SimpleModData()
                        {
                            Name      = iName,
                            FullPath  = mod.fullPath,
                            DatFile   = df.GetDataFileName(),
                            Category  = iCat,
                            IsDefault = false,
                            ModSize   = size,
                            ModOffset = mod.data.modOffset
                        };
                        smpd.SimpleModDataList.Add(smd);
                    }

                    await _ttmp.CreateSimpleModPack(smpd, XivCache.GameInfo.GameDirectory, null, true);
                }



                if (ProgressReporter != null)
                {
                    ProgressReporter.Report("Root copy complete.");
                }

                // Return the final file conversion listing.
                var ret  = newModelPaths.Union(newMaterialPaths).Union(newAvfxPaths).Union(newTexturePaths);
                var dict = ret.ToDictionary(x => x.Key, x => x.Value);
                dict.Add(Source.Info.GetRootFile(), Destination.Info.GetRootFile());
                return(dict);
            } finally
            {
                XivCache.CacheWorkerEnabled = workerStatus;
            }
        }
        /// <summary>
        /// Applies this Metadata object to the FFXIV file system.
        /// This should only called by Dat.WriteToDat() / RestoreDefaultMetadata()
        /// </summary>
        internal static async Task ApplyMetadata(ItemMetadata meta, IndexFile index = null, ModList modlist = null)
        {
            var _eqp     = new Eqp(XivCache.GameInfo.GameDirectory);
            var _modding = new Modding(XivCache.GameInfo.GameDirectory);
            var _index   = new Index(XivCache.GameInfo.GameDirectory);
            var df       = IOUtil.GetDataFileFromPath(meta.Root.Info.GetRootFile());

            var dummyItem = new XivGenericItemModel();

            dummyItem.Name = Constants.InternalModSourceName;
            dummyItem.SecondaryCategory = Constants.InternalModSourceName;


            // Beep boop
            bool doSave = false;

            if (index == null)
            {
                doSave = true;
                index  = await _index.GetIndexFile(df);

                modlist = await _modding.GetModListAsync();
            }


            if (meta.ImcEntries.Count > 0)
            {
                var _imc    = new Imc(XivCache.GameInfo.GameDirectory);
                var imcPath = meta.Root.GetRawImcFilePath();
                await _imc.SaveEntries(imcPath, meta.Root.Info.Slot, meta.ImcEntries, dummyItem, index, modlist);
            }

            // Applying EQP data via set 0 is not allowed, as it is a special set hard-coded to use Set 1's data.
            if (meta.EqpEntry != null && !(meta.Root.Info.PrimaryType == Items.Enums.XivItemType.equipment && meta.Root.Info.PrimaryId == 0))
            {
                await _eqp.SaveEqpEntry(meta.Root.Info.PrimaryId, meta.EqpEntry, dummyItem, index, modlist);
            }

            if (meta.EqdpEntries.Count > 0)
            {
                await _eqp.SaveEqdpEntries((uint)meta.Root.Info.PrimaryId, meta.Root.Info.Slot, meta.EqdpEntries, dummyItem, index, modlist);
            }

            if (meta.EstEntries.Count > 0)
            {
                var type    = Est.GetEstType(meta.Root);
                var entries = meta.EstEntries.Values.ToList();
                await Est.SaveExtraSkeletonEntries(type, entries, dummyItem, index, modlist);
            }

            if (meta.GmpEntry != null)
            {
                await _eqp.SaveGimmickParameter(meta.Root.Info.PrimaryId, meta.GmpEntry, dummyItem, index, modlist);
            }

            if (doSave)
            {
                await _index.SaveIndexFile(index);

                await _modding.SaveModListAsync(modlist);
            }
        }
Beispiel #29
0
        /// <summary>
        /// Gets the list of available mtrl parts for a given item
        /// </summary>
        /// <param name="itemModel">An item that contains model data</param>
        /// <param name="xivRace">The race for the requested data</param>
        /// <returns>A list of part characters</returns>
        public async Task <List <string> > GetTexturePartList(IItemModel itemModel, XivRace xivRace, XivDataFile dataFile, string type = "Primary")
        {
            var itemType = ItemType.GetItemType(itemModel);

            var version = "0001";

            var id           = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer      = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0');
            var itemCategory = itemModel.ItemCategory;

            if (type.Equals("Secondary"))
            {
                var xivGear = itemModel as XivGear;

                id      = xivGear.SecondaryModelInfo.ModelID.ToString().PadLeft(4, '0');
                bodyVer = xivGear.SecondaryModelInfo.Body.ToString().PadLeft(4, '0');

                var imc = new Imc(_gameDirectory, xivGear.DataFile);
                version = (await imc.GetImcInfo(itemModel, xivGear.SecondaryModelInfo)).Version.ToString().PadLeft(4, '0');

                if (imc.ChangedType)
                {
                    itemType     = XivItemType.equipment;
                    xivRace      = XivRace.Hyur_Midlander_Male;
                    itemCategory = XivStrings.Hands;
                }
            }
            else
            {
                if (itemType != XivItemType.human && itemType != XivItemType.furniture)
                {
                    // Get the mtrl version for the given item from the imc file
                    var imc = new Imc(_gameDirectory, dataFile);
                    version = (await imc.GetImcInfo(itemModel, itemModel.ModelInfo)).Version.ToString().PadLeft(4, '0');
                }
            }

            var parts = new[] { 'a', 'b', 'c', 'd', 'e', 'f' };
            var race  = xivRace.GetRaceCode();

            string mtrlFolder = "", mtrlFile = "";

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}e{id}_{SlotAbbreviationDictionary[itemCategory]}_";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}a{id}_{SlotAbbreviationDictionary[itemCategory]}_";
                break;

            case XivItemType.weapon:
                mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_w{id}b{bodyVer}_";
                break;

            case XivItemType.monster:
                mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_m{id}b{bodyVer}_";
                break;

            case XivItemType.demihuman:
                mtrlFolder = $"chara/{itemType}/d{id}/obj/body/e{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_d{id}e{bodyVer}_";
                break;

            case XivItemType.human:
                if (itemCategory.Equals(XivStrings.Body))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/b{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}b{bodyVer}_";
                }
                else if (itemCategory.Equals(XivStrings.Hair))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/h{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}h{bodyVer}_{SlotAbbreviationDictionary[itemCategory]}_";
                }
                else if (itemCategory.Equals(XivStrings.Face))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/f{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}f{bodyVer}_{SlotAbbreviationDictionary[itemCategory]}_";
                }
                else if (itemCategory.Equals(XivStrings.Tail))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/t{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}t{bodyVer}_";
                }
                break;

            case XivItemType.furniture:
                if (itemCategory.Equals(XivStrings.Furniture_Indoor))
                {
                    mtrlFolder = $"bgcommon/hou/indoor/general/{id}/material";
                    mtrlFile   = $"fun_b0_m{id}_0";
                }
                else if (itemCategory.Equals(XivStrings.Furniture_Outdoor))
                {
                    mtrlFolder = $"bgcommon/hou/outdoor/general/{id}/material";
                    mtrlFile   = $"gar_b0_m{id}_0";
                }

                break;

            default:
                mtrlFolder = "";
                break;
            }

            // Get a list of hashed mtrl files that are in the given folder
            var files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile);

            // append the part char to the mtrl file and see if its hashed value is within the files list
            var partList =
                (from part in parts
                 let mtrlCheck = mtrlFile + part + ".mtrl"
                                 where files.Contains(HashGenerator.GetHash(mtrlCheck))
                                 select part.ToString()).ToList();

            if (partList.Count < 1 && itemType == XivItemType.furniture)
            {
                if (itemCategory.Equals(XivStrings.Furniture_Indoor))
                {
                    mtrlFile = $"fun_b0_m{id}_1";
                }
                else if (itemCategory.Equals(XivStrings.Furniture_Outdoor))
                {
                    mtrlFile = $"gar_b0_m{id}_1";
                }

                // Get a list of hashed mtrl files that are in the given folder
                files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile);

                // append the part char to the mtrl file and see if its hashed value is within the files list
                partList =
                    (from part in parts
                     let mtrlCheck = mtrlFile + part + ".mtrl"
                                     where files.Contains(HashGenerator.GetHash(mtrlCheck))
                                     select part.ToString()).ToList();
            }

            // returns the list of parts that exist within the mtrl folder
            return(partList);
        }
        private async Task LoadItems()
        {
            List <string> children = new List <string>();
            var           root     = _item.GetRoot();

            if (root != null)
            {
                if (_level == XivDependencyLevel.Model)
                {
                    children = await root.GetModelFiles();
                }
                else if (_level == XivDependencyLevel.Material)
                {
                    var imc = new Imc(XivCache.GameInfo.GameDirectory);
                    try
                    {
                        var entry = await imc.GetImcInfo((IItemModel)_item);

                        children = await root.GetMaterialFiles(entry.MaterialSet);
                    } catch
                    {
                        if (root.Info.SecondaryType == XivItemType.hair ||
                            root.Info.SecondaryType == XivItemType.tail ||
                            (root.Info.PrimaryType == XivItemType.human && root.Info.SecondaryType == XivItemType.body))
                        {
                            // These types don't have IMC entries, but have a material variant number.
                            // Kind of weird, but whatever.
                            children = await root.GetMaterialFiles(1);
                        }
                        else
                        {
                            children = await root.GetMaterialFiles(0);
                        }
                    }
                }
                else if (_level == XivDependencyLevel.Texture)
                {
                    try
                    {
                        var imc   = new Imc(XivCache.GameInfo.GameDirectory);
                        var entry = await imc.GetImcInfo((IItemModel)_item);

                        children = await root.GetTextureFiles(entry.MaterialSet);
                    }
                    catch
                    {
                        if (root.Info.SecondaryType == XivItemType.hair ||
                            root.Info.SecondaryType == XivItemType.tail ||
                            (root.Info.PrimaryType == XivItemType.human && root.Info.SecondaryType == XivItemType.body))
                        {
                            // These types don't have IMC entries, but have a material variant number.
                            // Kind of weird, but whatever.
                            children = await root.GetTextureFiles(1);
                        }
                        else
                        {
                            children = await root.GetTextureFiles(0);
                        }
                    }
                }
                else
                {
                    // Invalid or root, nothing listed.
                }
            }

            var index = new Index(XivCache.GameInfo.GameDirectory);

            foreach (var file in children)
            {
                var exists = await index.FileExists(file);

                if (!exists)
                {
                    continue;
                }

                Files.Add(new FileEntry(file));
            }
        }