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(); }
private void TreeRefreshRequested(object sender, EventArgs e) { IProgress <(int current, string category)> progress = new Progress <(int current, string category)>((prog) => { if (prog.category == "Done") { ProgressBarVisible = Visibility.Collapsed; ProgressLabelVisible = Visibility.Collapsed; } else { ProgressValue = prog.current; ProgressLabel = $"Loading {prog.category} List"; } }); _mainWindow.ItemSearchTextBox.IsEnabled = false; var gameDirectory = new DirectoryInfo(Settings.Default.FFXIV_Directory); var lang = XivLanguages.GetXivLanguage(Settings.Default.Application_Language); try { // Settings are valid, application is updated, initialize the // Cache once so it can test if it needs to be updated as well. var _cache = new XivCache(gameDirectory, lang); FillTree(progress).GetAwaiter().OnCompleted(OnTreeRefreshCompleted); } catch (Exception ex) { // Revert to English when there were errors while loading the item tree/cache // and the game language was set to Chinese or Korean (they have separate clients) if (lang == XivLanguage.Chinese || lang == XivLanguage.Korean) { if (FlexibleMessageBox.Show(UIMessages.LanguageError, UIMessages.LanguageErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK) { Properties.Settings.Default.Application_Language = "en"; Properties.Settings.Default.Save(); System.Windows.Forms.Application.Restart(); System.Windows.Application.Current.Shutdown(); } } else { // Make this error not totally silent at least. FlexibleMessageBox.Show("An error occurred while trying to populate the item list.", "Item list Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
private async Task CheckCache() { var gameDirectory = new DirectoryInfo(Settings.Default.FFXIV_Directory); var lang = XivLanguages.GetXivLanguage(Settings.Default.Application_Language); await Task.Run(async() => { var _cache = new XivCache(gameDirectory, lang); _cache.RebuildCache(); }); AddText("\tCache Rebuilt Successfully.", textColor); AddText("\t\u2714\n", "Green"); }
/// <summary> /// Initializes the Cache and loads the item tree for the first time when done. /// </summary> /// <returns></returns> private async Task InitializeCache() { var gameDir = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); var lang = XivLanguages.GetXivLanguage(Properties.Settings.Default.Application_Language); await LockUi(UIStrings.Updating_Cache, UIStrings.Updating_Cache_Message, this); // Kick this in a new thread because the cache call will lock up the one it's on if it has to do a rebuild. await Task.Run(async() => { bool cacheOK = true; try { // If the cache needs to be rebuilt, this will synchronously block until it is done. XivCache.SetGameInfo(gameDir, lang); } catch (Exception ex) { cacheOK = false; FlexibleMessageBox.Show("An error occurred while attempting to rebuild the cache.\n" + ex.Message, "Cache Rebuild Error.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); } await Dispatcher.Invoke(async() => { await UnlockUi(); if (cacheOK) { await RefreshTree(); } if (InitialLoadComplete != null) { InitialLoadComplete.Invoke(this, null); } }); }); }
public LanguageOptionsView() { InitializeComponent(); CurrentLanguageLabel.Content = $"{XivLanguages.GetXivLanguage(Properties.Settings.Default.Application_Language)}"; }
/// <summary> /// Event handler for the start over menu item clicked /// </summary> private async void Menu_StartOver_Click(object sender, RoutedEventArgs e) { 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; } var result = FlexibleMessageBox.Show(UIMessages.StartOverMessage, UIMessages.StartOverTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (result == System.Windows.Forms.DialogResult.Yes) { var indexBackupsDirectory = new DirectoryInfo(Settings.Default.Backup_Directory); if (!Directory.Exists(indexBackupsDirectory.FullName)) { FlexibleMessageBox.Show(UIMessages.BackupFolderAccessErrorMessage, UIMessages.IndexBackupsErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var problemChecker = new ProblemChecker(gameDirectory); var progressController = await this.ShowProgressAsync(UIStrings.Start_Over, UIMessages.PleaseStandByMessage); progressController.SetIndeterminate(); IProgress <string> progress = new Progress <string>((update) => { progressController.SetMessage(update); }); try { await problemChecker.PerformStartOver(indexBackupsDirectory, progress, XivLanguages.GetXivLanguage(Settings.Default.Application_Language)); } catch { FlexibleMessageBox.Show(UIMessages.StartOverErrorMessage, UIMessages.StartOverErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); await progressController.CloseAsync(); return; } MainWindow.GetMainWindow().RefreshTree(this); await progressController.CloseAsync(); var c = (ItemTreeView.SelectedItem as Category); UpdateViews(c); await this.ShowMessageAsync(UIMessages.StartOverCompleteTitle, UIMessages.StartOverCompleteMessage); } }
/// <summary> /// Updates the View/ViewModel with a new selected base item. /// </summary> /// <param name="item"></param> /// <returns></returns> public async Task <bool> SetItem(IItem item, MainWindow mainWindow = null) { var gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); _imc = new Imc(gameDirectory, item.DataFile); _gear = new Gear(gameDirectory, XivLanguages.GetXivLanguage(Properties.Settings.Default.Application_Language)); if (mainWindow != null) { _mainWindow = mainWindow; } _item = item; _tree.Items.Clear(); IItemModel im = null; try { im = (IItemModel)item; } catch (Exception ex) { return(false); } if (im == null || im.ModelInfo == null) { return(false); } var topLevelItem = new TreeViewItem(); topLevelItem.Header = ""; if (im.ModelInfo.PrimaryID > 0) { topLevelItem.Header += CapFirst(item.GetPrimaryItemType().ToString()) + " #" + im.ModelInfo.PrimaryID.ToString().PadLeft(4, '0'); } else { topLevelItem.Header += CapFirst(item.GetPrimaryItemType().ToString()); } _tree.Items.Add(topLevelItem); var nextParent = topLevelItem; if (im.ModelInfo.SecondaryID > 0) { var nextNode = new TreeViewItem(); nextNode.Header += CapFirst(item.GetSecondaryItemType().ToString()) + " #" + im.ModelInfo.SecondaryID.ToString().PadLeft(4, '0'); nextParent.Items.Add(nextNode); nextParent.IsExpanded = true; nextParent = nextNode; } var abbreviation = _item.GetItemSlotAbbreviation(); if (abbreviation != "") { var nextNode = new TreeViewItem(); nextNode.Header = Mdl.SlotAbbreviationDictionary.First(x => x.Value == abbreviation).Key; nextParent.Items.Add(nextNode); nextParent.IsExpanded = true; nextParent = nextNode; } FullImcInfo fullInfo = null; try { fullInfo = await _imc.GetFullImcInfo(im); } catch (Exception ex) { // This item has no IMC file. var nextNode = new TreeViewItem(); nextNode.Header = im.Name; nextNode.DataContext = im; //nextNode.MouseDoubleClick += ItemNode_Activated; nextParent.Items.Add(nextNode); nextParent.IsExpanded = true; nextNode.IsSelected = true; nextParent = nextNode; // No shared items for things without IMC files, so just hide the view entirely? return(false); } var sharedList = await _gear.GetSameModelList(im); var myVariantNumber = fullInfo.GetEntry(im.ModelInfo.ImcSubsetID, im.GetItemSlotAbbreviation()).Variant; var myImcNumber = im.ModelInfo.ImcSubsetID; var materialVariantHeaders = new Dictionary <int, TreeViewItem>(); var imcVariantHeaders = new Dictionary <int, TreeViewItem>(); // TODO - // Add the Variant header nodes at the start, and only scan the IMC files when a TreeViewItem myMaterialHeader = null; TreeViewItem myImcHeader = null; TreeViewItem myNode = null; foreach (var i in sharedList) { // Get the Variant # information var info = fullInfo.GetEntry(i.ModelInfo.ImcSubsetID, i.GetItemSlotAbbreviation()); if (info == null) { // Invalid IMC Set ID for the item. continue; } if (!materialVariantHeaders.ContainsKey(info.Variant)) { materialVariantHeaders.Add(info.Variant, new TreeViewItem()); materialVariantHeaders[info.Variant].Header = "Material Variant #" + info.Variant; materialVariantHeaders[info.Variant].DataContext = info.Variant; } if (!imcVariantHeaders.ContainsKey(i.ModelInfo.ImcSubsetID)) { imcVariantHeaders.Add(i.ModelInfo.ImcSubsetID, new TreeViewItem()); imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header = "IMC Variant #" + i.ModelInfo.ImcSubsetID; imcVariantHeaders[i.ModelInfo.ImcSubsetID].DataContext = i.ModelInfo.ImcSubsetID; var hiddenParts = MaskToHidenParts(info.Mask); imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += " - Hidden Parts: "; if (hiddenParts.Count > 0) { imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += String.Join(",", hiddenParts); } else { imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += "None"; } materialVariantHeaders[info.Variant].Items.Add(imcVariantHeaders[i.ModelInfo.ImcSubsetID]); if (i.ModelInfo.ImcSubsetID == myImcNumber) { myImcHeader = imcVariantHeaders[i.ModelInfo.ImcSubsetID]; } } var nextNode = new TreeViewItem(); nextNode.Header = i.Name; nextNode.DataContext = i; imcVariantHeaders[i.ModelInfo.ImcSubsetID].Items.Add(nextNode); if (myMaterialHeader == null && info.Variant == myVariantNumber) { myMaterialHeader = materialVariantHeaders[info.Variant]; } if (i.Name == im.Name) { myNode = nextNode; } else { nextNode.MouseDoubleClick += ItemNode_Activated; } } var ordered = materialVariantHeaders.OrderBy(x => x.Key); foreach (var kv in ordered) { nextParent.Items.Add(kv.Value); } nextParent.IsExpanded = true; if (myMaterialHeader != null) { myMaterialHeader.IsExpanded = true; } if (myImcHeader != null) { myImcHeader.IsExpanded = true; } if (myNode != null) { myNode.IsSelected = true; } return(true); }
private static XivLanguage GetLanguage() { return(XivLanguages.GetXivLanguage(Properties.Settings.Default.Application_Language)); }
private async void Initialize() { SetDirectories(true); _gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); _index = new Index(_gameDirectory); ProgressLabel = "Checking for old installs..."; CheckForOldModList(); ProgressLabel = "Checking Game Version..."; await CheckGameVersion(); ProgressLabel = "Checking Index Files..."; await CheckIndexFiles(); IProgress <(int current, string category)> progress = new Progress <(int current, string category)>((prog) => { if (prog.category == "Done") { ProgressBarVisible = Visibility.Collapsed; ProgressLabelVisible = Visibility.Collapsed; } else { ProgressValue = prog.current; ProgressLabel = $"Loading {prog.category} List"; } }); _mainWindow.ItemSearchTextBox.IsEnabled = false; var gameDirectory = new DirectoryInfo(Settings.Default.FFXIV_Directory); var lang = XivLanguages.GetXivLanguage(Settings.Default.Application_Language); try { // Settings are valid, application is updated, initialize the // Cache once so it can test if it needs to be updated as well. var _cache = new XivCache(gameDirectory, lang); await FillTree(progress); } catch (Exception e) { // Revert to English when there were errors while loading the item tree/cache // and the game language was set to Chinese or Korean (they have separate clients) if (lang == XivLanguage.Chinese || lang == XivLanguage.Korean) { if (FlexibleMessageBox.Show(UIMessages.LanguageError, UIMessages.LanguageErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK) { Properties.Settings.Default.Application_Language = "en"; Properties.Settings.Default.Save(); System.Windows.Forms.Application.Restart(); System.Windows.Application.Current.Shutdown(); } } } _mainWindow.Menu_ModConverter.IsEnabled = true; _mainWindow.ItemSearchTextBox.IsEnabled = true; _mainWindow.SetFilter(); SetDefaults(); }
private async Task CheckGameVersion() { var applicationVersion = FileVersionInfo .GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion; Version ffxivVersion = null; var needsNewBackup = false; var backupMessage = ""; var modding = new Modding(_gameDirectory); var backupDirectory = new DirectoryInfo(Properties.Settings.Default.Backup_Directory); var versionFile = $"{_gameDirectory.Parent.Parent.FullName}\\ffxivgame.ver"; if (File.Exists(versionFile)) { var versionData = File.ReadAllLines(versionFile); ffxivVersion = new Version(versionData[0].Substring(0, versionData[0].LastIndexOf("."))); } else { FlexibleMessageBox.Show(_win32Window, UIMessages.GameVersionErrorMessage, string.Format(UIMessages.GameVersionErrorTitle, applicationVersion), MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } if (string.IsNullOrEmpty(Properties.Settings.Default.FFXIV_Version)) { Properties.Settings.Default.FFXIV_Version = ffxivVersion.ToString(); Properties.Settings.Default.Save(); needsNewBackup = true; backupMessage = UIMessages.NewInstallDetectedBackupMessage; } else { var versionCheck = new Version(Properties.Settings.Default.FFXIV_Version); if (ffxivVersion > versionCheck) { needsNewBackup = true; backupMessage = UIMessages.NewerVersionDetectedBackupMessage; } } if (!Directory.Exists(backupDirectory.FullName)) { FlexibleMessageBox.Show(_win32Window, UIMessages.BackupsDirectoryErrorMessage, UIMessages.BackupFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } if (Directory.GetFiles(backupDirectory.FullName).Length == 0) { needsNewBackup = true; backupMessage = UIMessages.NoBackupsFoundMessage; } if (needsNewBackup) { var indexFiles = new XivDataFile[] { XivDataFile._0A_Exd, XivDataFile._04_Chara, XivDataFile._06_Ui, XivDataFile._01_Bgcommon }; if (FlexibleMessageBox.Show(_win32Window, backupMessage, UIMessages.CreateBackupTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { if (_index.IsIndexLocked(XivDataFile._0A_Exd)) { FlexibleMessageBox.Show(_win32Window, UIMessages.IndexLockedBackupFailedMessage, UIMessages.BackupFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } try { // Need to initialize the cache here before doing the mod toggle. var gameDir = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); var lang = XivLanguages.GetXivLanguage(Properties.Settings.Default.Application_Language); XivCache.SetGameInfo(gameDir, lang, true); await modding.ToggleAllMods(false); } catch (Exception ex) { FlexibleMessageBox.Show(_win32Window, string.Format(UIMessages.BackupFailedErrorMessage, ex.Message), UIMessages.BackupFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } foreach (var xivDataFile in indexFiles) { try { File.Copy($"{_gameDirectory.FullName}\\{xivDataFile.GetDataFileName()}.win32.index", $"{backupDirectory}\\{xivDataFile.GetDataFileName()}.win32.index", true); File.Copy($"{_gameDirectory.FullName}\\{xivDataFile.GetDataFileName()}.win32.index2", $"{backupDirectory}\\{xivDataFile.GetDataFileName()}.win32.index2", true); } catch (Exception e) { FlexibleMessageBox.Show(_win32Window, string.Format(UIMessages.BackupFailedErrorMessage, e.Message), UIMessages.BackupFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } } Properties.Settings.Default.FFXIV_Version = ffxivVersion.ToString(); Properties.Settings.Default.Save(); } } }
public MainWindow(string[] args) { _mainWindow = this; AutoUpdater.ApplicationExitEvent += AutoUpdater_ApplicationExitEvent; // Forcefully assign the correct working directory. This helps keep the // AutoUpdater from choking. var cwd = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); Directory.SetCurrentDirectory(cwd); CheckForUpdates(); // This slightly unusual contrivance is to ensure that we actually exit program on updates // *before* performing the rest of the startup initialization. If we let it continue // some odd things can result. // In particular, threads can be spawned that may keep the application files locked when // the updater wants to replace them, and/or new installs can error out on the culture info // lines below, due to not having valid settings after Application.Shutdown() was already called. if (_UPDATING) { // Shut down any other copies of TexTools that are active. MainWindow.MakeHighlander(); if (Application.Current != null) { Application.Current.Shutdown(); } return; } CheckForSettingsUpdate(); LanguageSelection(); var ci = new CultureInfo(Properties.Settings.Default.Application_Language) { NumberFormat = { NumberDecimalSeparator = "." } }; CultureInfo.DefaultThreadCurrentCulture = ci; CultureInfo.DefaultThreadCurrentUICulture = ci; CultureInfo.CurrentCulture = ci; CultureInfo.CurrentUICulture = ci; // Data Context needs to be set before we call Initialize Component to ensure // that the bindings get connected immediately, and not after the constructor. var mainViewModel = new MainViewModel(this); this.DataContext = mainViewModel; InitializeComponent(); var fileVersion = FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion; // Clear out the debug message shown in the xaml designer. StatusTextBox.Text = ""; try { if (System.Globalization.CultureInfo.CurrentUICulture.Name == "zh") { this.ChinaDiscordButton.Visibility = Visibility.Visible; } } catch (Exception e) { System.Windows.MessageBox.Show(string.Format(UIMessages.DependencyErrorMessage, e.Message, e.InnerException), string.Format(UIMessages.DependencyErrorTitle, fileVersion)); Environment.Exit(-1); return; } if (args != null && args.Length > 0) { // Just do a hard synchronous cache initialization for import only mode. var gameDir = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); var lang = XivLanguages.GetXivLanguage(Properties.Settings.Default.Application_Language); XivCache.SetGameInfo(gameDir, lang); _startupArgs = args[0]; OnlyImport(); } else { this.Show(); var textureView = TextureTabItem.Content as TextureView; var textureViewModel = textureView.DataContext as TextureViewModel; textureViewModel.LoadingComplete += TextureViewModelOnLoadingComplete; var modelView = ModelTabItem.Content as ModelView; var modelViewModel = modelView.DataContext as ModelViewModel; modelViewModel.LoadingComplete += ModelViewModelOnLoadingComplete; modelViewModel.AddToFullModelEvent += ModelViewModelOnAddToFullModelEvent; // This can be set whereever, since the item select won't fire it unless things are loaded fully. ItemSelect.ItemSelected += ItemSelect_ItemSelected; ItemSelect.ItemsLoaded += OnTreeLoaded; InitializeCache(); } }
/// <summary> /// Event handler for the start over menu item clicked /// </summary> private async void Menu_StartOver_Click(object sender, RoutedEventArgs e) { 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; } var result = FlexibleMessageBox.Show(UIMessages.StartOverMessage, UIMessages.StartOverTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (result == System.Windows.Forms.DialogResult.Yes) { var indexBackupsDirectory = new DirectoryInfo(Settings.Default.Backup_Directory); if (!Directory.Exists(indexBackupsDirectory.FullName)) { FlexibleMessageBox.Show(UIMessages.BackupFolderAccessErrorMessage, UIMessages.IndexBackupsErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var problemChecker = new ProblemChecker(gameDirectory); await LockUi(UIStrings.Start_Over, UIMessages.PleaseStandByMessage, this); try { await problemChecker.PerformStartOver(indexBackupsDirectory, _lockProgress, XivLanguages.GetXivLanguage(Settings.Default.Application_Language)); } catch (Exception ex) { FlexibleMessageBox.Show(UIMessages.StartOverErrorMessage, UIMessages.StartOverErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); await UnlockUi(); return; } await UnlockUi(); await RefreshTree(this); var item = ItemSelect.SelectedItem; if (item != null) { UpdateViews(item); } await this.ShowMessageAsync(UIMessages.StartOverCompleteTitle, UIMessages.StartOverCompleteMessage); } }