public SimpleModPackImporter(DirectoryInfo modPackDirectory, ModPackJson modPackJson, TextureViewModel textureViewModel, ModelViewModel modelViewModel, bool silent = false, bool messageInImport = false) { this.DataContext = this; InitializeComponent(); JsonEntries = new List <ModsJson>(); SelectedEntries = new HashSet <int>(); _modPackDirectory = modPackDirectory; _gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); _modding = new Modding(_gameDirectory); _texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); _messageInImport = messageInImport; _textureViewModel = textureViewModel; _modelViewModel = modelViewModel; var index = new Index(_gameDirectory); _indexLockStatus = index.IsIndexLocked(XivDataFile._0A_Exd); _packJson = modPackJson; _silent = silent; ModListView.IsEnabled = false; LockedStatusLabel.Foreground = Brushes.Black; LockedStatusLabel.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Left; LockedStatusLabel.Content = UIStrings.Loading; Task.Run(Initialize); }
/// <summary> /// Event handler for the import mod pack menu item clicked /// </summary> private async void Menu_ImportModpack_Click(object sender, RoutedEventArgs e) { var modPackDirectory = new DirectoryInfo(Settings.Default.ModPack_Directory); var openFileDialog = new OpenFileDialog { InitialDirectory = modPackDirectory.FullName, Filter = "TexToolsModPack TTMP (*.ttmp;*.ttmp2)|*.ttmp;*.ttmp2" }; if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { try { var ttmp = new TTMP(modPackDirectory, XivStrings.TexTools); var ttmpData = ttmp.GetModPackJsonData(new DirectoryInfo(openFileDialog.FileName)); if (ttmpData.ModPackJson.TTMPVersion.Contains("w")) { var importWizard = new ImportModPackWizard(ttmpData.ModPackJson, ttmpData.ImageDictionary, new DirectoryInfo(openFileDialog.FileName)) { Owner = this }; var result = importWizard.ShowDialog(); if (result == true) { await this.ShowMessageAsync("Import Complete", $"{importWizard.TotalModsImported} mod(s) successfully imported."); } } else { var simpleImport = new SimpleModPackImporter(new DirectoryInfo(openFileDialog.FileName), ttmpData.ModPackJson) { Owner = this }; var result = simpleImport.ShowDialog(); if (result == true) { await this.ShowMessageAsync("Import Complete", $"{simpleImport.TotalModsImported} mod(s) successfully imported."); } } } catch (Exception ex) { var simpleImport = new SimpleModPackImporter(new DirectoryInfo(openFileDialog.FileName), null) { Owner = this }; var result = simpleImport.ShowDialog(); if (result == true) { await this.ShowMessageAsync("Import Complete", $"{simpleImport.TotalModsImported} mod(s) successfully imported."); } } } }
private async void Menu_ModConverter_Click(object sender, RoutedEventArgs e) { var modPackDirectory = new DirectoryInfo(Settings.Default.ModPack_Directory); var openFileDialog = new OpenFileDialog { InitialDirectory = modPackDirectory.FullName, Filter = "TexToolsModPack TTMP (*.ttmp;*.ttmp2)|*.ttmp;*.ttmp2" }; if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return; } var ttmpFileName = openFileDialog.FileName; var ttmp = new TTMP(modPackDirectory, XivStrings.TexTools); (ModPackJson ModPackJson, Dictionary <string, Image> ImageDictionary)ttmpData; var progressController = await this.ShowProgressAsync(UIStrings.Mod_Converter, UIMessages.PleaseStandByMessage); var modsJsonList = await ttmp.GetOriginalModPackJsonData(new DirectoryInfo(ttmpFileName)); if (modsJsonList == null) { ttmpData = await ttmp.GetModPackJsonData(new DirectoryInfo(ttmpFileName)); } else { ttmpData = (ModPackJson : new ModPackJson(), ImageDictionary : new Dictionary <string, Image>()); ttmpData.ModPackJson.Author = "Mod Converter"; ttmpData.ModPackJson.Version = "1.0.0"; ttmpData.ModPackJson.Name = Path.GetFileNameWithoutExtension(ttmpFileName); ttmpData.ModPackJson.TTMPVersion = "s"; ttmpData.ModPackJson.SimpleModsList = new List <ModsJson>(); foreach (var mod in modsJsonList) { var modsJson = new ModsJson(); modsJson.Category = mod.Category; modsJson.DatFile = mod.DatFile; modsJson.FullPath = mod.FullPath; modsJson.ModOffset = mod.ModOffset; modsJson.ModPackEntry = null; modsJson.ModSize = mod.ModSize; modsJson.Name = mod.Name; ttmpData.ModPackJson.SimpleModsList.Add(modsJson); } } var gameDir = new DirectoryInfo(Settings.Default.FFXIV_Directory); var lang = XivLanguages.GetXivLanguage(Settings.Default.Application_Language); var gear = new Gear(gameDir, lang); var gearList = await gear.GetGearList(); var modConverterView = new ModConverterView(gearList, ttmpFileName, ttmpData) { Owner = this, WindowStartupLocation = WindowStartupLocation.CenterOwner }; await progressController.CloseAsync(); modConverterView.ShowDialog(); }
/// <summary> /// The event handler for the create mod pack button /// </summary> /// <remarks> /// This is originally the help button, but has been repurposed /// </remarks> private async void ModPackWizard_CreateModPack(object sender, System.Windows.RoutedEventArgs e) { _progressController = await this.ShowProgressAsync(UIMessages.ModPackCreationMessage, UIMessages.PleaseStandByMessage); var wizPages = modPackWizard.Items; var modPackData = new ModPackData { Name = ModPackName.Text, Author = ModPackAuthor.Text, Version = VersionNumber, Description = ModPackDescription.Text, ModPackPages = new List <ModPackData.ModPackPage>() }; var pageIndex = 0; foreach (var wizPageItem in wizPages) { var wizPage = wizPageItem as WizardPage; if (wizPage.Content is WizardModPackControl control) { if (control.ModGroupList.Count > 0) { modPackData.ModPackPages.Add(new ModPackData.ModPackPage { PageIndex = pageIndex, ModGroups = control.ModGroupList }); } } pageIndex++; } if (modPackData.ModPackPages.Count > 0) { var progressIndicator = new Progress <double>(ReportProgress); var texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); await texToolsModPack.CreateWizardModPack(modPackData, progressIndicator); ModPackFileName = $"{ModPackName.Text}"; } else { ModPackFileName = "NoData"; } await _progressController.CloseAsync(); DialogResult = true; }
public SimpleModPackImporter(DirectoryInfo modPackDirectory, ModPackJson modPackJson) { InitializeComponent(); _modPackDirectory = modPackDirectory; _gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); _texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); if (modPackJson != null) { ImportSimpleModPack(modPackJson); } else { ImportOldModPack(); } }
public SimpleModPackImporter(DirectoryInfo modPackDirectory, ModPackJson modPackJson, bool silent = false, bool messageInImport = false) { InitializeComponent(); _modPackDirectory = modPackDirectory; _gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); _texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); _messageInImport = messageInImport; var index = new Index(_gameDirectory); _indexLockStatus = index.IsIndexLocked(XivDataFile._0A_Exd); ModListView.ItemsSource = _simpleDataList; Initialize(modPackJson, silent); }
/// <summary> /// Writes all selected mods to game data /// </summary> private async void FinalizeImport() { _progressController = await this.ShowProgressAsync("Importing ModPack", "Please Stand By..."); var texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); var importList = new List <ModsJson>(); foreach (var wizPageItem in importModPackWizard.Items) { var wizPage = wizPageItem as WizardPage; if (wizPage.Content is ImportWizardModPackControl control) { var optionList = control.OptionsList; foreach (var optionListItem in optionList.Items) { if (((ModOptionJson)optionListItem).IsChecked) { importList.AddRange(((ModOptionJson)optionListItem).ModsJsons); } } } } foreach (var modsJson in importList) { modsJson.ModPackEntry = _modPackEntry; } var gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); var modListDirectory = new DirectoryInfo(Path.Combine(gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath)); var progressIndicator = new Progress <double>(ReportProgress); TotalModsImported = await texToolsModPack.ImportModPackAsync(_modPackDirectory, importList, gameDirectory, modListDirectory, progressIndicator); await _progressController.CloseAsync(); DialogResult = true; }
/// <summary> /// The event handler for create mod pack button clicked /// </summary> private async void CreateModPackButton_Click(object sender, RoutedEventArgs e) { if (ModPackName.Text.Equals(string.Empty)) { if (FlexibleMessageBox.Show(new Wpf32Window(this), $"Nothing was entered for ModPack Name\n\nModPack Name will default to \"ModPack\"", "No Name Found", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.OK) { ModPackName.Text = "ModPack"; } else { return; } } var verString = ModPackVersion.Text.Replace("_", "0"); // Replace commas with periods for different culture formats such as FR if (verString.Contains(",")) { verString = verString.Replace(",", "."); } var versionNumber = Version.Parse(verString); if (versionNumber.ToString().Equals("0.0.0")) { if (FlexibleMessageBox.Show(new Wpf32Window(this), $"Nothing was entered for ModPack Version\n\nVersion will default to \"1.0.0\"", "No Version Found", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.OK) { versionNumber = new Version(1, 0, 0); } else { return; } } if (ModPackAuthor.Text.Equals(string.Empty)) { if (FlexibleMessageBox.Show(new Wpf32Window(this), $"Nothing was entered for ModPack Author\n\nAuthor will default to \"TexTools User\"", "No Author Found", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.OK) { ModPackAuthor.Text = "TexTools User"; } else { return; } } _progressController = await this.ShowProgressAsync("Creating ModPack", "Please Stand By..."); ModPackFileName = ModPackName.Text; var texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); var simpleModPackData = new SimpleModPackData { Name = ModPackName.Text, Author = ModPackAuthor.Text, Version = versionNumber, SimpleModDataList = new List <SimpleModData>() }; foreach (SimpleModPackEntries simpleEntry in ModListView.SelectedItems) { var simpleData = new SimpleModData { Name = simpleEntry.Name, Category = simpleEntry.Category, FullPath = simpleEntry.ModEntry.fullPath, ModOffset = simpleEntry.ModEntry.data.modOffset, ModSize = simpleEntry.ModEntry.data.modSize, DatFile = simpleEntry.ModEntry.datFile }; simpleModPackData.SimpleModDataList.Add(simpleData); } var progressIndicator = new Progress <double>(ReportProgress); await texToolsModPack.CreateSimpleModPack(simpleModPackData, _gameDirectory, progressIndicator); await _progressController.CloseAsync(); DialogResult = true; }
private async void LoadFromButton_Click(object sender, System.Windows.RoutedEventArgs e) { var openFileDialog = new OpenFileDialog { Filter = "Texture Files(*.ttmp2)|*.ttmp2", InitialDirectory = Settings.Default.ModPack_Directory }; if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return; } var ttmp = new TTMP(new DirectoryInfo(Settings.Default.ModPack_Directory), XivStrings.TexTools); var ttmpData = await ttmp.GetModPackJsonData(new DirectoryInfo(openFileDialog.FileName)); if (!ttmpData.ModPackJson.TTMPVersion.Contains("w")) { FlexibleMessageBox.Show(new Wpf32Window(this), UIMessages.NotWizardModPack, UIMessages.ModPackLoadingTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var tempMPD = Path.GetTempFileName(); using (var archive = ZipFile.OpenRead(openFileDialog.FileName)) { using (var zipStream = archive.GetEntry("TTMPD.mpd").Open()) { using (var fileStream = new FileStream(tempMPD, FileMode.OpenOrCreate)) { await zipStream.CopyToAsync(fileStream); } } } this.ModPackAuthor.Text = ttmpData.ModPackJson.Author; this.ModPackName.Text = ttmpData.ModPackJson.Name; this.ModPackVersion.Text = ttmpData.ModPackJson.Version; this.ModPackDescription.Text = ttmpData.ModPackJson.Description; for (var i = modPackWizard.Items.Count - 1; i > 0; i--) { modPackWizard.Items.RemoveAt(i); } //var previousPage = modPackWizard.CurrentPage; foreach (var wizPageItemJson in ttmpData.ModPackJson.ModPackPages) { var wizPage = new WizardPage(); wizPage.Background = null; wizPage.HeaderBackground = null; var wizModPackControl = new WizardModPackControl(); wizPage.Content = wizModPackControl; wizPage.PageType = WizardPageType.Blank; foreach (var groupJson in wizPageItemJson.ModGroups) { var modGroup = new ModGroup(); modGroup.OptionList = new List <ModOption>(); modGroup.GroupName = groupJson.GroupName; modGroup.SelectionType = groupJson.SelectionType; wizModPackControl.ModGroupList.Add(modGroup); wizModPackControl.ModGroupNames.Add(modGroup.GroupName); foreach (var optionJson in groupJson.OptionList) { var modOption = new ModOption(); modGroup.OptionList.Add(modOption); modOption.Name = optionJson.Name; modOption.GroupName = optionJson.GroupName; modOption.IsChecked = optionJson.IsChecked; modOption.SelectionType = optionJson.SelectionType; modOption.Description = optionJson.Description; if (optionJson.ImagePath.Length > 0) { using (var zipFile = ZipFile.OpenRead(openFileDialog.FileName)) { using (var stream = zipFile.GetEntry(optionJson.ImagePath).Open()) { var tmpImage = Path.GetTempFileName(); using (var imageStream = File.Open(tmpImage, FileMode.OpenOrCreate)) { await stream.CopyToAsync(imageStream); imageStream.Position = 0; } var fileNameBak = openFileDialog.FileName; openFileDialog.FileName = tmpImage; modOption.Image = Image.Load(openFileDialog.FileName); modOption.ImageFileName = openFileDialog.FileName; openFileDialog.FileName = fileNameBak; } } } foreach (var modJson in optionJson.ModsJsons) { var modData = new ModData(); modData.Category = modJson.Category; modData.FullPath = modJson.FullPath; modData.Name = modJson.Name; using (var br = new BinaryReader(File.OpenRead(tempMPD))) { br.BaseStream.Seek(modJson.ModOffset, SeekOrigin.Begin); modData.ModDataBytes = br.ReadBytes(modJson.ModSize); } modOption.Mods.Add(modData.FullPath, modData); } ((List <ModOption>)wizModPackControl.OptionsList.ItemsSource).Add(modOption); var view = (CollectionView)CollectionViewSource.GetDefaultView(wizModPackControl.OptionsList.ItemsSource); var groupDescription = new PropertyGroupDescription("GroupName"); view.GroupDescriptions.Clear(); view.GroupDescriptions.Add(groupDescription); } if (modGroup.OptionList.Count > 0 && modGroup.OptionList.Count(it => it.IsChecked) == 0) { modGroup.OptionList[0].IsChecked = true; } } modPackWizard.Items.Add(wizPage); modPackWizard.CanHelp = true; } modPackWizard.Items.Add(new WizardPage() { Content = new WizardModPackControl(), PageType = WizardPageType.Blank, Background = null, HeaderBackground = null }); }
/// <summary> /// Event handler for when the create modpack button is clicked, this method creates a modpack with "Backup dd-MM-yy" as its name /// </summary> private async void CreateModPackButton_Click(object sender, RoutedEventArgs e) { _progressController = await this.ShowProgressAsync(UIMessages.ModPackCreationMessage, UIMessages.PleaseStandByMessage); try { var backupModpackData = new BackupModPackData { Name = ModPackName.Text, ModsToBackup = new List <BackupModData>() }; var selectedEntries = from modpack in (List <BackupModpackItemEntry>)ModpackList.ItemsSource where modpack.IsChecked select modpack; if (selectedEntries.Count() == 0) { throw new Exception("No selected modpacks detected."); } foreach (var modpackEntry in selectedEntries) { ModPack selectedModpack = null; IEnumerable <Mod> modsInModpack = new List <Mod>(); if (modpackEntry.ModpackName == UIStrings.Standalone_Non_ModPack) { modsInModpack = from mods in _modList.Mods where !mods.name.Equals(string.Empty) && mods.modPack == null select mods; } else { selectedModpack = _modList.ModPacks.First(modPack => modPack.name == modpackEntry.ModpackName); modsInModpack = from mods in _modList.Mods where (mods.modPack != null && mods.modPack.name == selectedModpack.name) select mods; } foreach (var mod in modsInModpack) { var simpleModData = new SimpleModData { Name = mod.name, Category = mod.category, FullPath = mod.fullPath, ModOffset = mod.data.modOffset, ModSize = mod.data.modSize, DatFile = mod.datFile }; var backupModData = new BackupModData { SimpleModData = simpleModData, ModPack = selectedModpack }; backupModpackData.ModsToBackup.Add(backupModData); } } var texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); string modPackPath = System.IO.Path.Combine(Properties.Settings.Default.ModPack_Directory, $"{backupModpackData.Name}.ttmp2"); bool overwriteModpack = false; 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) { overwriteModpack = true; } else if (overwriteDialogResult == System.Windows.Forms.DialogResult.Cancel) { await _progressController.CloseAsync(); return; } } var progressIndicator = new Progress <(int current, int total, string message)>(ReportProgress); ModPackFileName = backupModpackData.Name; await texToolsModPack.CreateBackupModpack(backupModpackData, _gameDirectory, progressIndicator, overwriteModpack); } catch (Exception ex) { FlexibleMessageBox.Show("Failed to create modpack.\n\nError: " + ex.Message, "Modpack Creation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } finally { await _progressController.CloseAsync(); } DialogResult = true; }
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); } }
/// <summary> /// Event handler for when the import modpack button is clicked /// </summary> private async void ImportModPackButton_Click(object sender, RoutedEventArgs e) { _progressController = await this.ShowProgressAsync(UIMessages.ModPackImportTitle, UIMessages.PleaseStandByMessage); try { var importList = new List <ModsJson>(); var selectedModpackNames = (from modpack in (List <BackupModpackItemEntry>)ModpackList.ItemsSource where (modpack.IsChecked) select modpack).Select(entry => entry.ModpackName); // Separately add the mods that aren't associated to any modpacks if they are to be included in the backup if (selectedModpackNames.Contains(UIStrings.Standalone_Non_ModPack)) { importList.AddRange(from modsJson in _modsJsons where (modsJson.ModPackEntry == null) select modsJson); } importList.AddRange(from modsJson in _modsJsons where (selectedModpackNames.Contains(modsJson.ModPackEntry?.name)) select modsJson); var texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); var gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); var modListDirectory = new DirectoryInfo(System.IO.Path.Combine(gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath)); var progressIndicator = new Progress <(int current, int total, string message)>(ReportProgress); var importResults = await Task.Run(async() => { return(await texToolsModPack.ImportModPackAsync(_modpackDirectory, importList, gameDirectory, modListDirectory, progressIndicator)); }); TotalModsImported = importResults.ImportCount; TotalModsErrored = importResults.ErrorCount; ImportDuration = importResults.Duration; if (!string.IsNullOrEmpty(importResults.Errors)) { FlexibleMessageBox.Show( $"{UIMessages.ErrorImportingModsMessage}\n\n{importResults.Errors}", UIMessages.ErrorImportingModsTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception ex) { FlexibleMessageBox.Show( $"{UIMessages.ErrorImportingModsMessage}\n\n{ex.Message}", UIMessages.ErrorImportingModsTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { await _progressController.CloseAsync(); } if (_messageInImport) { var durationString = ImportDuration.ToString("0.00"); await this.ShowMessageAsync(UIMessages.ImportCompleteTitle, string.Format(UIMessages.SuccessfulImportCountMessage, TotalModsImported, TotalModsErrored, durationString)); } MainWindow.GetMainWindow().ReloadItem(); DialogResult = true; }
private async Task CreateModpack() { 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 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); } } string modPackPath = Path.Combine(Properties.Settings.Default.ModPack_Directory, $"{simpleModPackData.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.Cancel) { return; } } 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); 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); } }
/// <summary> /// This method opens the modpack import wizard or imports a modpack silently /// </summary> /// <param name="path">The path to the modpack</param> /// <param name="silent">If the modpack wizard should be shown or the modpack should just be imported without any user interaction</param> /// <returns></returns> private async Task <int> ImportModpack(DirectoryInfo path, DirectoryInfo modPackDirectory, bool silent = false, bool messageInImport = false) { var importError = false; TextureView textureView = null; TextureViewModel textureViewModel = null; ModelView modelView = null; ModelViewModel modelViewModel = null; if (TextureTabItem != null && ModelTabItem != null) { textureView = TextureTabItem.Content as TextureView; textureViewModel = textureView.DataContext as TextureViewModel; modelView = ModelTabItem.Content as ModelView; modelViewModel = modelView.DataContext as ModelViewModel; } if (!path.Extension.Contains("ttmp")) { FlexibleMessageBox.Show(string.Format(UIMessages.UnsupportedFileExtensionErrorMessage, path.Extension), UIMessages.UnsupportedFileExtensionErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } try { var ttmp = new TTMP(modPackDirectory, XivStrings.TexTools); var ttmpData = await ttmp.GetModPackJsonData(path); if (ttmpData.ModPackJson.TTMPVersion.Contains("w")) { var gameDirectory = new DirectoryInfo(Settings.Default.FFXIV_Directory); var index = new Index(gameDirectory); if (index.IsIndexLocked(XivDataFile._0A_Exd)) { FlexibleMessageBox.Show(UIMessages.IndexLockedErrorMessage, UIMessages.IndexLockedErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } try { var importWizard = new ImportModPackWizard(ttmpData.ModPackJson, ttmpData.ImageDictionary, path, textureViewModel, modelViewModel, messageInImport); if (messageInImport) { importWizard.WindowStartupLocation = WindowStartupLocation.CenterScreen; } else { importWizard.Owner = this; } var result = importWizard.ShowDialog(); if (result == true) { return(importWizard.TotalModsImported); } } catch { importError = true; } } else if (ttmpData.ModPackJson.TTMPVersion.Contains("s")) { try { var simpleImport = new SimpleModPackImporter(path, ttmpData.ModPackJson, textureViewModel, modelViewModel, silent, messageInImport); if (messageInImport) { simpleImport.WindowStartupLocation = WindowStartupLocation.CenterScreen; } else { simpleImport.Owner = this; } var result = simpleImport.ShowDialog(); if (result == true) { return(simpleImport.TotalModsImported); } } catch { importError = true; } } } catch (Exception ex) { if (!importError) { var simpleImport = new SimpleModPackImporter(path, null, textureViewModel, modelViewModel, silent, messageInImport); if (messageInImport) { simpleImport.WindowStartupLocation = WindowStartupLocation.CenterScreen; } else { simpleImport.Owner = this; } var result = simpleImport.ShowDialog(); if (result == true) { return(simpleImport.TotalModsImported); } } else { FlexibleMessageBox.Show(string.Format(UIMessages.ModPackImportErrorMessage, path.FullName, ex.Message), UIMessages.ModPackImportErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } } return(0); }
/// <summary> /// Copies the entirety of a given root to a new root. /// </summary> /// <param name="Source">Original Root to copy from.</param> /// <param name="Destination">Destination root to copy to.</param> /// <param name="ApplicationSource">Application to list as the source for the resulting mod entries.</param> /// <returns>Returns a Dictionary of all the file conversion</returns> public static async Task <Dictionary <string, string> > CloneRoot(XivDependencyRoot Source, XivDependencyRoot Destination, string ApplicationSource, int singleVariant = -1, string saveDirectory = null, IProgress <string> ProgressReporter = null, IndexFile index = null, ModList modlist = null, ModPack modPack = null) { if (!IsSupported(Source) || !IsSupported(Destination)) { throw new InvalidDataException("Cannot clone unsupported root."); } if (ProgressReporter != null) { ProgressReporter.Report("Stopping Cache Worker..."); } var workerStatus = XivCache.CacheWorkerEnabled; XivCache.CacheWorkerEnabled = false; try { var df = IOUtil.GetDataFileFromPath(Source.ToString()); var _imc = new Imc(XivCache.GameInfo.GameDirectory); var _mdl = new Mdl(XivCache.GameInfo.GameDirectory, df); var _dat = new Dat(XivCache.GameInfo.GameDirectory); var _index = new Index(XivCache.GameInfo.GameDirectory); var _mtrl = new Mtrl(XivCache.GameInfo.GameDirectory); var _modding = new Modding(XivCache.GameInfo.GameDirectory); var doSave = false; if (index == null) { doSave = true; index = await _index.GetIndexFile(df); modlist = await _modding.GetModListAsync(); } bool locked = _index.IsIndexLocked(df); if (locked) { throw new Exception("Game files currently in use."); } if (ProgressReporter != null) { ProgressReporter.Report("Analyzing items and variants..."); } // First, try to get everything, to ensure it's all valid. ItemMetadata originalMetadata = await GetCachedMetadata(index, modlist, Source, df, _dat); var originalModelPaths = await Source.GetModelFiles(index, modlist); var originalMaterialPaths = await Source.GetMaterialFiles(-1, index, modlist); var originalTexturePaths = await Source.GetTextureFiles(-1, index, modlist); var originalVfxPaths = new HashSet <string>(); if (Imc.UsesImc(Source)) { var avfxSets = originalMetadata.ImcEntries.Select(x => x.Vfx).Distinct(); foreach (var avfx in avfxSets) { var avfxStuff = await ATex.GetVfxPath(Source.Info, avfx); if (String.IsNullOrEmpty(avfxStuff.Folder) || String.IsNullOrEmpty(avfxStuff.File)) { continue; } var path = avfxStuff.Folder + "/" + avfxStuff.File; if (index.FileExists(path)) { originalVfxPaths.Add(path); } } } // Time to start editing things. // First, get a new, clean copy of the metadata, pointed at the new root. var newMetadata = await GetCachedMetadata(index, modlist, Source, df, _dat); newMetadata.Root = Destination.Info.ToFullRoot(); ItemMetadata originalDestinationMetadata = null; try { originalDestinationMetadata = await GetCachedMetadata(index, modlist, Destination, df, _dat); } catch { originalDestinationMetadata = new ItemMetadata(Destination); } // Set 0 needs special handling. if (Source.Info.PrimaryType == XivItemType.equipment && Source.Info.PrimaryId == 0) { var set1Root = new XivDependencyRoot(Source.Info.PrimaryType, 1, null, null, Source.Info.Slot); var set1Metadata = await GetCachedMetadata(index, modlist, set1Root, df, _dat); newMetadata.EqpEntry = set1Metadata.EqpEntry; if (Source.Info.Slot == "met") { newMetadata.GmpEntry = set1Metadata.GmpEntry; } } else if (Destination.Info.PrimaryType == XivItemType.equipment && Destination.Info.PrimaryId == 0) { newMetadata.EqpEntry = null; newMetadata.GmpEntry = null; } // Now figure out the path names for all of our new paths. // These dictionarys map Old Path => New Path Dictionary <string, string> newModelPaths = new Dictionary <string, string>(); Dictionary <string, string> newMaterialPaths = new Dictionary <string, string>(); Dictionary <string, string> newMaterialFileNames = new Dictionary <string, string>(); Dictionary <string, string> newTexturePaths = new Dictionary <string, string>(); Dictionary <string, string> newAvfxPaths = new Dictionary <string, string>(); if (ProgressReporter != null) { ProgressReporter.Report("Calculating files to copy..."); } // For each path, replace any instances of our primary and secondary types. foreach (var path in originalModelPaths) { newModelPaths.Add(path, UpdatePath(Source, Destination, path)); } foreach (var path in originalMaterialPaths) { var nPath = UpdatePath(Source, Destination, path); newMaterialPaths.Add(path, nPath); var fName = Path.GetFileName(path); if (!newMaterialFileNames.ContainsKey(fName)) { newMaterialFileNames.Add(fName, Path.GetFileName(nPath)); } } foreach (var path in originalTexturePaths) { newTexturePaths.Add(path, UpdatePath(Source, Destination, path)); } foreach (var path in originalVfxPaths) { newAvfxPaths.Add(path, UpdatePath(Source, Destination, path)); } var destItem = Destination.GetFirstItem(); var srcItem = (await Source.GetAllItems(singleVariant))[0]; var iCat = destItem.SecondaryCategory; var iName = destItem.Name; var files = newModelPaths.Select(x => x.Value).Union( newMaterialPaths.Select(x => x.Value)).Union( newAvfxPaths.Select(x => x.Value)).Union( newTexturePaths.Select(x => x.Value)); var allFiles = new HashSet <string>(); foreach (var f in files) { allFiles.Add(f); } allFiles.Add(Destination.Info.GetRootFile()); if (ProgressReporter != null) { ProgressReporter.Report("Getting modlist..."); } if (ProgressReporter != null) { ProgressReporter.Report("Removing existing modifications to destination root..."); } if (Destination != Source) { var dPath = Destination.Info.GetRootFolder(); var allMods = modlist.Mods.ToList(); foreach (var mod in allMods) { if (mod.fullPath.StartsWith(dPath) && !mod.IsInternal()) { if (Destination.Info.SecondaryType != null || Destination.Info.Slot == null) { // If this is a slotless root, purge everything. await _modding.DeleteMod(mod.fullPath, false, index, modlist); } else if (allFiles.Contains(mod.fullPath) || mod.fullPath.Contains(Destination.Info.GetBaseFileName(true))) { // Otherwise, only purge the files we're replacing, and anything else that // contains our slot name. await _modding.DeleteMod(mod.fullPath, false, index, modlist); } } } } if (ProgressReporter != null) { ProgressReporter.Report("Copying models..."); } // Load, Edit, and resave the model files. foreach (var kv in newModelPaths) { var src = kv.Key; var dst = kv.Value; var offset = index.Get8xDataOffset(src); var xmdl = await _mdl.GetRawMdlData(src, false, offset); var tmdl = TTModel.FromRaw(xmdl); if (xmdl == null || tmdl == null) { continue; } tmdl.Source = dst; xmdl.MdlPath = dst; // Replace any material references as needed. foreach (var m in tmdl.MeshGroups) { foreach (var matKv in newMaterialFileNames) { m.Material = m.Material.Replace(matKv.Key, matKv.Value); } } // Save new Model. var bytes = await _mdl.MakeNewMdlFile(tmdl, xmdl, null); await _dat.WriteModFile(bytes, dst, ApplicationSource, destItem, index, modlist); } if (ProgressReporter != null) { ProgressReporter.Report("Copying textures..."); } // Raw Copy all Texture files to the new destinations to avoid having the MTRL save functions auto-generate blank textures. foreach (var kv in newTexturePaths) { var src = kv.Key; var dst = kv.Value; await _dat.CopyFile(src, dst, ApplicationSource, true, destItem, index, modlist); } if (ProgressReporter != null) { ProgressReporter.Report("Copying materials..."); } HashSet <string> CopiedMaterials = new HashSet <string>(); // Load every Material file and edit the texture references to the new texture paths. foreach (var kv in newMaterialPaths) { var src = kv.Key; var dst = kv.Value; try { var offset = index.Get8xDataOffset(src); if (offset == 0) { continue; } var xivMtrl = await _mtrl.GetMtrlData(offset, src, 11); xivMtrl.MTRLPath = dst; for (int i = 0; i < xivMtrl.TexturePathList.Count; i++) { foreach (var tkv in newTexturePaths) { xivMtrl.TexturePathList[i] = xivMtrl.TexturePathList[i].Replace(tkv.Key, tkv.Value); } } await _mtrl.ImportMtrl(xivMtrl, destItem, ApplicationSource, index, modlist); CopiedMaterials.Add(dst); } catch (Exception ex) { // Let functions later handle this mtrl then. } } if (ProgressReporter != null) { ProgressReporter.Report("Copying VFX..."); } // Copy VFX files. foreach (var kv in newAvfxPaths) { var src = kv.Key; var dst = kv.Value; await _dat.CopyFile(src, dst, ApplicationSource, true, destItem, index, modlist); } if (ProgressReporter != null) { ProgressReporter.Report("Creating missing variants..."); } // Check to see if we need to add any variants var cloneNum = newMetadata.ImcEntries.Count >= 2 ? 1 : 0; while (originalDestinationMetadata.ImcEntries.Count > newMetadata.ImcEntries.Count) { // Clone Variant 1 into the variants we are missing. newMetadata.ImcEntries.Add((XivImc)newMetadata.ImcEntries[cloneNum].Clone()); } if (singleVariant >= 0) { if (ProgressReporter != null) { ProgressReporter.Report("Setting single-variant data..."); } if (singleVariant < newMetadata.ImcEntries.Count) { var v = newMetadata.ImcEntries[singleVariant]; for (int i = 0; i < newMetadata.ImcEntries.Count; i++) { newMetadata.ImcEntries[i] = (XivImc)v.Clone(); } } } // Update Skeleton references to be for the correct set Id. var setId = Destination.Info.SecondaryId == null ? (ushort)Destination.Info.PrimaryId : (ushort)Destination.Info.SecondaryId; foreach (var entry in newMetadata.EstEntries) { entry.Value.SetId = setId; } if (ProgressReporter != null) { ProgressReporter.Report("Copying metdata..."); } // Poke through the variants and adjust any that point to null Material Sets to instead use a valid one. if (newMetadata.ImcEntries.Count > 0 && originalMetadata.ImcEntries.Count > 0) { var valid = newMetadata.ImcEntries.FirstOrDefault(x => x.MaterialSet != 0).MaterialSet; if (valid <= 0) { valid = originalMetadata.ImcEntries.FirstOrDefault(x => x.MaterialSet != 0).MaterialSet; } for (int i = 0; i < newMetadata.ImcEntries.Count; i++) { var entry = newMetadata.ImcEntries[i]; if (entry.MaterialSet == 0) { entry.MaterialSet = valid; } } } await ItemMetadata.SaveMetadata(newMetadata, ApplicationSource, index, modlist); // Save the new Metadata file via the batch function so that it's only written to the memory cache for now. await ItemMetadata.ApplyMetadataBatched(new List <ItemMetadata>() { newMetadata }, index, modlist, false); if (ProgressReporter != null) { ProgressReporter.Report("Filling in missing material sets..."); } // Validate all variants/material sets for valid materials, and copy materials as needed to fix. if (Imc.UsesImc(Destination)) { var mSets = newMetadata.ImcEntries.Select(x => x.MaterialSet).Distinct(); foreach (var mSetId in mSets) { var path = Destination.Info.GetRootFolder() + "material/v" + mSetId.ToString().PadLeft(4, '0') + "/"; foreach (var mkv in newMaterialFileNames) { // See if the material was copied over. var destPath = path + mkv.Value; if (CopiedMaterials.Contains(destPath)) { continue; } string existentCopy = null; // If not, find a material where one *was* copied over. foreach (var mSetId2 in mSets) { var p2 = Destination.Info.GetRootFolder() + "material/v" + mSetId2.ToString().PadLeft(4, '0') + "/"; foreach (var cmat2 in CopiedMaterials) { if (cmat2 == p2 + mkv.Value) { existentCopy = cmat2; break; } } } // Shouldn't ever actually hit this, but if we do, nothing to be done about it. if (existentCopy == null) { continue; } // Copy the material over. await _dat.CopyFile(existentCopy, destPath, ApplicationSource, true, destItem, index, modlist); } } } if (ProgressReporter != null) { ProgressReporter.Report("Updating modlist..."); } if (modPack == null) { modPack = new ModPack() { author = "System", name = "Item Copy - " + srcItem.Name + " to " + iName, url = "", version = "1.0" }; } List <Mod> mods = new List <Mod>(); foreach (var mod in modlist.Mods) { if (allFiles.Contains(mod.fullPath)) { // Ensure all of our modified files are attributed correctly. mod.name = iName; mod.category = iCat; mod.source = ApplicationSource; mod.modPack = modPack; mods.Add(mod); } } if (!modlist.ModPacks.Any(x => x.name == modPack.name)) { modlist.ModPacks.Add(modPack); } if (doSave) { // Save everything. await _index.SaveIndexFile(index); await _modding.SaveModListAsync(modlist); } XivCache.QueueDependencyUpdate(allFiles.ToList()); if (saveDirectory != null) { ProgressReporter.Report("Creating TTMP File..."); var desc = "Item Converter Modpack - " + srcItem.Name + " -> " + iName + "\nCreated at: " + DateTime.Now.ToString(); // Time to save the modlist to file. var dir = new DirectoryInfo(saveDirectory); var _ttmp = new TTMP(dir, ApplicationSource); var smpd = new SimpleModPackData() { Author = modPack.author, Description = desc, Url = modPack.url, Version = new Version(1, 0, 0), Name = modPack.name, SimpleModDataList = new List <SimpleModData>() }; foreach (var mod in mods) { var size = await _dat.GetCompressedFileSize(mod.data.modOffset, df); var smd = new SimpleModData() { Name = iName, FullPath = mod.fullPath, DatFile = df.GetDataFileName(), Category = iCat, IsDefault = false, ModSize = size, ModOffset = mod.data.modOffset }; smpd.SimpleModDataList.Add(smd); } await _ttmp.CreateSimpleModPack(smpd, XivCache.GameInfo.GameDirectory, null, true); } if (ProgressReporter != null) { ProgressReporter.Report("Root copy complete."); } // Return the final file conversion listing. var ret = newModelPaths.Union(newMaterialPaths).Union(newAvfxPaths).Union(newTexturePaths); var dict = ret.ToDictionary(x => x.Key, x => x.Value); dict.Add(Source.Info.GetRootFile(), Destination.Info.GetRootFile()); return(dict); } finally { XivCache.CacheWorkerEnabled = workerStatus; } }
private async void Menu_ModConverter_Click(object sender, RoutedEventArgs e) { var modPackDirectory = new DirectoryInfo(Settings.Default.ModPack_Directory); var openFileDialog = new OpenFileDialog { InitialDirectory = modPackDirectory.FullName, Filter = "TexToolsModPack TTMP (*.ttmp;*.ttmp2)|*.ttmp;*.ttmp2" }; if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return; } var ttmpFileName = openFileDialog.FileName; var ttmp = new TTMP(modPackDirectory, XivStrings.TexTools); (ModPackJson ModPackJson, Dictionary <string, Image> ImageDictionary)ttmpData; var progressController = await this.ShowProgressAsync(UIStrings.Mod_Converter, UIMessages.PleaseStandByMessage); var modsJsonList = await ttmp.GetOriginalModPackJsonData(new DirectoryInfo(ttmpFileName)); if (modsJsonList == null) { ttmpData = await ttmp.GetModPackJsonData(new DirectoryInfo(ttmpFileName)); } else { ttmpData = (ModPackJson : new ModPackJson(), ImageDictionary : new Dictionary <string, Image>()); ttmpData.ModPackJson.Author = "Mod Converter"; ttmpData.ModPackJson.Version = "1.0.0"; ttmpData.ModPackJson.Name = Path.GetFileNameWithoutExtension(ttmpFileName); ttmpData.ModPackJson.TTMPVersion = "s"; ttmpData.ModPackJson.SimpleModsList = new List <ModsJson>(); foreach (var mod in modsJsonList) { var modsJson = new ModsJson(); modsJson.Category = mod.Category; modsJson.DatFile = mod.DatFile; modsJson.FullPath = mod.FullPath; modsJson.ModOffset = mod.ModOffset; modsJson.ModPackEntry = null; modsJson.ModSize = mod.ModSize; modsJson.Name = mod.Name; ttmpData.ModPackJson.SimpleModsList.Add(modsJson); } } var categorys = ItemTreeView.ItemsSource as ObservableCollection <Category>; var list = new List <xivModdingFramework.Items.Interfaces.IItem>(); var ctgs1 = categorys[0]; foreach (var ctgs2 in ctgs1.Categories) { if (ctgs2.Item != null) { list.Add(ctgs2.Item); continue; } foreach (var ctgs3 in ctgs2.Categories) { if (ctgs3.Item != null) { list.Add(ctgs3.Item); } } } var modConverterView = new ModConverterView(list, ttmpFileName, ttmpData) { Owner = this, WindowStartupLocation = WindowStartupLocation.CenterOwner }; await progressController.CloseAsync(); modConverterView.ShowDialog(); }
/// <summary> /// The event handler for the create mod pack button /// </summary> /// <remarks> /// This is originally the help button, but has been repurposed /// </remarks> private async void ModPackWizard_CreateModPack(object sender, System.Windows.RoutedEventArgs e) { _progressController = await this.ShowProgressAsync(UIMessages.ModPackCreationMessage, UIMessages.PleaseStandByMessage); try { var wizPages = modPackWizard.Items; var modPackData = new ModPackData { Name = ModPackName.Text, Author = ModPackAuthor.Text, Version = VersionNumber, Description = ModPackDescription.Text, Url = ModPackUrl.Text, ModPackPages = new List <ModPackData.ModPackPage>() }; var pageIndex = 0; foreach (var wizPageItem in wizPages) { var wizPage = wizPageItem as WizardPage; if (wizPage.Content is WizardModPackControl control) { if (control.ModGroupList.Count > 0) { modPackData.ModPackPages.Add(new ModPackData.ModPackPage { PageIndex = pageIndex, ModGroups = control.ModGroupList }); } } pageIndex++; } if (modPackData.ModPackPages.Count > 0) { var progressIndicator = new Progress <double>(ReportProgress); var texToolsModPack = new TTMP(new DirectoryInfo(Properties.Settings.Default.ModPack_Directory), XivStrings.TexTools); var modPackPath = Path.Combine(Properties.Settings.Default.ModPack_Directory, $"{modPackData.Name}.ttmp2"); var overwriteModpack = false; if (File.Exists(modPackPath)) { var overwriteDialogResult = FlexibleMessageBox.Show(new Wpf32Window(this), UIMessages.ModPackOverwriteMessage, UIMessages.OverwriteTitle, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning); if (overwriteDialogResult == System.Windows.Forms.DialogResult.Yes) { overwriteModpack = true; } else if (overwriteDialogResult == System.Windows.Forms.DialogResult.Cancel) { return; } } await texToolsModPack.CreateWizardModPack(modPackData, progressIndicator, overwriteModpack); ModPackFileName = $"{ModPackName.Text}"; } else { ModPackFileName = "NoData"; } } catch (Exception ex) { FlexibleMessageBox.Show("Failed to create modpack.\n\nError: " + ex.Message, "Modpack Creation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } finally { await _progressController.CloseAsync(); } DialogResult = true; }
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); } }
/// <summary> /// This method opens the modpack import wizard or imports a modpack silently /// </summary> /// <param name="path">The path to the modpack</param> /// <param name="silent">If the modpack wizard should be shown or the modpack should just be imported without any user interaction</param> /// <returns></returns> private async Task <int> ImportModpack(DirectoryInfo path, DirectoryInfo modPackDirectory, bool silent = false) { var importError = false; try { var ttmp = new TTMP(modPackDirectory, XivStrings.TexTools); var ttmpData = ttmp.GetModPackJsonData(path); if (ttmpData.ModPackJson.TTMPVersion.Contains("w")) { try { var importWizard = new ImportModPackWizard(ttmpData.ModPackJson, ttmpData.ImageDictionary, path) { Owner = this }; var result = importWizard.ShowDialog(); if (result == true) { return(importWizard.TotalModsImported); } } catch { importError = true; } } else if (ttmpData.ModPackJson.TTMPVersion.Contains("s")) { try { var simpleImport = new SimpleModPackImporter(path, ttmpData.ModPackJson, silent) { Owner = this }; var result = simpleImport.ShowDialog(); if (result == true) { return(simpleImport.TotalModsImported); } } catch { importError = true; } } } catch (Exception ex) { if (!importError) { var simpleImport = new SimpleModPackImporter(path, null, silent) { Owner = this }; var result = simpleImport.ShowDialog(); if (result == true) { return(simpleImport.TotalModsImported); } } else { FlexibleMessageBox.Show($"There was an error importing the mod pack at {path.FullName}\n\nMessage: {ex.Message}", $"ModPack Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } } return(0); }