/// <summary>
        /// The event handler for the advanced options button clicked
        /// </summary>
        private async void AdvOptionsButton_Click(object sender, RoutedEventArgs e)
        {
            var selectedItem = ModelTypeComboBox.SelectedItem as ModComboBox;

            var mod = selectedItem.SelectedMod;

            var includedMod = new IncludedMods
            {
                Name     = $"{Path.GetFileNameWithoutExtension(mod.fullPath)} ({((Category)ModListTreeView.SelectedItem).Name})",
                FullPath = mod.fullPath
            };

            var itemModel = MakeItemModel(mod);

            var includedModsList = IncludedModsList.Items.Cast <IncludedMods>().ToList();
            var mdl = new Mdl(_gameDirectory, XivDataFiles.GetXivDataFile(mod.datFile));

            try
            {
                // TODO - Include Submesh ID ?
                // Do we even have any kind of UI To specify this in the wizard?
                // Submeshes are only used for Furniture anyways, so it might be a 'will not fix'
                bool success = await ImportModelView.ImportModel(itemModel, IOUtil.GetRaceFromPath(mod.fullPath), null, this, null, true);

                if (!success)
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                FlexibleMessageBox.Show(ex.Message, UIMessages.AdvancedImportErrorTitle,
                                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var mdlData = ImportModelView.GetData();

            if (includedModsList.Any(item => item.Name.Equals(includedMod.Name)))
            {
                if (FlexibleMessageBox.Show(
                        string.Format(UIMessages.ExistingOption, includedMod.Name),
                        UIMessages.OverwriteTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    System.Windows.Forms.DialogResult.Yes)
                {
                    _selectedModOption.Mods[mod.fullPath].ModDataBytes = mdlData;
                }
            }
            else
            {
                IncludedModsList.Items.Add(includedMod);
                _selectedModOption.Mods.Add(mod.fullPath, new ModData
                {
                    Name         = mod.name,
                    Category     = mod.category,
                    FullPath     = mod.fullPath,
                    ModDataBytes = mdlData,
                });
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Toggles all mods on or off
        /// </summary>
        /// <param name="enable">The status to switch the mods to True if enable False if disable</param>
        public void ToggleAllMods(bool enable)
        {
            var index = new Index(_gameDirectory);

            var modList = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(ModListDirectory.FullName));

            if (modList == null || modList.modCount == 0)
            {
                return;
            }

            foreach (var modEntry in modList.Mods)
            {
                if (enable && !modEntry.enabled)
                {
                    index.UpdateIndex(modEntry.data.modOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                    index.UpdateIndex2(modEntry.data.modOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                    modEntry.enabled = true;
                }
                else if (!enable && modEntry.enabled)
                {
                    index.UpdateIndex(modEntry.data.originalOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                    index.UpdateIndex2(modEntry.data.originalOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                    modEntry.enabled = false;
                }
            }

            File.WriteAllText(ModListDirectory.FullName, JsonConvert.SerializeObject(modList, Formatting.Indented));
        }
        /// <summary>
        /// The event handler for the add current material button clicked
        /// </summary>
        private void AddCurrentMaterialButton_Click(object sender, RoutedEventArgs e)
        {
            var dat = new Dat(_gameDirectory);

            var selectedItem = MaterialComboBox.SelectedItem as ModComboBox;

            var mod = selectedItem.SelectedMod;

            var includedMod = new IncludedMods
            {
                Name     = $"{Path.GetFileNameWithoutExtension(mod.fullPath)} ({((Category)ModListTreeView.SelectedItem).Name})",
                FullPath = mod.fullPath
            };

            var includedModsList = IncludedModsList.Items.Cast <IncludedMods>().ToList();

            if (includedModsList.Any(item => item.Name.Equals(includedMod.Name)))
            {
                if (FlexibleMessageBox.Show(
                        string.Format(UIMessages.ExistingOption, includedMod.Name),
                        UIMessages.OverwriteTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    System.Windows.Forms.DialogResult.Yes)
                {
                    var rawData = dat.GetRawData(mod.data.modOffset, XivDataFiles.GetXivDataFile(mod.datFile), mod.data.modSize);

                    if (rawData == null)
                    {
                        FlexibleMessageBox.Show(
                            string.Format(UIMessages.RawDataErrorMessage, mod.data.modOffset, mod.datFile),
                            UIMessages.ModDataReadErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    _selectedModOption.Mods[mod.fullPath].ModDataBytes = rawData;
                }
            }
            else
            {
                var rawData = dat.GetRawData(mod.data.modOffset, XivDataFiles.GetXivDataFile(mod.datFile), mod.data.modSize);

                if (rawData == null)
                {
                    FlexibleMessageBox.Show(
                        string.Format(UIMessages.RawDataErrorMessage, mod.data.modOffset, mod.datFile),
                        UIMessages.ModDataReadErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                var modData = new ModData
                {
                    Name         = mod.name,
                    Category     = mod.category,
                    FullPath     = mod.fullPath,
                    ModDataBytes = rawData,
                };

                IncludedModsList.Items.Add(includedMod);
                _selectedModOption.Mods.Add(mod.fullPath, modData);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Toggles the mod on or off
        /// </summary>
        /// <param name="internalFilePath">The internal file path of the mod</param>
        /// <param name="enable">The status of the mod</param>
        public void ToggleModStatus(string internalFilePath, bool enable)
        {
            var index = new Index(_gameDirectory);

            var modEntry = TryGetModEntry(internalFilePath);

            if (modEntry == null)
            {
                throw new Exception("Unable to find mod entry in modlist.");
            }

            if (enable)
            {
                index.UpdateIndex(modEntry.data.modOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                index.UpdateIndex2(modEntry.data.modOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));
            }
            else
            {
                index.UpdateIndex(modEntry.data.originalOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                index.UpdateIndex2(modEntry.data.originalOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));
            }

            var modListDirectory = new DirectoryInfo(Path.Combine(_gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath));

            var modList = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(modListDirectory.FullName));

            var entryEnableUpdate = (from entry in modList.Mods
                                     where entry.fullPath.Equals(modEntry.fullPath)
                                     select entry).FirstOrDefault();

            entryEnableUpdate.enabled = enable;

            File.WriteAllText(modListDirectory.FullName, JsonConvert.SerializeObject(modList, Formatting.Indented));
        }
Esempio n. 5
0
        /// <summary>
        /// Toggles the mod on or off
        /// </summary>
        /// <param name="internalFilePath">The internal file path of the mod</param>
        /// <param name="enable">The status of the mod</param>
        public async Task ToggleModStatus(string internalFilePath, bool enable)
        {
            if (string.IsNullOrEmpty(internalFilePath))
            {
                throw new Exception("File Path missing, unable to toggle mod.");
            }

            var modEntry = await TryGetModEntry(internalFilePath);

            if (modEntry == null)
            {
                throw new Exception("Unable to find mod entry in modlist.");
            }

            if (enable)
            {
                await Index.UpdateIndex(modEntry.data.modOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));

                await Index.UpdateIndex2(modEntry.data.modOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));
            }
            else
            {
                await Index.UpdateIndex(modEntry.data.originalOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));

                await Index.UpdateIndex2(modEntry.data.originalOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));
            }

            var modList = GetModList();

            var entryEnableUpdate = modList.Mods.Find(m => m.fullPath == modEntry.fullPath);

            entryEnableUpdate.enabled = enable;

            WriteModList(modList);
        }
        /// <summary>
        /// The event handler for the add custom texture button clicked
        /// </summary>
        private async void AddCustomTextureButton_Click(object sender, RoutedEventArgs e)
        {
            var selectedItem = TextureMapComboBox.SelectedItem as ModComboBox;

            var mod = selectedItem.SelectedMod;

            byte[] modData;

            var includedMod = new IncludedMods
            {
                Name     = $"{Path.GetFileNameWithoutExtension(mod.fullPath)} ({((Category)ModListTreeView.SelectedItem).Name})",
                FullPath = mod.fullPath
            };

            var includedModsList = IncludedModsList.Items.Cast <IncludedMods>().ToList();

            var tex = new Tex(_gameDirectory);

            var ddsDirectory = new DirectoryInfo(CustomTextureTextBox.Text);

            if (selectedItem.TexTypePath.Type == XivTexType.ColorSet)
            {
                var mtrl = new Mtrl(_gameDirectory, XivDataFiles.GetXivDataFile(mod.datFile), GetLanguage());

                var xivMtrl = await mtrl.GetMtrlData(mod.data.modOffset, mod.fullPath, int.Parse(Settings.Default.DX_Version));

                modData = tex.DDStoMtrlData(xivMtrl, ddsDirectory, ((Category)ModListTreeView.SelectedItem).Item, GetLanguage());
            }
            else
            {
                var texData = await tex.GetTexData(selectedItem.TexTypePath);

                modData = await tex.DDStoTexData(texData, ((Category)ModListTreeView.SelectedItem).Item, ddsDirectory);
            }

            if (includedModsList.Any(item => item.Name.Equals(includedMod.Name)))
            {
                if (FlexibleMessageBox.Show(
                        string.Format(UIMessages.ExistingOption, includedMod.Name),
                        UIMessages.OverwriteTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    System.Windows.Forms.DialogResult.Yes)
                {
                    _selectedModOption.Mods[mod.fullPath].ModDataBytes = modData;
                }
            }
            else
            {
                IncludedModsList.Items.Add(includedMod);
                _selectedModOption.Mods.Add(mod.fullPath, new ModData
                {
                    Name         = mod.name,
                    Category     = mod.category,
                    FullPath     = mod.fullPath,
                    ModDataBytes = modData
                });
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Checks to see whether the mod is currently enabled
        /// </summary>
        /// <param name="internalPath">The internal path of the file</param>
        /// <param name="dataFile">The data file to check in</param>
        /// <param name="indexCheck">Flag to determine whether to check the index file or just the modlist</param>
        /// <returns></returns>
        public async Task <XivModStatus> IsModEnabled(string internalPath, bool indexCheck)
        {
            if (!File.Exists(ModListDirectory.FullName))
            {
                return(XivModStatus.Original);
            }

            if (indexCheck)
            {
                var index = new Index(_gameDirectory);

                var modEntry = await TryGetModEntry(internalPath);

                if (modEntry == null)
                {
                    return(XivModStatus.Original);
                }

                var originalOffset = modEntry.data.originalOffset;
                var moddedOffset   = modEntry.data.modOffset;

                var offset = await index.GetDataOffset(
                    HashGenerator.GetHash(Path.GetDirectoryName(internalPath).Replace("\\", "/")),
                    HashGenerator.GetHash(Path.GetFileName(internalPath)),
                    XivDataFiles.GetXivDataFile(modEntry.datFile));

                if (offset.Equals(originalOffset))
                {
                    return(XivModStatus.Disabled);
                }

                if (offset.Equals(moddedOffset))
                {
                    return(XivModStatus.Enabled);
                }

                throw new Exception("Offset in Index does not match either original or modded offset in modlist.");
            }
            else
            {
                var modEntry = await TryGetModEntry(internalPath);

                if (modEntry == null)
                {
                    return(XivModStatus.Original);
                }
                // If modEntry not null but modded offset and original offset are the same as is the case with matadd textures
                if (modEntry.data.modOffset == modEntry.data.originalOffset)
                {
                    // Return original to disable the disable/enable button as there's nothing to toggle between
                    return(XivModStatus.MatAdd);
                }

                return(modEntry.enabled ? XivModStatus.Enabled : XivModStatus.Disabled);
            }
        }
        /// <summary>
        /// The event handler for the custom model button clicked
        /// </summary>
        private async void AddCustomModelButton_Click(object sender, RoutedEventArgs e)
        {
            var selectedItem = ModelTypeComboBox.SelectedItem as ModComboBox;

            var mod = selectedItem.SelectedMod;

            var includedMod = new IncludedMods
            {
                Name     = $"{Path.GetFileNameWithoutExtension(mod.fullPath)} ({((Category)ModListTreeView.SelectedItem).Name})",
                FullPath = mod.fullPath
            };

            var itemModel = MakeItemModel(mod);

            var includedModsList = IncludedModsList.Items.Cast <IncludedMods>().ToList();
            var mdl    = new Mdl(_gameDirectory, XivDataFiles.GetXivDataFile(mod.datFile));
            var xivMdl = await mdl.GetMdlData(itemModel, GetRace(mod.fullPath), null, null, mod.data.originalOffset);

            var warnings = await mdl.ImportModel(itemModel, xivMdl, new DirectoryInfo(CustomModelTextBox.Text), null, XivStrings.TexTools,
                                                 Settings.Default.DAE_Plugin_Target, true);

            if (warnings.Count > 0)
            {
                foreach (var warning in warnings)
                {
                    FlexibleMessageBox.Show(
                        $"{warning.Value}", $"{warning.Key}",
                        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }

            var mdlData = mdl.MDLRawData;

            if (includedModsList.Any(item => item.Name.Equals(includedMod.Name)))
            {
                if (FlexibleMessageBox.Show(
                        string.Format(UIMessages.ExistingOption, includedMod.Name),
                        UIMessages.OverwriteTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    System.Windows.Forms.DialogResult.Yes)
                {
                    _selectedModOption.Mods[mod.fullPath].ModDataBytes = mdlData;
                }
            }
            else
            {
                IncludedModsList.Items.Add(includedMod);
                _selectedModOption.Mods.Add(mod.fullPath, new ModData
                {
                    Name         = mod.name,
                    Category     = mod.category,
                    FullPath     = mod.fullPath,
                    ModDataBytes = mdlData
                });
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Imports a mod pack
        /// </summary>
        /// <param name="modPackDirectory">The directory of the mod pack</param>
        /// <param name="modsJson">The list of mods to be imported</param>
        /// <param name="gameDirectory">The game directory</param>
        /// <param name="modListDirectory">The mod list directory</param>
        public void ImportModPack(DirectoryInfo modPackDirectory, List <ModsJson> modsJson, DirectoryInfo gameDirectory, DirectoryInfo modListDirectory)
        {
            var dat = new Dat(gameDirectory);
            var modListFullPaths = new List <string>();
            var modList          = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(modListDirectory.FullName));

            foreach (var modListMod in modList.Mods)
            {
                modListFullPaths.Add(modListMod.fullPath);
            }

            using (var archive = ZipFile.OpenRead(modPackDirectory.FullName))
            {
                foreach (var zipEntry in archive.Entries)
                {
                    if (zipEntry.FullName.EndsWith(".mpd"))
                    {
                        using (var binaryReader = new BinaryReader(zipEntry.Open()))
                        {
                            foreach (var modJson in modsJson)
                            {
                                if (modListFullPaths.Contains(modJson.FullPath))
                                {
                                    var existingEntry = (from entry in modList.Mods
                                                         where entry.fullPath.Equals(modJson.FullPath)
                                                         select entry).FirstOrDefault();

                                    binaryReader.BaseStream.Seek(modJson.ModOffset, SeekOrigin.Begin);

                                    var data = binaryReader.ReadBytes(modJson.ModSize);

                                    dat.WriteToDat(new List <byte>(data), existingEntry, modJson.FullPath,
                                                   modJson.Category, modJson.Name, XivDataFiles.GetXivDataFile(modJson.DatFile), _source,
                                                   GetDataType(modJson.FullPath));
                                }
                                else
                                {
                                    binaryReader.BaseStream.Seek(modJson.ModOffset, SeekOrigin.Begin);

                                    var data = binaryReader.ReadBytes(modJson.ModSize);

                                    dat.WriteToDat(new List <byte>(data), null, modJson.FullPath,
                                                   modJson.Category, modJson.Name, XivDataFiles.GetXivDataFile(modJson.DatFile), _source,
                                                   GetDataType(modJson.FullPath));
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Toggles the mod on or off
        /// </summary>
        /// <param name="internalFilePath">The internal file path of the mod</param>
        /// <param name="enable">The status of the mod</param>
        public void ToggleModPackStatus(string modPackName, bool enable)
        {
            var index = new Index(_gameDirectory);

            var        modList          = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(ModListDirectory.FullName));
            var        modListDirectory = new DirectoryInfo(Path.Combine(_gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath));
            List <Mod> mods             = null;

            if (modPackName.Equals("Standalone (Non-ModPack)"))
            {
                mods = (from mod in modList.Mods
                        where mod.modPack == null
                        select mod).ToList();
            }
            else
            {
                mods = (from mod in modList.Mods
                        where mod.modPack != null && mod.modPack.name.Equals(modPackName)
                        select mod).ToList();
            }


            if (mods == null)
            {
                throw new Exception("Unable to find mods with given Mod Pack Name in modlist.");
            }

            foreach (var modEntry in mods)
            {
                if (modEntry.name.Equals(string.Empty))
                {
                    continue;
                }

                if (enable)
                {
                    index.UpdateIndex(modEntry.data.modOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                    index.UpdateIndex2(modEntry.data.modOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                    modEntry.enabled = true;
                }
                else
                {
                    index.UpdateIndex(modEntry.data.originalOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                    index.UpdateIndex2(modEntry.data.originalOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));
                    modEntry.enabled = false;
                }
            }

            File.WriteAllText(modListDirectory.FullName, JsonConvert.SerializeObject(modList, Formatting.Indented));
        }
Esempio n. 11
0
        /// <summary>
        /// Checks to see whether the mod is currently enabled
        /// </summary>
        /// <param name="internalPath">The internal path of the file</param>
        /// <param name="dataFile">The data file to check in</param>
        /// <param name="indexCheck">Flag to determine whether to check the index file or just the modlist</param>
        /// <returns></returns>
        public async Task <XivModStatus> IsModEnabled(string internalPath, bool indexCheck)
        {
            if (!File.Exists(ModListDirectory.FullName))
            {
                return(XivModStatus.Original);
            }

            if (indexCheck)
            {
                var index = new Index(_gameDirectory);

                var modEntry = await TryGetModEntry(internalPath);

                if (modEntry == null)
                {
                    return(XivModStatus.Original);
                }

                var originalOffset = modEntry.data.originalOffset;
                var moddedOffset   = modEntry.data.modOffset;

                var offset = await index.GetDataOffset(
                    HashGenerator.GetHash(Path.GetDirectoryName(internalPath).Replace("\\", "/")),
                    HashGenerator.GetHash(Path.GetFileName(internalPath)),
                    XivDataFiles.GetXivDataFile(modEntry.datFile));

                if (offset.Equals(originalOffset))
                {
                    return(XivModStatus.Disabled);
                }

                if (offset.Equals(moddedOffset))
                {
                    return(XivModStatus.Enabled);
                }

                throw new Exception("Offset in Index does not match either original or modded offset in modlist.");
            }
            else
            {
                var modEntry = await TryGetModEntry(internalPath);

                if (modEntry == null)
                {
                    return(XivModStatus.Original);
                }

                return(modEntry.enabled ? XivModStatus.Enabled : XivModStatus.Disabled);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Toggles the mod on or off
        /// </summary>
        /// <param name="internalFilePath">The internal file path of the mod</param>
        /// <param name="enable">The status of the mod</param>
        public async Task ToggleModStatus(string internalFilePath, bool enable)
        {
            var index = new Index(_gameDirectory);

            if (string.IsNullOrEmpty(internalFilePath))
            {
                throw new Exception("File Path missing, unable to toggle mod.");
            }

            var modEntry = await TryGetModEntry(internalFilePath);

            if (modEntry == null)
            {
                throw new Exception("Unable to find mod entry in modlist.");
            }

            // Matadd textures have the same mod offset as original so nothing to toggle
            if (modEntry.data.originalOffset == modEntry.data.modOffset)
            {
                return;
            }

            if (enable)
            {
                await index.UpdateIndex(modEntry.data.modOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));

                await index.UpdateIndex2(modEntry.data.modOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));
            }
            else
            {
                await index.UpdateIndex(modEntry.data.originalOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));

                await index.UpdateIndex2(modEntry.data.originalOffset, internalFilePath, XivDataFiles.GetXivDataFile(modEntry.datFile));
            }

            var modListDirectory = new DirectoryInfo(Path.Combine(_gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath));

            var modList = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(modListDirectory.FullName));

            var entryEnableUpdate = (from entry in modList.Mods
                                     where entry.fullPath.Equals(modEntry.fullPath)
                                     select entry).FirstOrDefault();

            entryEnableUpdate.enabled = enable;

            File.WriteAllText(modListDirectory.FullName, JsonConvert.SerializeObject(modList, Formatting.Indented));
        }
        /// <summary>
        /// The event handler for the advanced options button clicked
        /// </summary>
        private void AdvOptionsButton_Click(object sender, RoutedEventArgs e)
        {
            var selectedItem = ModelTypeComboBox.SelectedItem as ModComboBox;

            var mod = selectedItem.SelectedMod;

            var includedMod = new IncludedMods
            {
                Name     = $"{Path.GetFileNameWithoutExtension(mod.fullPath)} ({((Category)ModListTreeView.SelectedItem).Name})",
                FullPath = mod.fullPath
            };

            var itemModel = MakeItemModel(mod);

            var includedModsList = IncludedModsList.Items.Cast <IncludedMods>().ToList();
            var mdl = new Mdl(_gameDirectory, XivDataFiles.GetXivDataFile(mod.datFile));

            var xivMdl = mdl.GetMdlData(itemModel, GetRace(mod.fullPath), null, null, mod.data.originalOffset);

            var advancedImportView = new AdvancedModelImportView(xivMdl, itemModel, GetRace(mod.fullPath), true);
            var result             = advancedImportView.ShowDialog();

            if (result == true)
            {
                if (includedModsList.Any(item => item.Name.Equals(includedMod.Name)))
                {
                    if (FlexibleMessageBox.Show(
                            $"This Option already includes {includedMod.Name}  \n\n Would you like to overwrite the existing mod for this option?",
                            "Overwrite?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                        System.Windows.Forms.DialogResult.Yes)
                    {
                        _selectedModOption.Mods[mod.fullPath].ModDataBytes = advancedImportView.RawModelData;
                    }
                }
                else
                {
                    IncludedModsList.Items.Add(includedMod);
                    _selectedModOption.Mods.Add(mod.fullPath, new ModData
                    {
                        Name         = mod.name,
                        Category     = mod.category,
                        FullPath     = mod.fullPath,
                        ModDataBytes = advancedImportView.RawModelData
                    });
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        /// The event handler for the custom model button clicked
        /// </summary>
        private void AddCustomModelButton_Click(object sender, RoutedEventArgs e)
        {
            var selectedItem = ModelTypeComboBox.SelectedItem as ModComboBox;

            var mod = selectedItem.SelectedMod;

            var includedMod = new IncludedMods
            {
                Name     = $"{Path.GetFileNameWithoutExtension(mod.fullPath)} ({((Category)ModListTreeView.SelectedItem).Name})",
                FullPath = mod.fullPath
            };

            var itemModel = MakeItemModel(mod);

            var includedModsList = IncludedModsList.Items.Cast <IncludedMods>().ToList();
            var mdl           = new Mdl(_gameDirectory, XivDataFiles.GetXivDataFile(mod.datFile));
            var xivMdl        = mdl.GetMdlData(itemModel, GetRace(mod.fullPath));
            var importResults = mdl.ImportModel(itemModel, xivMdl, new DirectoryInfo(CustomModelTextBox.Text), null, XivStrings.TexTools,
                                                true);

            //TODO: Add dialogs for import results (warning messages)

            var mdlData = mdl.MDLRawData;

            if (includedModsList.Any(item => item.Name.Equals(includedMod.Name)))
            {
                if (FlexibleMessageBox.Show(
                        $"This Option already includes {includedMod.Name}  \n\n Would you like to overwrite the existing mod for this option?",
                        "Overwrite?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    System.Windows.Forms.DialogResult.Yes)
                {
                    _selectedModOption.Mods[mod.fullPath].ModDataBytes = mdlData;
                }
            }
            else
            {
                IncludedModsList.Items.Add(includedMod);
                _selectedModOption.Mods.Add(mod.fullPath, new ModData
                {
                    Name         = mod.name,
                    Category     = mod.category,
                    FullPath     = mod.fullPath,
                    ModDataBytes = mdlData
                });
            }
        }
        /// <summary>
        /// The event handler for the current model button clicked
        /// </summary>
        private void AddCurrentModelButton_Click(object sender, RoutedEventArgs e)
        {
            var dat = new Dat(_gameDirectory);

            var selectedItem = ModelTypeComboBox.SelectedItem as ModComboBox;

            var mod = selectedItem.SelectedMod;

            var includedMod = new IncludedMods
            {
                Name     = $"{Path.GetFileNameWithoutExtension(mod.fullPath)} ({((Category)ModListTreeView.SelectedItem).Name})",
                FullPath = mod.fullPath
            };

            var includedModsList = IncludedModsList.Items.Cast <IncludedMods>().ToList();

            if (includedModsList.Any(item => item.Name.Equals(includedMod.Name)))
            {
                if (FlexibleMessageBox.Show(
                        $"This Option already includes {includedMod.Name}  \n\n Would you like to overwrite the existing mod for this option?",
                        "Overwrite?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    System.Windows.Forms.DialogResult.Yes)
                {
                    _selectedModOption.Mods[mod.fullPath].ModDataBytes = dat.GetRawData(mod.data.modOffset,
                                                                                        XivDataFiles.GetXivDataFile(mod.datFile), mod.data.modSize);
                }
            }
            else
            {
                IncludedModsList.Items.Add(includedMod);

                var modData = new ModData
                {
                    Name         = mod.name,
                    Category     = mod.category,
                    FullPath     = mod.fullPath,
                    ModDataBytes = dat.GetRawData(mod.data.modOffset, XivDataFiles.GetXivDataFile(mod.datFile), mod.data.modSize)
                };

                _selectedModOption.Mods.Add(mod.fullPath, modData);
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Imports a mod pack asynchronously
        /// </summary>
        /// <param name="modPackDirectory">The directory of the mod pack</param>
        /// <param name="modsJson">The list of mods to be imported</param>
        /// <param name="gameDirectory">The game directory</param>
        /// <param name="modListDirectory">The mod list directory</param>
        /// <param name="progress">The progress of the import</param>
        /// <returns>The number of total mods imported</returns>
        public async Task <int> ImportModPackAsync(DirectoryInfo modPackDirectory, List <ModsJson> modsJson,
                                                   DirectoryInfo gameDirectory, DirectoryInfo modListDirectory, IProgress <double> progress)
        {
            var processCount = await Task.Run <int>(() =>
            {
                var dat = new Dat(gameDirectory);
                var modListFullPaths = new List <string>();
                var modList          = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(modListDirectory.FullName));
                var modCount         = 1;

                foreach (var modListMod in modList.Mods)
                {
                    modListFullPaths.Add(modListMod.fullPath);
                }

                using (var archive = ZipFile.OpenRead(modPackDirectory.FullName))
                {
                    foreach (var zipEntry in archive.Entries)
                    {
                        if (zipEntry.FullName.EndsWith(".mpd"))
                        {
                            _tempMPD = Path.GetTempFileName();
                            zipEntry.ExtractToFile(_tempMPD, true);

                            using (var binaryReader = new BinaryReader(File.OpenRead(_tempMPD)))
                            {
                                foreach (var modJson in modsJson)
                                {
                                    if (modListFullPaths.Contains(modJson.FullPath))
                                    {
                                        var existingEntry = (from entry in modList.Mods
                                                             where entry.fullPath.Equals(modJson.FullPath)
                                                             select entry).FirstOrDefault();

                                        binaryReader.BaseStream.Seek(modJson.ModOffset, SeekOrigin.Begin);

                                        var data = binaryReader.ReadBytes(modJson.ModSize);

                                        dat.WriteToDat(new List <byte>(data), existingEntry, modJson.FullPath,
                                                       modJson.Category, modJson.Name, XivDataFiles.GetXivDataFile(modJson.DatFile), _source,
                                                       GetDataType(modJson.FullPath));
                                    }
                                    else
                                    {
                                        binaryReader.BaseStream.Seek(modJson.ModOffset, SeekOrigin.Begin);

                                        var data = binaryReader.ReadBytes(modJson.ModSize);

                                        dat.WriteToDat(new List <byte>(data), null, modJson.FullPath,
                                                       modJson.Category, modJson.Name, XivDataFiles.GetXivDataFile(modJson.DatFile), _source,
                                                       GetDataType(modJson.FullPath));
                                    }

                                    progress?.Report((double)modCount / modsJson.Count);

                                    modCount++;
                                }
                            }

                            File.Delete(_tempMPD);
                            break;
                        }
                    }
                }

                return(modCount - 1);
            });

            return(processCount);
        }
        /// <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);
        }
        /// <summary>
        /// The event handler for the tree view item selection changed
        /// </summary>
        private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            TextureMapComboBox.Items.Clear();
            ModelTypeComboBox.Items.Clear();
            MaterialComboBox.Items.Clear();
            CustomTextureTextBox.Text = string.Empty;
            CustomModelTextBox.Text   = string.Empty;

            var selectedItem = e.NewValue as Category;

            var modList = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(_modListDirectory.FullName));

            var modItems =
                from mod in modList.Mods
                where mod.name.Equals(selectedItem.Name)
                select mod;

            foreach (var modItem in modItems)
            {
                var itemPath = modItem.fullPath;
                var modCB    = new ModComboBox();
                var ttp      = new TexTypePath
                {
                    Path     = itemPath,
                    DataFile = XivDataFiles.GetXivDataFile(modItem.datFile)
                };

                // Textures
                if (itemPath.Contains("_d."))
                {
                    modCB.Name        = $"{XivTexType.Diffuse} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Diffuse;
                }
                else if (itemPath.Contains("_n."))
                {
                    modCB.Name        = $"{XivTexType.Normal} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Normal;
                }
                else if (itemPath.Contains("_s."))
                {
                    modCB.Name        = $"{XivTexType.Specular} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Specular;
                }
                else if (itemPath.Contains("_m."))
                {
                    modCB.Name        = $"{XivTexType.Multi} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Multi;
                }
                else if (itemPath.Contains("material"))
                {
                    modCB.Name        = $"{XivTexType.ColorSet} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.ColorSet;
                }
                else if (itemPath.Contains("decal"))
                {
                    modCB.Name        = $"{XivTexType.Mask} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Mask;
                }
                else if (itemPath.Contains("vfx"))
                {
                    modCB.Name        = $"{XivTexType.Vfx} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Vfx;
                }
                else if (itemPath.Contains("ui/"))
                {
                    if (itemPath.Contains("icon"))
                    {
                        modCB.Name        = $"{XivTexType.Icon} ({Path.GetFileNameWithoutExtension(itemPath)})";
                        modCB.SelectedMod = modItem;
                        ttp.Type          = XivTexType.Icon;
                    }
                    else if (itemPath.Contains("map"))
                    {
                        modCB.Name        = $"{XivTexType.Map} ({Path.GetFileNameWithoutExtension(itemPath)})";
                        modCB.SelectedMod = modItem;
                        ttp.Type          = XivTexType.Map;
                    }
                    else
                    {
                        modCB.Name        = $"UI ({Path.GetFileNameWithoutExtension(itemPath)})";
                        modCB.SelectedMod = modItem;
                        ttp.Type          = XivTexType.Other;
                    }
                }

                if (modCB.Name != null)
                {
                    modCB.TexTypePath = ttp;
                    TextureMapComboBox.Items.Add(modCB);
                }

                // Models
                if (itemPath.Contains(".mdl"))
                {
                    modCB.Name        = $"{((IItemModel)selectedItem.Item).ModelInfo.ModelID} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    modCB.TexTypePath = null;

                    ModelTypeComboBox.Items.Add(modCB);
                }

                // Material
                if (itemPath.Contains(".mtrl"))
                {
                    modCB.Name        = $"Material ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    modCB.TexTypePath = null;

                    MaterialComboBox.Items.Add(modCB);
                    MaterialTabItem.IsEnabled = true;
                }
            }

            if (TextureMapComboBox.Items.Count > 0)
            {
                AddCurrentTextureButton.IsEnabled = true;
                GetCustomTextureButton.IsEnabled  = true;
                CustomTextureTextBox.IsEnabled    = true;
                AddCustomTextureButton.IsEnabled  = false;
                TextureMapComboBox.SelectedIndex  = 0;
                NoTextureModsLabel.Content        = string.Empty;
            }
            else
            {
                AddCurrentTextureButton.IsEnabled = false;
                GetCustomTextureButton.IsEnabled  = false;
                CustomTextureTextBox.IsEnabled    = false;
                AddCustomTextureButton.IsEnabled  = false;
                NoTextureModsLabel.Content        = "There are no Texture mods present.\n\nIf you would like to enable this, first import a texture for the selected item.";
            }

            if (ModelTypeComboBox.Items.Count > 0)
            {
                AddCurrentModelButton.IsEnabled = true;
                GetCustomModelButton.IsEnabled  = true;
                CustomModelTextBox.IsEnabled    = true;
                AdvOptionsButton.IsEnabled      = true;
                AddCustomModelButton.IsEnabled  = false;
                ModelTypeComboBox.SelectedIndex = 0;
                NoModelModsLabel.Content        = string.Empty;
            }
            else
            {
                AddCurrentModelButton.IsEnabled = false;
                GetCustomModelButton.IsEnabled  = false;
                CustomModelTextBox.IsEnabled    = false;
                AdvOptionsButton.IsEnabled      = false;
                AddCustomModelButton.IsEnabled  = false;
                NoModelModsLabel.Content        = "There are no 3D Model mods present.\n\nIf you would like to enable this, first import a model for the selected item.";
            }

            if (MaterialComboBox.Items.Count > 0)
            {
                AddCurrentMaterialButton.IsEnabled = true;
                MaterialComboBox.SelectedIndex     = 0;
                NoMaterialsModsLabel.Content       = string.Empty;
            }
            else
            {
                AddCurrentMaterialButton.IsEnabled = false;
                NoMaterialsModsLabel.Content       = "There are no Material mods present.\n\nIf you would like to enable this, first import a Material for the selected item.";
            }

            SelectModGroup.IsEnabled = true;
        }
Esempio n. 19
0
        /// <summary>
        /// Toggles the mod on or off
        /// </summary>
        /// <param name="internalFilePath">The internal file path of the mod</param>
        /// <param name="enable">The status of the mod</param>
        public async Task ToggleModPackStatus(string modPackName, bool enable)
        {
            var        modList = GetModList();
            List <Mod> mods    = null;

            if (modPackName.Equals("Standalone (Non-ModPack)"))
            {
                mods = (from mod in modList.Mods
                        where mod.modPack == null
                        select mod).ToList();
            }
            else
            {
                mods = (from mod in modList.Mods
                        where mod.modPack != null && mod.modPack.name.Equals(modPackName)
                        select mod).ToList();
            }


            if (mods == null)
            {
                throw new Exception("Unable to find mods with given Mod Pack Name in modlist.");
            }

            foreach (var modEntry in mods)
            {
                if (modEntry.name.Equals(string.Empty))
                {
                    continue;
                }

                if (enable)
                {
                    await Index.UpdateIndex(modEntry.data.modOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));

                    await Index.UpdateIndex2(modEntry.data.modOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));

                    modEntry.enabled = true;
                }
                else
                {
                    await Index.UpdateIndex(modEntry.data.originalOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));

                    await Index.UpdateIndex2(modEntry.data.originalOffset, modEntry.fullPath, XivDataFiles.GetXivDataFile(modEntry.datFile));

                    modEntry.enabled = false;
                }
            }

            WriteModList(modList);
        }
Esempio n. 20
0
        /// <summary>
        /// Creates a mod pack that uses simple installation
        /// </summary>
        /// <param name="modPackData">The data that will go into the mod pack</param>
        /// <param name="gameDirectory">The game directory</param>
        /// <param name="progress">The progress of the mod pack creation</param>
        /// <returns>The number of mods processed for the mod pack</returns>
        public async Task <int> CreateSimpleModPack(SimpleModPackData modPackData, DirectoryInfo gameDirectory, IProgress <double> progress)
        {
            var processCount = await Task.Run <int>(() =>
            {
                var dat      = new Dat(gameDirectory);
                _tempMPD     = Path.GetTempFileName();
                _tempMPL     = Path.GetTempFileName();
                var modCount = 1;

                var modPackJson = new ModPackJson
                {
                    TTMPVersion    = _currentSimpleTTMPVersion,
                    Name           = modPackData.Name,
                    Author         = modPackData.Author,
                    Version        = modPackData.Version.ToString(),
                    Description    = modPackData.Description,
                    SimpleModsList = new List <ModsJson>()
                };

                using (var binaryWriter = new BinaryWriter(File.Open(_tempMPD, FileMode.Open)))
                {
                    foreach (var simpleModData in modPackData.SimpleModDataList)
                    {
                        var modsJson = new ModsJson
                        {
                            Name      = simpleModData.Name,
                            Category  = simpleModData.Category,
                            FullPath  = simpleModData.FullPath,
                            ModSize   = simpleModData.ModSize,
                            DatFile   = simpleModData.DatFile,
                            ModOffset = binaryWriter.BaseStream.Position
                        };

                        var rawData = dat.GetRawData((int)simpleModData.ModOffset, XivDataFiles.GetXivDataFile(simpleModData.DatFile),
                                                     simpleModData.ModSize);

                        binaryWriter.Write(rawData);

                        modPackJson.SimpleModsList.Add(modsJson);

                        progress?.Report((double)modCount / modPackData.SimpleModDataList.Count);

                        modCount++;
                    }
                }

                File.WriteAllText(_tempMPL, JsonConvert.SerializeObject(modPackJson));

                var modPackPath = $"{_modPackDirectory}\\{modPackData.Name}.ttmp";

                if (File.Exists(modPackPath))
                {
                    var fileNum = 1;
                    modPackPath = $"{_modPackDirectory}\\{modPackData.Name}({fileNum}).ttmp";
                    while (File.Exists(modPackPath))
                    {
                        fileNum++;
                        modPackPath = $"{_modPackDirectory}\\{modPackData.Name}({fileNum}).ttmp";
                    }
                }

                using (var zip = ZipFile.Open(modPackPath, ZipArchiveMode.Create))
                {
                    zip.CreateEntryFromFile(_tempMPL, "TTMPL.mpl");
                    zip.CreateEntryFromFile(_tempMPD, "TTMPD.mpd");
                }

                File.Delete(_tempMPD);
                File.Delete(_tempMPL);

                return(modCount);
            });

            return(processCount);
        }
        /// <summary>
        /// The event handler for the tree view item selection changed
        /// </summary>
        private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            var selectedItem = e.NewValue as Category;

            if (selectedItem == null || selectedItem.Item == null)
            {
                return;
            }

            TextureMapComboBox.Items.Clear();
            ModelTypeComboBox.Items.Clear();
            MaterialComboBox.Items.Clear();
            CustomTextureTextBox.Text = string.Empty;


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

            var modItems =
                from mod in modList.Mods
                where mod.name.Equals(selectedItem.Name)
                select mod;

            foreach (var modItem in modItems)
            {
                var itemPath = modItem.fullPath;
                var modCB    = new ModComboBox();
                var ttp      = new TexTypePath
                {
                    Path     = itemPath,
                    DataFile = XivDataFiles.GetXivDataFile(modItem.datFile)
                };

                // Textures
                if (itemPath.Contains("_d."))
                {
                    modCB.Name        = $"{XivTexType.Diffuse} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Diffuse;
                }
                else if (itemPath.Contains("_n."))
                {
                    modCB.Name        = $"{XivTexType.Normal} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Normal;
                }
                else if (itemPath.Contains("_s."))
                {
                    modCB.Name        = $"{XivTexType.Specular} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Specular;
                }
                else if (itemPath.Contains("_m."))
                {
                    modCB.Name        = $"{XivTexType.Multi} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Multi;
                }
                else if (itemPath.Contains("material"))
                {
                    modCB.Name        = $"{XivTexType.ColorSet} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.ColorSet;
                }
                else if (itemPath.Contains("decal"))
                {
                    modCB.Name        = $"{XivTexType.Mask} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Mask;
                }
                else if (itemPath.Contains("vfx"))
                {
                    modCB.Name        = $"{XivTexType.Vfx} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Vfx;
                }
                else if (itemPath.Contains("ui/"))
                {
                    if (itemPath.Contains("icon"))
                    {
                        modCB.Name        = $"{XivTexType.Icon} ({Path.GetFileNameWithoutExtension(itemPath)})";
                        modCB.SelectedMod = modItem;
                        ttp.Type          = XivTexType.Icon;
                    }
                    else if (itemPath.Contains("map"))
                    {
                        modCB.Name        = $"{XivTexType.Map} ({Path.GetFileNameWithoutExtension(itemPath)})";
                        modCB.SelectedMod = modItem;
                        ttp.Type          = XivTexType.Map;
                    }
                    else
                    {
                        modCB.Name        = $"UI ({Path.GetFileNameWithoutExtension(itemPath)})";
                        modCB.SelectedMod = modItem;
                        ttp.Type          = XivTexType.Other;
                    }
                }
                else if (itemPath.Contains(".tex"))
                {
                    modCB.Name        = $"{XivTexType.Other} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    modCB.SelectedMod = modItem;
                    ttp.Type          = XivTexType.Other;
                }

                if (modCB.Name != null)
                {
                    modCB.TexTypePath = ttp;
                    TextureMapComboBox.Items.Add(modCB);
                }

                // Models
                if (itemPath.Contains(".mdl"))
                {
                    //esrinzou for Repair program crash when selecting [character/Body] item
                    //modCB.Name = $"{((IItemModel)selectedItem.Item).ModelInfo.ModelID} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    //esrinzou begin
                    if (((IItemModel)selectedItem.Item).ModelInfo == null)
                    {
                        modCB.Name = $"{((IItemModel)selectedItem.Item).Name} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    }
                    else
                    {
                        var modelId = ((IItemModel)selectedItem.Item).ModelInfo.PrimaryID;

                        if (selectedItem.Item.PrimaryCategory.Equals(XivStrings.Character))
                        {
                            var item = selectedItem.Item;

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

                        modCB.Name = $"{modelId} ({Path.GetFileNameWithoutExtension(itemPath)})";
                    }
                    //esrinzou end
                    modCB.SelectedMod = modItem;
                    modCB.TexTypePath = null;

                    ModelTypeComboBox.Items.Add(modCB);
                }

                // Material
                if (itemPath.Contains(".mtrl"))
                {
                    var materialModCB = new ModComboBox
                    {
                        Name        = $"Material ({Path.GetFileNameWithoutExtension(itemPath)})",
                        SelectedMod = modItem,
                        TexTypePath = null
                    };

                    MaterialComboBox.Items.Add(materialModCB);
                    MaterialTabItem.IsEnabled = true;
                }
            }

            if (TextureMapComboBox.Items.Count > 0)
            {
                AddCurrentTextureButton.IsEnabled = true;
                GetCustomTextureButton.IsEnabled  = true;
                CustomTextureTextBox.IsEnabled    = true;
                AddCustomTextureButton.IsEnabled  = false;
                TextureMapComboBox.SelectedIndex  = 0;
                NoTextureModsLabel.Content        = string.Empty;
            }
            else
            {
                AddCurrentTextureButton.IsEnabled = false;
                GetCustomTextureButton.IsEnabled  = false;
                CustomTextureTextBox.IsEnabled    = false;
                AddCustomTextureButton.IsEnabled  = false;
                NoTextureModsLabel.Content        = UIStrings.No_Texture_Mods;
            }

            if (ModelTypeComboBox.Items.Count > 0)
            {
                AddCurrentModelButton.IsEnabled = true;
                AdvOptionsButton.IsEnabled      = true;
                ModelTypeComboBox.SelectedIndex = 0;
                NoModelModsLabel.Content        = string.Empty;
            }
            else
            {
                AddCurrentModelButton.IsEnabled = false;
                AdvOptionsButton.IsEnabled      = false;
                NoModelModsLabel.Content        = UIStrings.No_3D_Mods;
            }

            if (MaterialComboBox.Items.Count > 0)
            {
                AddCurrentMaterialButton.IsEnabled = true;
                MaterialComboBox.SelectedIndex     = 0;
                NoMaterialsModsLabel.Content       = string.Empty;
            }
            else
            {
                AddCurrentMaterialButton.IsEnabled = false;
                NoMaterialsModsLabel.Content       = UIStrings.No_Material_Mods;
            }

            SelectModGroup.IsEnabled = true;
        }
Esempio n. 22
0
        /// <summary>
        /// Checks the mods for any problems
        /// </summary>
        private void CheckMods()
        {
            var modListDirectory = new DirectoryInfo(Path.Combine(_gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath));

            var modList = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(modListDirectory.FullName));

            var dat = new Dat(_gameDirectory);

            if (modList.modCount > 0)
            {
                foreach (var mod in modList.Mods)
                {
                    if (mod.name.Equals(string.Empty))
                    {
                        continue;
                    }

                    var fileName = Path.GetFileName(mod.fullPath);

                    var tabs = "";
                    if (fileName.Length < 21 && fileName.Length > 12)
                    {
                        tabs = "\t";
                    }
                    else if (fileName.Length < 12)
                    {
                        tabs = "\t\t";
                    }

                    AddText($"\t{fileName}{tabs}", textColor);

                    if (mod.data.originalOffset == 0)
                    {
                        AddText("\t\u2716\n", "Red");
                        AddText("\tOriginal Offset was 0, you will be unable to revert to original, consider starting over. \n", "Red");
                    }
                    else if (mod.data.modOffset == 0)
                    {
                        AddText("\t\u2716\n", "Red");
                        AddText("\tMod Offset was 0, Disable from File > Modlist and reimport.\n", "Red");
                    }
                    else
                    {
                        AddText("\t\u2714", "Green");
                    }

                    var fileType = 0;
                    try
                    {
                        fileType = dat.GetFileType(mod.data.modOffset, XivDataFiles.GetXivDataFile(mod.datFile));
                    }
                    catch (Exception ex)
                    {
                        AddText("\t\u2716\n", "Red");
                        AddText($"\tError: {ex.Message}\n", "Red");
                    }


                    if (fileType != 2 && fileType != 3 && fileType != 4)
                    {
                        AddText("\t\u2716\n", "Red");
                        AddText($"\tFound unknown file type ( {fileType} ) offset is most likely corrupt.\n", "Red");
                    }
                    else
                    {
                        AddText("\t\u2714\n", "Green");
                    }
                }
            }
            else
            {
                AddText("\tNo entries found in modlist.\n", "Orange");
            }
        }
Esempio n. 23
0
        /// <summary>
        /// Performs post-patch modlist corrections and validation, prompting user also to generate backups after a successful completion.
        /// </summary>
        /// <returns></returns>
        public async Task DoPostPatchCleanup()
        {
            FlexibleMessageBox.Show(_mainWindow.Win32Window, UIMessages.PatchDetectedMessage, "Post Patch Cleanup Starting", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            MainWindow.MakeHighlander();

            var resetLumina = false;

            await _mainWindow.LockUi("Performing Post-Patch Maintenence", "This may take a few minutes if you have many mods installed.", this);

            var gi = XivCache.GameInfo;

            if (XivCache.GameInfo.UseLumina)
            {
                resetLumina = true;
                XivCache.SetGameInfo(gi.GameDirectory, gi.GameLanguage, gi.DxMode, false, false, gi.LuminaDirectory, gi.UseLumina);
            }

            var workerStatus = XivCache.CacheWorkerEnabled;

            if (workerStatus)
            {
                // Stop the cache worker if it's running.
                XivCache.CacheWorkerEnabled = false;
            }
            try
            {
                var modding = new Modding(_gameDirectory);
                var _index  = new Index(_gameDirectory);
                var _dat    = new Dat(_gameDirectory);

                var validTypes = new List <int>()
                {
                    2, 3, 4
                };

                // We have to do a few things here.
                // 1.  Save a list of what mods were enabled.
                // 2.  Go through and validate everything that says it is enabled actually is enabled, or mark it as disabled and update its original index offset if it is not.
                // 3.  Prompt the user for either a full disable and backup creation, or a restore to normal state (re-enable anything that was enabled before but is not now)
                var modList = modding.GetModList();

                Dictionary <XivDataFile, IndexFile> indexFiles = new Dictionary <XivDataFile, IndexFile>();


                // Cache our currently enabled stuff.
                List <Mod> enabledMods = modList.Mods.Where(x => x.enabled == true).ToList();
                var        toRemove    = new List <Mod>();

                foreach (var mod in modList.Mods)
                {
                    if (!String.IsNullOrEmpty(mod.fullPath))
                    {
                        var df = IOUtil.GetDataFileFromPath(mod.fullPath);
                        if (!indexFiles.ContainsKey(df))
                        {
                            indexFiles[df] = await _index.GetIndexFile(df);
                        }

                        var index1Value       = indexFiles[df].Get8xDataOffset(mod.fullPath);
                        var index2Value       = indexFiles[df].Get8xDataOffsetIndex2(mod.fullPath);
                        var oldOriginalOffset = mod.data.originalOffset;
                        var modOffset         = mod.data.modOffset;


                        // In any event where an offset does not match either of our saved offsets, we must assume this is a new
                        // default file offset for post-patch.
                        if (index1Value != oldOriginalOffset && index1Value != modOffset && index1Value != 0)
                        {
                            // Index 1 value is our new base offset.
                            var type = _dat.GetFileType(index1Value, df);

                            // Make sure the file it's trying to point to is actually valid.
                            if (validTypes.Contains(type))
                            {
                                mod.data.originalOffset = index1Value;
                                mod.enabled             = false;
                            }
                            else
                            {
                                // Oh dear.  The new index is f****d.  Is the old Index Ok?
                                type = _dat.GetFileType(oldOriginalOffset, df);

                                if (validTypes.Contains(type) && oldOriginalOffset != 0)
                                {
                                    // Old index is fine, so keep using that.

                                    // But mark the index value as invalid, so that we stomp on the index value after this.
                                    index1Value = -1;
                                    mod.enabled = false;
                                }
                                else
                                {
                                    // Okay... Maybe the new Index2 Value?
                                    if (index2Value != 0)
                                    {
                                        type = _dat.GetFileType(index2Value, df);
                                        if (validTypes.Contains(type))
                                        {
                                            // Set the index 1 value to invalid so that the if later down the chain stomps the index1 value.
                                            index1Value = -1;

                                            mod.data.originalOffset = index2Value;
                                            mod.enabled             = false;
                                        }
                                        else
                                        {
                                            // We be f****d.
                                            throw new Exception("Unable to determine working original offset for file:" + mod.fullPath);
                                        }
                                    }
                                    else
                                    {
                                        // We be f****d.
                                        throw new Exception("Unable to determine working original offset for file:" + mod.fullPath);
                                    }
                                }
                            }
                        }
                        else if (index2Value != oldOriginalOffset && index2Value != modOffset && index2Value != 0)
                        {
                            // Our Index 1 was normal, but our Index 2 is changed to an unknown value.
                            // If the index 2 points to a valid file, we must assume that this new file
                            // is our new base data offset.

                            var type = _dat.GetFileType(index2Value, df);

                            if (validTypes.Contains(type) && index2Value != 0)
                            {
                                mod.data.originalOffset = index2Value;
                                mod.enabled             = false;
                            }
                            else
                            {
                                // Oh dear.  The new index is f****d.  Is the old Index Ok?
                                type = _dat.GetFileType(oldOriginalOffset, df);

                                if (validTypes.Contains(type) && oldOriginalOffset != 0)
                                {
                                    // Old index is fine, so keep using that, but set the index2 value to invalid to ensure we
                                    // stomp on the current broken index value.
                                    index2Value = -1;
                                }
                                else
                                {
                                    // We be f****d.
                                    throw new Exception("Unable to determine working original offset for file:" + mod.fullPath);
                                }
                            }
                        }

                        // Indexes don't match.  This can occur if SE adds something to index2 that didn't exist in index2 before.
                        if (index1Value != index2Value && index2Value != 0)
                        {
                            // We should never actually get to this state for file-addition mods.  If we do, uh.. I guess correct the indexes and yolo?
                            // ( Only way we get here is if SE added a new file at the same name as a file the user had created via modding, in which case, it's technically no longer a file addition mod )
                            indexFiles[df].SetDataOffset(mod.fullPath, mod.data.originalOffset);
                            index1Value = mod.data.originalOffset;
                            index2Value = mod.data.originalOffset;

                            mod.enabled = false;
                        }

                        // Set it to the corrected state.
                        if (index1Value == mod.data.modOffset)
                        {
                            mod.enabled = true;
                        }
                        else
                        {
                            mod.enabled = false;
                        }

                        // Perform a basic file type check on our results.
                        var fileType         = _dat.GetFileType(mod.data.modOffset, IOUtil.GetDataFileFromPath(mod.fullPath));
                        var originalFileType = _dat.GetFileType(mod.data.modOffset, IOUtil.GetDataFileFromPath(mod.fullPath));

                        if (!validTypes.Contains(fileType) || mod.data.modOffset == 0)
                        {
                            // Mod data is busted.  Fun.
                            toRemove.Add(mod);
                        }

                        if ((!validTypes.Contains(originalFileType)) || mod.data.originalOffset == 0)
                        {
                            if (mod.IsCustomFile())
                            {
                                // Okay, in this case this is recoverable as the mod is a custom addition anyways, so we can just delete it.
                                if (!toRemove.Contains(mod))
                                {
                                    toRemove.Add(mod);
                                }
                            }
                            else
                            {
                                // Update ended up with us unable to find a working offset.  Double fun.
                                throw new Exception("Unable to determine working offset for file:" + mod.fullPath);
                            }
                        }
                    }

                    // Okay, this mod is now represented in the modlist in it's actual post-patch index state.
                    var datNum = (int)((mod.data.modOffset / 8) & 0x0F) / 2;
                    var dat    = XivDataFiles.GetXivDataFile(mod.datFile);

                    var originalDats = await _dat.GetUnmoddedDatList(dat);

                    var datPath = $"{dat.GetDataFileName()}{Dat.DatExtension}{datNum}";

                    // Test for SE Dat file rollover.
                    if (originalDats.Contains(datPath))
                    {
                        // Shit.  This means that the dat file where this mod lived got eaten by SE.  We have to destroy the modlist entry at this point.
                        toRemove.Add(mod);
                    }
                }

                // Save any index changes we made.
                foreach (var dkv in indexFiles)
                {
                    await _index.SaveIndexFile(dkv.Value);
                }

                // The modlist is now saved in its current index-represented post patch state.
                modding.SaveModList(modList);

                // We now need to clear out any mods that are irreparably f****d, and clear out all of our
                // internal data files so we can rebuild them later.

                var internalFiles = modList.Mods.Where(x => x.IsInternal());
                toRemove.AddRange(internalFiles);

                if (toRemove.Count > 0)
                {
                    var removedString = "";

                    // Soft-Disable all metadata mods, since we're going to purge their internal file entries.
                    var metadata = modList.Mods.Where(x => x.fullPath.EndsWith(".meta") || x.fullPath.EndsWith(".rgsp"));
                    foreach (var mod in metadata)
                    {
                        var df = IOUtil.GetDataFileFromPath(mod.fullPath);
                        await modding.ToggleModUnsafe(false, mod, true, false, indexFiles[df], modList);
                    }

                    foreach (var mod in toRemove)
                    {
                        if (mod.data.modOffset == 0 || mod.data.originalOffset == 0)
                        {
                            if (mod.data.originalOffset == 0 && mod.enabled)
                            {
                                // This is awkward.  We have a mod whose data got bashed, but has no valid original offset to restore.
                                // So the indexes here are f****d if we do, f****d if we don't.
                                throw new Exception("Patch-Broken file has no valid index to restore.  Clean Index Restoration required.");
                            }

                            modList.Mods.Remove(mod);
                            enabledMods.Remove(mod);
                            removedString += mod.fullPath + "\n";
                        }
                        else
                        {
                            if (mod.enabled)
                            {
                                var df = IOUtil.GetDataFileFromPath(mod.fullPath);
                                await modding.ToggleModUnsafe(false, mod, true, false, indexFiles[df], modList);
                            }

                            modList.Mods.Remove(mod);

                            // Since we're deleting this entry entirely, we can't leave it in the other cached list either to get re-enabled later.
                            enabledMods.Remove(mod);

                            if (!mod.IsInternal())
                            {
                                removedString += mod.fullPath + "\n";
                            }
                        }
                    }

                    // Save the index files and modlist again now that we've removed all the invalid entries.
                    foreach (var dkv in indexFiles)
                    {
                        await _index.SaveIndexFile(dkv.Value);
                    }
                    modding.SaveModList(modList);

                    // Show the user a message if we purged any real files.
                    if (toRemove.Any(x => !String.IsNullOrEmpty(x.fullPath) && !x.IsInternal()))
                    {
                        var text = String.Format(UIMessages.PatchDestroyedFiles, removedString);

                        FlexibleMessageBox.Show(_mainWindow.Win32Window, text, "Destroyed Files Notification", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                    }
                }

                // Always create clean index backups after this process is completed.

                _mainWindow.LockProgress.Report("Disabling Mods...");
                await modding.ToggleAllMods(false);

                _mainWindow.LockProgress.Report("Creating Index Backups...");
                var           pc = new ProblemChecker(_gameDirectory);
                DirectoryInfo backupDir;
                try
                {
                    Directory.CreateDirectory(Settings.Default.Backup_Directory);
                    backupDir = new DirectoryInfo(Settings.Default.Backup_Directory);
                }
                catch
                {
                    throw new Exception("Unable to create index backups.\nThe Index Backup directory is invalid or inaccessible: " + Settings.Default.Backup_Directory);
                }

                await pc.BackupIndexFiles(backupDir);

                // Now restore the modlist enable/disable state back to how the user had it before.
                _mainWindow.LockProgress.Report("Re-Enabling mods...");

                // Re-enable things.
                await modding.ToggleMods(true, enabledMods.Select(x => x.fullPath));

                FlexibleMessageBox.Show(_mainWindow.Win32Window, UIMessages.PostPatchComplete, "Post-Patch Process Complete", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            }
            catch (Exception Ex)
            {
                // Show the user the error, then let them go about their business of fixing things.
                FlexibleMessageBox.Show(_mainWindow.Win32Window, String.Format(UIMessages.PostPatchError, Ex.Message), "Post-Patch Failure", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            }
            finally
            {
                if (resetLumina)
                {
                    // Reset lumina mode back to on if we disabled it to perform update checks.
                    XivCache.SetGameInfo(gi.GameDirectory, gi.GameLanguage, gi.DxMode, true, false, gi.LuminaDirectory, true);
                }

                XivCache.CacheWorkerEnabled = workerStatus;
                await _mainWindow.UnlockUi(this);
            }
        }