Example #1
0
        /// <summary>
        /// Gets the Icon info for a specific gear item
        /// </summary>
        /// <param name="gearItem">The gear item</param>
        /// <returns>A list of TexTypePath containing Icon Info</returns>
        public async Task <List <TexTypePath> > GetItemIcons(IItemModel iconItem)
        {
            var  type       = iconItem.GetType();
            uint iconNumber = 0;

            if (type == typeof(XivGear))
            {
                iconNumber = ((XivGear)iconItem).IconNumber;
            }
            else if (type == typeof(XivFurniture))
            {
                iconNumber = ((XivFurniture)iconItem).IconNumber;
            }

            if (iconNumber <= 0)
            {
                return(new List <TexTypePath>());
            }

            var iconString = iconNumber.ToString();

            var ttpList = new List <TexTypePath>();


            var iconBaseNum  = iconString.Substring(0, 2).PadRight(iconString.Length, '0');
            var iconFolder   = $"ui/icon/{iconBaseNum.PadLeft(6, '0')}";
            var iconHQFolder = $"{iconFolder}/hq";
            var iconFile     = $"{iconString.PadLeft(6, '0')}.tex";

            var path = iconFolder + "/" + iconFile;

            if (await _index.FileExists(path, XivDataFile._06_Ui))
            {
                ttpList.Add(new TexTypePath
                {
                    Name     = "Icon",
                    Path     = $"{iconFolder}/{iconFile}",
                    Type     = XivTexType.Icon,
                    DataFile = XivDataFile._06_Ui
                });
            }


            path = iconHQFolder + "/" + iconFile;
            if (await _index.FileExists(path, XivDataFile._06_Ui))
            {
                ttpList.Add(new TexTypePath
                {
                    Name     = "HQ Icon",
                    Path     = $"{iconHQFolder}/{iconFile}",
                    Type     = XivTexType.Icon,
                    DataFile = XivDataFile._06_Ui
                });
            }

            return(ttpList);
        }
Example #2
0
        private async Task DoCopy()
        {
            var from = FromBox.Text;
            var to   = ToBox.Text;

            if (String.IsNullOrWhiteSpace(to) || String.IsNullOrWhiteSpace(to))
            {
                return;
            }

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


            try
            {
                var exists = await _index.FileExists(from);

                if (!exists)
                {
                    throw new InvalidDataException("Source file does not exist.");
                }

                exists = await _index.FileExists(to);

                if (exists)
                {
                    var cancel = false;
                    Dispatcher.Invoke(() =>
                    {
                        var result = FlexibleMessageBox.Show("Destination file already exists.  Overwrite?", "Overwrite Confirmation", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Warning);
                        cancel     = result == System.Windows.Forms.DialogResult.No;
                    });

                    if (cancel)
                    {
                        return;
                    }
                }

                await _dat.CopyFile(from, to, XivStrings.TexTools, true);

                Dispatcher.Invoke(() =>
                {
                    FlexibleMessageBox.Show("File Copied Successfully.", "Copy Success", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
                    Close();
                });
            } catch (Exception ex)
            {
                FlexibleMessageBox.Show("File Copy Failed:\n" + ex.Message, "Copy Failure", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }
Example #3
0
        private async Task <bool> AddFile(string file)
        {
            var _index = new Index(XivCache.GameInfo.GameDirectory);

            if (Path.GetExtension(file) != ".meta")
            {
                if (!(await _index.FileExists(file)))
                {
                    // File doesn't actually exist, can't be added.
                    return(false);
                }
            }

            var match = _suffixRegex.Match(file);

            if (match.Success && match.Groups[1].Value == "mdl")
            {
                ModelListBox.Items.Add(new StandardModpackFileSelect.FileEntry(file));
            }
            else if (match.Success && (match.Groups[1].Value == "mtrl" || match.Groups[1].Value == "avfx"))
            {
                MaterialListBox.Items.Add(new StandardModpackFileSelect.FileEntry(file));
            }
            else if (match.Success && (match.Groups[1].Value == "tex" || match.Groups[1].Value == "atex"))
            {
                TextureListBox.Items.Add(new StandardModpackFileSelect.FileEntry(file));
            }
            else
            {
                MetaListBox.Items.Add(new StandardModpackFileSelect.FileEntry(file));
            }
            return(true);
        }
        public async Task <char> GetNewMaterialIdentifier()
        {
            // Get new Material Identifier
            var           alphabet = Constants.Alphabet;
            List <string> partList = new List <string>();

            var materialIdentifier = _material.GetMaterialIdentifier();

            var newIdentifier = '\0';
            var rex           = new Regex("_([a-z0-9])\\.mtrl");

            if (!rex.IsMatch(_material.MTRLPath))
            {
                return('a');
            }
            for (var i = 1; i < alphabet.Length; i++)
            {
                var identifier = alphabet[i];
                var newPath    = Regex.Replace(_material.MTRLPath, "_([a-z0-9])\\.mtrl", "_" + identifier + ".mtrl");
                var exists     = await _index.FileExists(newPath);

                if (!exists)
                {
                    return(identifier);
                }
            }

            // No empty material names left.
            // Note - This can be fixed.  Materials don't need to be named a-z, but realisitcally is anyone going to have more than 26 materials?
            if (newIdentifier == '\0')
            {
                if (materialIdentifier == '\0')
                {
                    newIdentifier = 'a';
                }
                else
                {
                    throw new NotSupportedException("Maximum Material Limit Reached.");
                }
            }
            return(newIdentifier);
        }
        private async Task CreateBasic()
        {
            string modPackPath = Path.Combine(Properties.Settings.Default.ModPack_Directory, $"{ViewModel.Name}.ttmp2");

            if (File.Exists(modPackPath))
            {
                DialogResult overwriteDialogResult = FlexibleMessageBox.Show(new Wpf32Window(this), UIMessages.ModPackOverwriteMessage,
                                                                             UIMessages.OverwriteTitle, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                if (overwriteDialogResult != System.Windows.Forms.DialogResult.Yes)
                {
                    return;
                }
            }

            TTMP texToolsModPack = new TTMP(new DirectoryInfo(Settings.Default.ModPack_Directory), XivStrings.TexTools);
            var  index           = new Index(XivCache.GameInfo.GameDirectory);
            var  dat             = new Dat(XivCache.GameInfo.GameDirectory);
            var  modding         = new Modding(XivCache.GameInfo.GameDirectory);
            var  ModList         = modding.GetModList();

            SimpleModPackData simpleModPackData = new SimpleModPackData
            {
                Name              = ViewModel.Name,
                Author            = ViewModel.Author,
                Version           = ViewModel.Version,
                Description       = ViewModel.Description,
                Url               = ViewModel.Url,
                SimpleModDataList = new List <SimpleModData>()
            };

            foreach (var entry in ViewModel.Entries)
            {
                foreach (var file in entry.AllFiles)
                {
                    var exists = await index.FileExists(file);

                    // This is a funny case where in order to create the modpack we actually have to write a default meta entry to the dats first.
                    // If we had the right functions we could just load and serialize the data, but we don't atm.
                    if (!exists && Path.GetExtension(file) == ".meta")
                    {
                        var meta = await ItemMetadata.GetMetadata(file);

                        await ItemMetadata.SaveMetadata(meta, XivStrings.TexTools);
                    }

                    var offset = await index.GetDataOffset(file);

                    var dataFile       = IOUtil.GetDataFileFromPath(file);
                    var compressedSize = await dat.GetCompressedFileSize(offset, dataFile);

                    var modEntry = ModList.Mods.FirstOrDefault(x => x.fullPath == file);
                    var modded   = modEntry != null && modEntry.enabled == true;


                    SimpleModData simpleData = new SimpleModData
                    {
                        Name      = entry.Item.Name,
                        Category  = entry.Item.SecondaryCategory,
                        FullPath  = file,
                        ModOffset = offset,
                        ModSize   = compressedSize,
                        IsDefault = !modded,
                        DatFile   = dataFile.GetDataFileName()
                    };

                    simpleModPackData.SimpleModDataList.Add(simpleData);
                }
            }



            try
            {
                await LockUi(UIStrings.Creating_Modpack, null, null);

                Progress <(int current, int total, string message)> progressIndicator = new Progress <(int current, int total, string message)>(ReportProgress);
                await texToolsModPack.CreateSimpleModPack(simpleModPackData, XivCache.GameInfo.GameDirectory, progressIndicator, true);

                FlexibleMessageBox.Show(new Wpf32Window(this), "Modpack Created Successfully.",
                                        "Modpack Created", MessageBoxButtons.OK, MessageBoxIcon.Information);
                await UnlockUi(this);

                DialogResult = true;
            }
            catch (Exception ex)
            {
                FlexibleMessageBox.Show(new Wpf32Window(this), "An Error occured while creating the modpack.\n\n" + ex.Message,
                                        "Modpack Creation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                await UnlockUi(this);
            }
        }
        private async Task CreateAdvanced()
        {
            string modPackPath = Path.Combine(Properties.Settings.Default.ModPack_Directory, $"{ViewModel.Name}.ttmp2");

            if (File.Exists(modPackPath))
            {
                DialogResult overwriteDialogResult = FlexibleMessageBox.Show(new Wpf32Window(this), UIMessages.ModPackOverwriteMessage,
                                                                             UIMessages.OverwriteTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (overwriteDialogResult != System.Windows.Forms.DialogResult.Yes)
                {
                    return;
                }
            }

            await LockUi(UIStrings.Creating_Modpack, null, null);

            try
            {
                TTMP texToolsModPack = new TTMP(new DirectoryInfo(Settings.Default.ModPack_Directory), XivStrings.TexTools);
                var  index           = new Index(XivCache.GameInfo.GameDirectory);
                var  dat             = new Dat(XivCache.GameInfo.GameDirectory);
                var  modding         = new Modding(XivCache.GameInfo.GameDirectory);
                var  ModList         = modding.GetModList();

                var wizardData = new ModPackData()
                {
                    Name         = ViewModel.Name,
                    Author       = ViewModel.Author,
                    Version      = ViewModel.Version,
                    Description  = ViewModel.Description,
                    Url          = ViewModel.Url,
                    ModPackPages = new List <ModPackData.ModPackPage>()
                };

                var page = new ModPackData.ModPackPage()
                {
                    PageIndex = 1,
                    ModGroups = new List <ModGroup>()
                };

                wizardData.ModPackPages.Add(page);


                foreach (var e in ViewModel.Entries)
                {
                    var item  = e.Item;
                    var files = e.AllFiles;

                    var group = new ModGroup()
                    {
                        GroupName     = item.Name,
                        SelectionType = "Multi",
                        OptionList    = new List <ModOption>()
                    };
                    page.ModGroups.Add(group);

                    var option = new ModOption
                    {
                        GroupName     = group.GroupName,
                        IsChecked     = true,
                        Name          = GetNiceLevelName(e.Level, true, true),
                        Description   = "Item: " + item.Name + "\nInclusion Level: " + GetNiceLevelName(e.Level) + "\nPrimary Files:" + e.MainFiles.Count + "\nTotal Files:" + e.AllFiles.Count,
                        SelectionType = "Multi",
                    };
                    group.OptionList.Add(option);

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

                        // This is a funny case where in order to create the modpack we actually have to write a default meta entry to the dats first.
                        // If we had the right functions we could just load and serialize the data, but we don't atm.
                        if (!exists && Path.GetExtension(file) == ".meta")
                        {
                            var meta = await ItemMetadata.GetMetadata(file);

                            await ItemMetadata.SaveMetadata(meta, XivStrings.TexTools);
                        }

                        var offset = await index.GetDataOffset(file);

                        var dataFile       = IOUtil.GetDataFileFromPath(file);
                        var compressedSize = await dat.GetCompressedFileSize(offset, dataFile);

                        var modEntry = ModList.Mods.FirstOrDefault(x => x.fullPath == file);
                        var modded   = modEntry != null && modEntry.enabled == true;

                        var fData = new ModData
                        {
                            Name         = e.Item.Name,
                            Category     = e.Item.SecondaryCategory,
                            FullPath     = file,
                            IsDefault    = !modded,
                            ModDataBytes = dat.GetRawData(offset, dataFile, compressedSize)
                        };
                        option.Mods.Add(file, fData);
                    }
                }

                // Okay modpack is now created internally, just need to save it.
                var progressIndicator = new Progress <double>(ReportProgressAdv);
                await texToolsModPack.CreateWizardModPack(wizardData, progressIndicator, true);

                FlexibleMessageBox.Show(new Wpf32Window(this), "Modpack Created Successfully.",
                                        "Modpack Created", MessageBoxButtons.OK, MessageBoxIcon.Information);
                await UnlockUi(this);

                DialogResult = true;
            } catch (Exception ex)
            {
                FlexibleMessageBox.Show(new Wpf32Window(this), "An Error occured while creating the modpack.\n\n" + ex.Message,
                                        "Modpack Creation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                await UnlockUi(this);
            }
        }
        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));
            }
        }
Example #8
0
        /// <summary>
        /// Saves a set of IMC entries to file.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="entries"></param>
        /// <returns></returns>
        internal async Task SaveEntries(string path, string slot, List <XivImc> entries, IItem referenceItem = null, IndexFile cachedIndexFile = null, ModList cachedModList = null)
        {
            var dat   = new Dat(_gameDirectory);
            var index = new Index(_gameDirectory);

            var exists = await index.FileExists(path);

            FullImcInfo info;

            if (exists)
            {
                info = await GetFullImcInfo(path, cachedIndexFile, cachedModList);
            }
            else
            {
                var ri = XivDependencyGraph.ExtractRootInfo(path);
                if (ri.SecondaryType == null)
                {
                    info = new FullImcInfo()
                    {
                        DefaultSubset = new List <XivImc>()
                        {
                            new XivImc(), new XivImc(), new XivImc(), new XivImc(), new XivImc()
                        },
                        SubsetList     = new List <List <XivImc> >(),
                        TypeIdentifier = ImcType.Set
                    };
                }
                else
                {
                    info = new FullImcInfo()
                    {
                        DefaultSubset = new List <XivImc>()
                        {
                            new XivImc()
                        },
                        SubsetList     = new List <List <XivImc> >(),
                        TypeIdentifier = ImcType.NonSet
                    };
                }
            }


            for (int i = 0; i < entries.Count; i++)
            {
                XivImc e;
                if (i >= info.SubsetCount + 1)
                {
                    e = new XivImc();
                }
                else
                {
                    e = info.GetEntry(i, slot);
                }
                e.Mask        = entries[i].Mask;
                e.Decal       = entries[i].Decal;
                e.Vfx         = entries[i].Vfx;
                e.Animation   = entries[i].Animation;
                e.MaterialSet = entries[i].MaterialSet;

                if (i >= info.SubsetCount + 1)
                {
                    info.SetEntry(e, i, slot, true);
                }
            }

            // Save the modified info.
            await SaveFullImcInfo(info, path, Constants.InternalModSourceName, referenceItem, cachedIndexFile, cachedModList);
        }
        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...";
            }
        }