Beispiel #1
0
        /// <summary>
        /// Gets the atex paths for a given item
        /// </summary>
        /// <param name="itemModel">The item to get the atex paths for</param>
        /// <returns>A list of TexTypePath containing the atex info</returns>
        public List <TexTypePath> GetAtexPaths(IItemModel itemModel)
        {
            var atexTexTypePathList = new List <TexTypePath>();

            var index = new Index(_gameDirectory);
            var avfx  = new Avfx(_gameDirectory, _dataFile);

            var itemType = ItemType.GetItemType(itemModel);

            var vfxPath = GetVfxPath(itemModel, itemType);

            var vfxOffset = index.GetDataOffset(HashGenerator.GetHash(vfxPath.Folder), HashGenerator.GetHash(vfxPath.File),
                                                _dataFile);

            if (vfxOffset == 0)
            {
                throw new Exception($"Could not find offset for vfx path {vfxPath.Folder}/{vfxPath.File}");
            }

            var aTexPaths = avfx.GetATexPaths(vfxOffset);

            foreach (var atexPath in aTexPaths)
            {
                var ttp = new TexTypePath
                {
                    DataFile = _dataFile,
                    Name     = Path.GetFileNameWithoutExtension(atexPath),
                    Path     = atexPath
                };

                atexTexTypePathList.Add(ttp);
            }

            return(atexTexTypePathList);
        }
Beispiel #2
0
        /// <summary>
        /// Gets the MTRL data for the given item
        /// </summary>
        /// <remarks>
        /// It requires a race (The default is usually <see cref="XivRace.Hyur_Midlander_Male"/>)
        /// It also requires an mtrl part <see cref="GearInfo.GetPartList(IItemModel, XivRace)"/> (default is 'a')
        /// </remarks>
        /// <param name="itemModel">Item that contains model data</param>
        /// <param name="race">The race for the requested data</param>
        /// <param name="mtrlFile">The Mtrl file</param>
        /// <returns>XivMtrl containing all the mtrl data</returns>
        public XivMtrl GetMtrlData(IItemModel itemModel, XivRace race, string mtrlFile, int dxVersion)
        {
            var index    = new Index(_gameDirectory);
            var itemType = ItemType.GetItemType(itemModel);

            // Get mtrl path
            var mtrlFolder     = GetMtrlFolder(itemModel, race, itemType);
            var mtrlStringPath = $"{mtrlFolder}/{mtrlFile}";

            if (itemType == XivItemType.furniture)
            {
                mtrlStringPath = $"b{mtrlFile}";
                mtrlFolder     = Path.GetDirectoryName(mtrlStringPath).Replace("\\", "/");
                mtrlFile       = Path.GetFileName(mtrlStringPath);
            }

            // Get mtrl offset
            var mtrlOffset = index.GetDataOffset(HashGenerator.GetHash(mtrlFolder), HashGenerator.GetHash(mtrlFile),
                                                 _dataFile);

            if (mtrlOffset == 0)
            {
                throw new Exception($"Could not find offest for {mtrlStringPath}");
            }

            var mtrlData = GetMtrlData(mtrlOffset, mtrlStringPath, dxVersion);

            return(mtrlData);
        }
Beispiel #3
0
        /// <summary>
        /// Gets the relevant IMC information for a given item
        /// </summary>
        /// <param name="item">The item to get the version for</param>
        /// <param name="modelInfo">The model info of the item</param>
        /// <returns>The XivImc Data</returns>
        public XivImc GetImcInfo(IItemModel item, XivModelInfo modelInfo)
        {
            var xivImc = new XivImc();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int headerLength     = 4;
            const int variantLength    = 6;
            const int variantSetLength = 30;

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

            var itemType = ItemType.GetItemType(item);
            var imcPath  = GetImcPath(modelInfo, itemType);

            var imcOffset = index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder), HashGenerator.GetHash(imcPath.File), _dataFile);

            if (imcOffset == 0)
            {
                throw new Exception($"Could not find offest for {imcPath.Folder}/{imcPath.File}");
            }

            var imcData = dat.GetType2Data(imcOffset, _dataFile);

            using (var br = new BinaryReader(new MemoryStream(imcData)))
            {
                int variantOffset;

                if (itemType == XivItemType.weapon || itemType == XivItemType.monster)
                {
                    // weapons and monsters do not have variant sets
                    variantOffset = (modelInfo.Variant * variantLength) + headerLength;
                }
                else
                {
                    // Variant Sets contain 5 variants for each slot
                    // These can be Head, Body, Hands, Legs, Feet  or  Ears, Neck, Wrists, LRing, RRing
                    // This skips to the correct variant set, then to the correct slot within that set for the item
                    variantOffset = (modelInfo.Variant * variantSetLength) + (_slotOffsetDictionary[item.ItemCategory] * variantLength) + headerLength;
                }

                br.BaseStream.Seek(variantOffset, SeekOrigin.Begin);

                xivImc.Version = br.ReadByte();
                var unknown = br.ReadByte();
                xivImc.Mask = br.ReadUInt16();
                xivImc.Vfx  = br.ReadUInt16();
            }

            return(xivImc);
        }
Beispiel #4
0
        /// <summary>
        /// Gets the MTRL data for the given item
        /// </summary>
        /// <remarks>
        /// It requires a race (The default is usually <see cref="XivRace.Hyur_Midlander_Male"/>)
        /// It also requires an mtrl part <see cref="GearInfo.GetPartList(IItemModel, XivRace)"/> (default is 'a')
        /// </remarks>
        /// <param name="itemModel">Item that contains model data</param>
        /// <param name="race">The race for the requested data</param>
        /// <param name="part">The Mtrl part </param>
        /// <returns>XivMtrl containing all the mtrl data</returns>
        public XivMtrl GetMtrlData(IItemModel itemModel, XivRace race, char part, int dxVersion)
        {
            var index    = new Index(_gameDirectory);
            var itemType = ItemType.GetItemType(itemModel);

            // Get mtrl path
            var mtrlPath       = GetMtrlPath(itemModel, race, part, itemType);
            var mtrlStringPath = $"{mtrlPath.Folder}/{mtrlPath.File}";

            // Get mtrl offset
            var mtrlOffset = index.GetDataOffset(HashGenerator.GetHash(mtrlPath.Folder), HashGenerator.GetHash(mtrlPath.File),
                                                 _dataFile);

            if (mtrlOffset == 0 && itemType == XivItemType.furniture)
            {
                mtrlPath.File  = mtrlPath.File.Replace("_0", "_1");
                mtrlStringPath = $"{mtrlPath.Folder}/{mtrlPath.File}";

                // Get mtrl offset
                mtrlOffset = index.GetDataOffset(HashGenerator.GetHash(mtrlPath.Folder), HashGenerator.GetHash(mtrlPath.File),
                                                 _dataFile);
            }

            if (mtrlOffset == 0)
            {
                throw new Exception($"Could not find offest for {mtrlStringPath}");
            }

            var mtrlData = GetMtrlData(mtrlOffset, mtrlStringPath, dxVersion);

            if (mtrlPath.HasVfx)
            {
                var atex = new ATex(_gameDirectory, _dataFile);
                mtrlData.TextureTypePathList.AddRange(atex.GetAtexPaths(itemModel));
            }

            return(mtrlData);
        }
Beispiel #5
0
        /// <summary>
        /// Gets the full IMC information for a given item
        /// </summary>
        /// <param name="item"></param>
        /// <param name="modelInfo"></param>
        /// <returns>The ImcData data</returns>
        public async Task <ImcData> GetFullImcInfo(IItemModel item, XivModelInfo modelInfo)
        {
            var index = new Index(_gameDirectory);
            var dat   = new Dat(_gameDirectory);

            var itemType = ItemType.GetItemType(item);
            var imcPath  = GetImcPath(modelInfo, itemType);

            var imcOffset = await index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder), HashGenerator.GetHash(imcPath.File), _dataFile);

            if (imcOffset == 0)
            {
                throw new Exception($"Could not find offset for {imcPath.Folder}/{imcPath.File}");
            }

            var imcByteData = await dat.GetType2Data(imcOffset, _dataFile);

            return(await Task.Run(() =>
            {
                using (var br = new BinaryReader(new MemoryStream(imcByteData)))
                {
                    var imcData = new ImcData()
                    {
                        VariantCount = br.ReadInt16(),
                        Unknown = br.ReadInt16(),
                        GearVariantList = new List <VariantSet>()
                    };

                    //weapons and monsters do not have variant sets
                    if (itemType == XivItemType.weapon || itemType == XivItemType.monster)
                    {
                        imcData.OtherVariantList = new List <XivImc>();

                        imcData.DefaultVariant = new XivImc
                        {
                            Version = br.ReadUInt16(),
                            Mask = br.ReadUInt16(),
                            Vfx = br.ReadUInt16()
                        };

                        for (var i = 0; i < imcData.VariantCount; i++)
                        {
                            imcData.OtherVariantList.Add(new XivImc
                            {
                                Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                            });
                        }
                    }
                    else
                    {
                        imcData.GearVariantList = new List <VariantSet>();

                        imcData.DefaultVariantSet = new VariantSet
                        {
                            Slot1 = new XivImc
                            {
                                Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                            },
                            Slot2 = new XivImc
                            {
                                Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                            },
                            Slot3 = new XivImc
                            {
                                Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                            },
                            Slot4 = new XivImc
                            {
                                Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                            },
                            Slot5 = new XivImc
                            {
                                Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                            },
                        };

                        for (var i = 0; i < imcData.VariantCount; i++)
                        {
                            // gets the data for each slot in the current variant set
                            var imcGear = new VariantSet
                            {
                                Slot1 = new XivImc
                                {
                                    Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                                },
                                Slot2 = new XivImc
                                {
                                    Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                                },
                                Slot3 = new XivImc
                                {
                                    Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                                },
                                Slot4 = new XivImc
                                {
                                    Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                                },
                                Slot5 = new XivImc
                                {
                                    Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16()
                                },
                            };

                            imcData.GearVariantList.Add(imcGear);
                        }
                    }

                    return imcData;
                }
            }));
        }
Beispiel #6
0
        /// <summary>
        /// Gets the relevant IMC information for a given item
        /// </summary>
        /// <param name="item">The item to get the version for</param>
        /// <param name="modelInfo">The model info of the item</param>
        /// <returns>The XivImc Data</returns>
        public async Task <XivImc> GetImcInfo(IItemModel item, XivModelInfo modelInfo)
        {
            var xivImc = new XivImc();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int headerLength     = 4;
            const int variantLength    = 6;
            const int variantSetLength = 30;

            var itemType = ItemType.GetItemType(item);
            var imcPath  = GetImcPath(modelInfo, itemType);

            var itemCategory = item.ItemCategory;

            var imcOffset = await _modding.Index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder),
                                                               HashGenerator.GetHash(imcPath.File), _dataFile);

            if (imcOffset == 0)
            {
                if (item.ItemCategory == XivStrings.Two_Handed)
                {
                    itemCategory = XivStrings.Hands;
                    itemType     = XivItemType.equipment;
                    imcPath      = GetImcPath(modelInfo, itemType);

                    imcOffset = await _modding.Index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder),
                                                                   HashGenerator.GetHash(imcPath.File), _dataFile);

                    if (imcOffset == 0)
                    {
                        throw new Exception($"Could not find offset for {imcPath.Folder}/{imcPath.File}");
                    }

                    ChangedType = true;
                }
                else
                {
                    throw new Exception($"Could not find offset for {imcPath.Folder}/{imcPath.File}");
                }
            }

            var imcData = await _modding.Dat.GetType2Data(imcOffset, _dataFile);

            await Task.Run(() =>
            {
                using (var br = new BinaryReader(new MemoryStream(imcData)))
                {
                    int variantOffset;

                    if (itemType == XivItemType.weapon || itemType == XivItemType.monster)
                    {
                        // weapons and monsters do not have variant sets
                        variantOffset = (modelInfo.Variant *variantLength) + headerLength;

                        // use default if offset is out of range
                        if (variantOffset >= imcData.Length)
                        {
                            variantOffset = headerLength;
                        }
                    }
                    else
                    {
                        // Variant Sets contain 5 variants for each slot
                        // These can be Head, Body, Hands, Legs, Feet  or  Ears, Neck, Wrists, LRing, RRing
                        // This skips to the correct variant set, then to the correct slot within that set for the item
                        variantOffset = (modelInfo.Variant *variantSetLength) +
                                        (_slotOffsetDictionary[itemCategory] * variantLength) + headerLength;

                        // use defalut if offset is out of range
                        if (variantOffset >= imcData.Length)
                        {
                            variantOffset = (_slotOffsetDictionary[itemCategory] * variantLength) + headerLength;
                        }
                    }

                    br.BaseStream.Seek(variantOffset, SeekOrigin.Begin);

                    // if(variantOffset)

                    xivImc.Version = br.ReadByte();
                    var unknown    = br.ReadByte();
                    xivImc.Mask    = br.ReadUInt16();
                    xivImc.Vfx     = br.ReadByte();
                    var unknown1   = br.ReadByte();
                }
            });

            return(xivImc);
        }
Beispiel #7
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);
        }
Beispiel #8
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());
        }
Beispiel #9
0
        /// <summary>
        /// Gets the available races that contain model data for the given gear
        /// </summary>
        /// <remarks>
        /// This checks to see if the mdl file for each race exists in the mdl folder
        /// It creates a list of the races which do have an available mdl file
        /// </remarks>
        /// <param name="xivGear">A gear item</param>
        /// <returns>A list of XivRace data</returns>
        public async Task <List <XivRace> > GetRacesForModels(XivGear xivGear, XivDataFile dataFile)
        {
            var itemType = ItemType.GetItemType(xivGear);

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

            var raceList = new List <XivRace>();

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

            string mdlFolder;
            var    id = xivGear.ModelInfo.ModelID.ToString().PadLeft(4, '0');

            switch (itemType)
            {
            case XivItemType.equipment:
                mdlFolder = $"chara/{itemType}/e{id}/model";
                break;

            case XivItemType.accessory:
                mdlFolder = $"chara/{itemType}/a{id}/model";
                break;

            default:
                mdlFolder = "";
                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 mdlFile;

                switch (itemType)
                {
                case XivItemType.equipment:
                    mdlFile = $"c{ID}e{modelID}_{SlotAbbreviationDictionary[xivGear.ItemCategory]}.mdl";
                    break;

                case XivItemType.accessory:
                    mdlFile = $"c{ID}a{modelID}_{SlotAbbreviationDictionary[xivGear.ItemCategory]}.mdl";
                    break;

                default:
                    mdlFile = "";
                    break;
                }

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

            // get the list of hashed file names from the mtrl folder
            var files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mdlFolder), 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);
        }
Beispiel #10
0
 public static ItemType ConvertItemType(int i)
 {
     return(ItemType.GetItemType(i));
 }
Beispiel #11
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 List <XivRace> GetRacesForTextures(XivGear xivGear, XivDataFile dataFile)
        {
            // Get the material version for the item from the imc file
            var imc         = new Imc(_gameDirectory, dataFile);
            var gearVersion = imc.GetImcInfo(xivGear, xivGear.PrimaryModelInfo).Version.ToString().PadLeft(4, '0');

            var modelID = xivGear.PrimaryModelInfo.ModelID.ToString().PadLeft(4, '0');

            var raceList = new List <XivRace>();

            var    index    = new Index(_gameDirectory);
            var    itemType = ItemType.GetItemType(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}_{SlotAbbreviationDictionary[xivGear.ItemCategory]}_a.mtrl";
                    break;

                case XivItemType.accessory:
                    mtrlFile = $"mt_c{ID}a{modelID}_{SlotAbbreviationDictionary[xivGear.ItemCategory]}_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 = 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);
        }
Beispiel #12
0
        /// <summary>
        /// Gets the MTRL data for the given item
        /// </summary>
        /// <remarks>
        /// It requires a race (The default is usually <see cref="XivRace.Hyur_Midlander_Male"/>)
        /// It also requires an mtrl part <see cref="GearInfo.GetPartList(IItemModel, XivRace)"/> (default is 'a')
        /// </remarks>
        /// <param name="itemModel">Item that contains model data</param>
        /// <param name="race">The race for the requested data</param>
        /// <param name="part">The Mtrl part </param>
        /// <returns></returns>
        public XivMtrl GetMtrlData(IItemModel itemModel, XivRace race, char part)
        {
            var index    = new Index(_gameDirectory);
            var dat      = new Dat(_gameDirectory);
            var itemType = ItemType.GetItemType(itemModel);

            // Get mtrl path
            var mtrlPath = GetMtrlPath(itemModel, race, part, itemType);

            // Get mtrl offset
            var mtrlOffset = index.GetDataOffset(HashGenerator.GetHash(mtrlPath.Folder), HashGenerator.GetHash(mtrlPath.File),
                                                 _dataFile);

            if (mtrlOffset == 0)
            {
                throw new Exception($"Could not find offest for {mtrlPath.Folder}/{mtrlPath.File}");
            }

            // Get uncompressed mtrl data
            var mtrlData = dat.GetType2Data(mtrlOffset, _dataFile);

            XivMtrl xivMtrl;

            using (var br = new BinaryReader(new MemoryStream(mtrlData)))
            {
                xivMtrl = new XivMtrl
                {
                    Signature            = br.ReadInt32(),
                    FileSize             = br.ReadInt16(),
                    ColorSetDataSize     = br.ReadInt16(),
                    MaterialDataSize     = br.ReadInt16(),
                    TexturePathsDataSize = br.ReadByte(),
                    Unknown             = br.ReadByte(),
                    TextureCount        = br.ReadByte(),
                    MapCount            = br.ReadByte(),
                    ColorSetCount       = br.ReadByte(),
                    Unknown1            = br.ReadByte(),
                    TextureTypePathList = new List <TexTypePath>(),
                    MTRLPath            = $"{mtrlPath.Folder}/{mtrlPath.File}"
                };

                var pathSizeList = new List <int>();

                // get the texture path offsets
                xivMtrl.TexturePathOffsetList = new List <int>(xivMtrl.TextureCount);
                for (var i = 0; i < xivMtrl.TextureCount; i++)
                {
                    xivMtrl.TexturePathOffsetList.Add(br.ReadInt16());
                    br.ReadBytes(2);

                    // add the size of the paths
                    if (i > 0)
                    {
                        pathSizeList.Add(xivMtrl.TexturePathOffsetList[i] - xivMtrl.TexturePathOffsetList[i - 1]);
                    }
                }

                // get the map path offsets
                xivMtrl.MapPathOffsetList = new List <int>(xivMtrl.MapCount);
                for (var i = 0; i < xivMtrl.MapCount; i++)
                {
                    xivMtrl.MapPathOffsetList.Add(br.ReadInt16());
                    br.ReadBytes(2);

                    // add the size of the paths
                    if (i > 0)
                    {
                        pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.MapPathOffsetList[i - 1]);
                    }
                    else
                    {
                        pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.TexturePathOffsetList[xivMtrl.TextureCount - 1]);
                    }
                }

                // get the color set offsets
                xivMtrl.ColorSetPathOffsetList = new List <int>(xivMtrl.ColorSetCount);
                for (var i = 0; i < xivMtrl.ColorSetCount; i++)
                {
                    xivMtrl.ColorSetPathOffsetList.Add(br.ReadInt16());
                    br.ReadBytes(2);

                    // add the size of the paths
                    if (i > 0)
                    {
                        pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.ColorSetPathOffsetList[i - 1]);
                    }
                    else
                    {
                        pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.MapPathOffsetList[xivMtrl.MapCount - 1]);
                    }
                }

                pathSizeList.Add(xivMtrl.TexturePathsDataSize - xivMtrl.ColorSetPathOffsetList[xivMtrl.ColorSetCount - 1]);

                var count = 0;

                // get the texture path strings
                xivMtrl.TexturePathList = new List <string>(xivMtrl.TextureCount);
                for (var i = 0; i < xivMtrl.TextureCount; i++)
                {
                    xivMtrl.TexturePathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", ""));
                    count++;
                }

                // add the textures to the TextureTypePathList
                xivMtrl.TextureTypePathList.AddRange(GetTexNames(xivMtrl.TexturePathList, _dataFile));

                // get the map path strings
                xivMtrl.MapPathList = new List <string>(xivMtrl.MapCount);
                for (var i = 0; i < xivMtrl.MapCount; i++)
                {
                    xivMtrl.MapPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", ""));
                    count++;
                }

                // get the color set path strings
                xivMtrl.ColorSetPathList = new List <string>(xivMtrl.ColorSetCount);
                for (var i = 0; i < xivMtrl.ColorSetCount; i++)
                {
                    xivMtrl.ColorSetPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", ""));
                    count++;
                }

                // If the mtrl file contains a color set, add it to the TextureTypePathList
                if (xivMtrl.ColorSetDataSize > 0)
                {
                    var ttp = new TexTypePath
                    {
                        Path     = mtrlPath.Folder + "/" + mtrlPath.File,
                        Type     = XivTexType.ColorSet,
                        DataFile = _dataFile
                    };
                    xivMtrl.TextureTypePathList.Add(ttp);
                }

                var shaderPathSize = xivMtrl.MaterialDataSize - xivMtrl.TexturePathsDataSize;

                xivMtrl.Shader = Encoding.UTF8.GetString(br.ReadBytes(shaderPathSize)).Replace("\0", "");

                xivMtrl.Unknown2 = br.ReadInt32();

                xivMtrl.ColorSetData = new List <Half>();
                for (var i = 0; i < xivMtrl.ColorSetDataSize / 2; i++)
                {
                    xivMtrl.ColorSetData.Add(new Half(br.ReadUInt16()));
                }

                xivMtrl.AdditionalDataSize = br.ReadInt16();

                xivMtrl.DataStruct1Count = br.ReadInt16();

                xivMtrl.DataStruct2Count = br.ReadInt16();

                xivMtrl.ParameterStructCount = br.ReadInt16();

                xivMtrl.ShaderNumber = br.ReadInt16();

                xivMtrl.Unknown3 = br.ReadInt16();

                xivMtrl.DataStruct1List = new List <DataStruct1>(xivMtrl.DataStruct1Count);
                for (var i = 0; i < xivMtrl.DataStruct1Count; i++)
                {
                    xivMtrl.DataStruct1List.Add(new DataStruct1 {
                        ID = br.ReadUInt32(), Unknown1 = br.ReadUInt32()
                    });
                }

                xivMtrl.DataStruct2List = new List <DataStruct2>(xivMtrl.DataStruct2Count);
                for (var i = 0; i < xivMtrl.DataStruct2Count; i++)
                {
                    xivMtrl.DataStruct2List.Add(new DataStruct2 {
                        ID = br.ReadUInt32(), Offset = br.ReadInt16(), Size = br.ReadInt16()
                    });
                }

                xivMtrl.ParameterStructList = new List <ParameterStruct>(xivMtrl.ParameterStructCount);
                for (var i = 0; i < xivMtrl.ParameterStructCount; i++)
                {
                    xivMtrl.ParameterStructList.Add(new ParameterStruct {
                        ID = br.ReadUInt32(), Unknown1 = br.ReadInt16(), Unknown2 = br.ReadInt16(), TextureIndex = br.ReadUInt32()
                    });
                }

                xivMtrl.AdditionalData = br.ReadBytes(xivMtrl.AdditionalDataSize);
            }

            return(xivMtrl);
        }