private async void ImportButton_Click(object sender, RoutedEventArgs e)
        {
            var path = PathBox.Text;

            if (String.IsNullOrWhiteSpace(path))
            {
                return;
            }

            var od     = new OpenFileDialog();
            var result = od.ShowDialog();

            if (result != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            byte[] data = null;

            var _dat   = new Dat(XivCache.GameInfo.GameDirectory);
            var _index = new Index(XivCache.GameInfo.GameDirectory);

            if (DecompressedType2.IsChecked == true)
            {
                var temp = File.ReadAllBytes(od.FileName);
                data = await _dat.CreateType2Data(temp);
            }
            else
            {
                data = File.ReadAllBytes(od.FileName);
            }

            var type = BitConverter.ToInt32(data, 4);

            if (type < 2 || type > 4)
            {
                FlexibleMessageBox.Show("Invalid Data Type.\nGeneric binary files should be imported as decompressed type 2 Data.", "Data Type Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                var dummyItem = new XivGenericItemModel();
                dummyItem.Name = Path.GetFileName(path);
                dummyItem.SecondaryCategory = "Raw File Imports";
                await _dat.WriteModFile(data, path, XivStrings.TexTools, dummyItem);
            }
            catch (Exception Ex)
            {
                FlexibleMessageBox.Show("Unable to import file.\n\nError: " + Ex.Message, "Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            FlexibleMessageBox.Show("File Imported Successfully.", "Import Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            this.Close();
        }
示例#2
0
        private static async Task SaveCharaMakeParameterSet(CharaMakeParameterSet cmp, IndexFile index = null, ModList modlist = null)
        {
            var _dat      = new Dat(XivCache.GameInfo.GameDirectory);
            var dummyItem = new XivGenericItemModel();

            dummyItem.Name = "human.cmp";
            dummyItem.SecondaryCategory = Constants.InternalModSourceName;

            await _dat.ImportType2Data(cmp.GetBytes(), HumanCmpPath, Constants.InternalModSourceName, dummyItem, index, modlist);
        }
示例#3
0
        public static async Task SaveStainingTemplateFile(StainingTemplateFile file, string applicationSource, IndexFile index = null, ModList modlist = null)
        {
            throw new NotImplementedException();
            var data = new byte[0];//file.GetBytes();

            var _dat = new Dat(XivCache.GameInfo.GameDirectory);

            var dummyItem = new XivGenericItemModel()
            {
                Name = "Equipment Staining Template",
                SecondaryCategory = "Raw Files"
            };

            await _dat.ImportType2Data(data, GearStainingTemplatePath, applicationSource, null, index, modlist);
        }
示例#4
0
        /// <summary>
        /// Saves a racial scaling entry to file.
        /// </summary>
        /// <param name="rgsp"></param>
        /// <param name=""></param>
        /// <returns></returns>
        public static async Task SaveScalingParameter(RacialGenderScalingParameter rgsp, string sourceApplication, IndexFile index = null, ModList modlist = null)
        {
            // Write the .rgsp file and let the DAT functions handle applying it.
            var rgspFilePath = GetRgspPath(rgsp.Race, rgsp.Gender);

            var bytes = rgsp.GetBytes();


            var dummyItem = new XivGenericItemModel();

            dummyItem.Name = rgsp.Race.GetDisplayName() + " - " + rgsp.Gender.ToString();
            dummyItem.SecondaryCategory = "Racial Scaling";

            var _dat = new Dat(XivCache.GameInfo.GameDirectory);
            await _dat.ImportType2Data(bytes, rgspFilePath, sourceApplication, dummyItem, index, modlist);
        }
        /// <summary>
        /// Makes a generic item model from the mod item
        /// </summary>
        /// <param name="modItem">The mod item</param>
        /// <returns>The mod item as a XivGenericItemModel</returns>
        private static XivGenericItemModel MakeItemModel(Mod modItem)
        {
            var fullPath = modItem.fullPath;

            var item = new XivGenericItemModel
            {
                Name         = modItem.name,
                ItemCategory = modItem.category,
                DataFile     = XivDataFiles.GetXivDataFile(modItem.datFile)
            };


            if (modItem.fullPath.Contains("chara/equipment") || modItem.fullPath.Contains("chara/accessory"))
            {
                item.Category  = XivStrings.Gear;
                item.ModelInfo = new XivModelInfo
                {
                    ModelID = int.Parse(fullPath.Substring(17, 4))
                };
            }


            if (modItem.fullPath.Contains("chara/weapon"))
            {
                item.Category  = XivStrings.Gear;
                item.ModelInfo = new XivModelInfo
                {
                    ModelID = int.Parse(fullPath.Substring(14, 4))
                };
            }

            if (modItem.fullPath.Contains("chara/human"))
            {
                item.Category = XivStrings.Character;


                if (item.Name.Equals(XivStrings.Body))
                {
                    item.ModelInfo = new XivModelInfo
                    {
                        ModelID = int.Parse(fullPath.Substring(fullPath.IndexOf("/body", StringComparison.Ordinal) + 7, 4))
                    };
                }
                else if (item.Name.Equals(XivStrings.Hair))
                {
                    item.ModelInfo = new XivModelInfo
                    {
                        ModelID = int.Parse(fullPath.Substring(fullPath.IndexOf("/hair", StringComparison.Ordinal) + 7, 4))
                    };
                }
                else if (item.Name.Equals(XivStrings.Face))
                {
                    item.ModelInfo = new XivModelInfo
                    {
                        ModelID = int.Parse(fullPath.Substring(fullPath.IndexOf("/face", StringComparison.Ordinal) + 7, 4))
                    };
                }
                else if (item.Name.Equals(XivStrings.Tail))
                {
                    item.ModelInfo = new XivModelInfo
                    {
                        ModelID = int.Parse(fullPath.Substring(fullPath.IndexOf("/tail", StringComparison.Ordinal) + 7, 4))
                    };
                }
            }

            if (modItem.fullPath.Contains("chara/common"))
            {
                item.Category = XivStrings.Character;

                if (item.Name.Equals(XivStrings.Face_Paint))
                {
                    item.ModelInfo = new XivModelInfo
                    {
                        ModelID = int.Parse(fullPath.Substring(fullPath.LastIndexOf("_", StringComparison.Ordinal) + 1, 1))
                    };
                }
                else if (item.Name.Equals(XivStrings.Equip_Decals))
                {
                    item.ModelInfo = new XivModelInfo
                    {
                        ModelID = int.Parse(fullPath.Substring(fullPath.LastIndexOf("_", StringComparison.Ordinal) + 1, 3))
                    };
                }
            }

            if (modItem.fullPath.Contains("chara/monster"))
            {
                item.Category = XivStrings.Companions;

                item.ModelInfo = new XivModelInfo
                {
                    ModelID = int.Parse(fullPath.Substring(15, 4)),
                    Body    = int.Parse(fullPath.Substring(fullPath.IndexOf("/body", StringComparison.Ordinal) + 7, 4))
                };
            }

            if (modItem.fullPath.Contains("chara/demihuman"))
            {
                item.Category = XivStrings.Companions;

                item.ModelInfo = new XivModelInfo
                {
                    Body    = int.Parse(fullPath.Substring(17, 4)),
                    ModelID = int.Parse(fullPath.Substring(fullPath.IndexOf("t/e", StringComparison.Ordinal) + 3, 4))
                };
            }

            if (modItem.fullPath.Contains("ui/"))
            {
                item.Category = XivStrings.UI;

                if (modItem.fullPath.Contains("ui/uld") || modItem.fullPath.Contains("ui/map"))
                {
                    item.ModelInfo = new XivModelInfo
                    {
                        ModelID = 0
                    };
                }
                else
                {
                    item.ModelInfo = new XivModelInfo
                    {
                        ModelID = int.Parse(fullPath.Substring(fullPath.LastIndexOf("/", StringComparison.Ordinal) + 1,
                                                               6))
                    };
                }
            }

            if (modItem.fullPath.Contains("/hou/"))
            {
                item.Category = XivStrings.Housing;

                item.ModelInfo = new XivModelInfo
                {
                    ModelID = int.Parse(fullPath.Substring(fullPath.LastIndexOf("_m", StringComparison.Ordinal) + 2, 3))
                };
            }

            return(item);
        }
示例#6
0
        /// <summary>
        /// Gets the materials for the model
        /// </summary>
        /// <returns>A dictionary containing the mesh number(key) and the associated texture data (value)</returns>
        public static Dictionary <int, ModelTextureData> GetMaterials(
            DirectoryInfo gameDirectory, IItemModel item, XivMdl mdlData, XivRace race)
        {
            var      textureDataDictionary = new Dictionary <int, ModelTextureData>();
            var      mtrlDictionary        = new Dictionary <int, XivMtrl>();
            var      mtrl                 = new Mtrl(gameDirectory, item.DataFile);
            var      mtrlFilePaths        = mdlData.PathData.MaterialList;
            var      hasColorChangeShader = false;
            Color?   customColor          = null;
            WinColor winColor;

            var materialNum = 0;

            foreach (var mtrlFilePath in mtrlFilePaths)
            {
                var mtrlItem = new XivGenericItemModel
                {
                    Category        = item.Category,
                    ItemCategory    = item.ItemCategory,
                    ItemSubCategory = item.ItemSubCategory,
                    ModelInfo       = new XivModelInfo
                    {
                        Body      = item.ModelInfo.Body,
                        ModelID   = item.ModelInfo.ModelID,
                        ModelType = item.ModelInfo.ModelType,
                        Variant   = item.ModelInfo.Variant
                    },
                    Name = item.Name
                };

                var modelID  = mtrlItem.ModelInfo.ModelID;
                var bodyID   = mtrlItem.ModelInfo.Body;
                var filePath = mtrlFilePath;

                if (!filePath.Contains("hou") && mtrlFilePath.Count(x => x == '/') > 1)
                {
                    filePath = mtrlFilePath.Substring(mtrlFilePath.LastIndexOf("/"));
                }

                var typeChar = $"{mtrlFilePath[4]}{mtrlFilePath[9]}";

                var raceString = "";
                switch (typeChar)
                {
                // Character Body
                case "cb":
                    var body = mtrlFilePath.Substring(mtrlFilePath.IndexOf("b") + 1, 4);
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    if (!raceString.Equals("0901") && !raceString.Equals("1001") && !raceString.Equals("1101"))
                    {
                        var gender = 0;
                        if (int.Parse(raceString.Substring(0, 2)) % 2 == 0)
                        {
                            gender = 1;
                        }

                        var settingsRace = GetSettingsRace(gender);

                        race = settingsRace.Race;

                        filePath = mtrlFilePath.Replace(raceString, race.GetRaceCode()).Replace(body, settingsRace.BodyID);

                        body = settingsRace.BodyID;
                    }


                    mtrlItem = new XivGenericItemModel
                    {
                        Category     = XivStrings.Character,
                        ItemCategory = XivStrings.Body,
                        Name         = XivStrings.Body,
                        ModelInfo    = new XivModelInfo
                        {
                            Body = int.Parse(body)
                        }
                    };

                    winColor    = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Skin_Color);
                    customColor = new Color(winColor.R, winColor.G, winColor.B, winColor.A);

                    break;

                // Face
                case "cf":
                    bodyID     = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("f") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem = new XivGenericItemModel
                    {
                        Category     = XivStrings.Character,
                        ItemCategory = XivStrings.Face,
                        Name         = XivStrings.Face,
                        ModelInfo    = new XivModelInfo
                        {
                            Body = bodyID
                        }
                    };

                    break;

                // Hair
                case "ch":
                    bodyID     = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("h") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem = new XivGenericItemModel
                    {
                        Category     = XivStrings.Character,
                        ItemCategory = XivStrings.Hair,
                        Name         = XivStrings.Hair,
                        ModelInfo    = new XivModelInfo
                        {
                            Body = bodyID
                        }
                    };

                    winColor    = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Hair_Color);
                    customColor = new Color(winColor.R, winColor.G, winColor.B, winColor.A);

                    break;

                // Tail
                case "ct":
                    var tempPath = mtrlFilePath.Substring(4);
                    bodyID     = int.Parse(tempPath.Substring(tempPath.IndexOf("t") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem = new XivGenericItemModel
                    {
                        Category     = XivStrings.Character,
                        ItemCategory = XivStrings.Tail,
                        Name         = XivStrings.Tail,
                        ModelInfo    = new XivModelInfo
                        {
                            Body = bodyID
                        }
                    };

                    winColor    = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Hair_Color);
                    customColor = new Color(winColor.R, winColor.G, winColor.B, winColor.A);

                    break;

                // Equipment
                case "ce":
                    modelID    = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("e") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem.ModelInfo.ModelID = modelID;
                    break;

                // Accessory
                case "ca":
                    modelID    = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("a") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem.ModelInfo.ModelID = modelID;
                    break;

                // Weapon
                case "wb":
                    modelID = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("w") + 1, 4));
                    bodyID  = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("b") + 1, 4));
                    mtrlItem.ModelInfo.ModelID = modelID;
                    mtrlItem.ModelInfo.Body    = bodyID;
                    break;

                // Monster
                case "mb":
                    modelID = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("_m") + 2, 4));
                    bodyID  = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("b") + 1, 4));
                    mtrlItem.ModelInfo.ModelID = modelID;
                    mtrlItem.ModelInfo.Body    = bodyID;
                    break;

                // DemiHuman
                case "de":
                    modelID = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("d") + 1, 4));
                    bodyID  = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("e") + 1, 4));
                    mtrlItem.ModelInfo.ModelID = modelID;
                    mtrlItem.ModelInfo.Body    = bodyID;
                    break;

                default:
                    break;
                }

                var dxVersion = int.Parse(Settings.Default.DX_Version);

                var     mtrlFile = filePath.Remove(0, 1);
                XivMtrl mtrlData;
                try
                {
                    mtrlData = mtrl.GetMtrlData(mtrlItem, race, mtrlFile, dxVersion);
                }
                catch (Exception)
                {
                    if (mtrlItem.ModelInfo.ModelID == item.ModelInfo.ModelID)
                    {
                        throw;
                    }

                    // Fall back to material data from the primary model.
                    mtrlData = mtrl.GetMtrlData(item, race, mtrlFile, dxVersion);
                }


                if (mtrlData.Shader.Contains("colorchange"))
                {
                    hasColorChangeShader = true;
                }

                mtrlDictionary.Add(materialNum, mtrlData);

                materialNum++;
            }

            foreach (var xivMtrl in mtrlDictionary)
            {
                var modelTexture = new ModelTexture(gameDirectory, xivMtrl.Value);

                if (hasColorChangeShader)
                {
                    var modelMaps = modelTexture.GetModelMaps(null, true);

                    textureDataDictionary.Add(xivMtrl.Key, modelMaps);
                }
                else
                {
                    if (item.ItemCategory.Equals(XivStrings.Face))
                    {
                        var path = xivMtrl.Value.MTRLPath;

                        if (path.Contains("_iri_"))
                        {
                            winColor = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Iris_Color);
                        }
                        else if (path.Contains("_etc_"))
                        {
                            winColor = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Etc_Color);
                        }
                        else
                        {
                            winColor = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Skin_Color);
                        }

                        customColor = new Color(winColor.R, winColor.G, winColor.B, winColor.A);
                    }

                    var modelMaps = modelTexture.GetModelMaps(customColor);

                    textureDataDictionary.Add(xivMtrl.Key, modelMaps);
                }
            }

            return(textureDataDictionary);
        }
        /// <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);
            }
        }
        /// <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);
            }
        }