private async void AskLoadCompressedBundle(BundleFileInstance bundleInst) { const string fileOption = "File"; const string memoryOption = "Memory"; const string cancelOption = "Cancel"; string result = await MessageBoxUtil.ShowDialogCustom( this, "Note", "This bundle is compressed. Decompress to file or memory?", fileOption, memoryOption, cancelOption); if (result == fileOption) { SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Save as..."; sfd.Filters = new List <FileDialogFilter>() { new FileDialogFilter() { Name = "All files", Extensions = new List <string>() { "*" } } }; string savePath; while (true) { savePath = await sfd.ShowAsync(this); if (savePath == "" || savePath == null) { return; } if (Path.GetFullPath(savePath) == Path.GetFullPath(bundleInst.path)) { await MessageBoxUtil.ShowDialog(this, "File in use", "Since this file is already open in UABEA, you must pick a new file name (sorry!)"); continue; } else { break; } } DecompressToFile(bundleInst, savePath); } else if (result == memoryOption) { DecompressToMemory(bundleInst); } else //if (result == cancelOption || result == closeOption) { return; } LoadBundle(bundleInst); }
private async void MenuCreatePackageFile_Click(object?sender, RoutedEventArgs e) { await MessageBoxUtil.ShowDialog(this, "Not implemented", "Bundle pkgs are not supported at the moment.\n" + "Trying to install an emip file? Try running\n" + "UABEAvalonia applyemip from the command line."); }
private async void BtnOk_Click(object?sender, Avalonia.Interactivity.RoutedEventArgs e) { var fileInsts = new List <AssetsFileInstance>(); var replacerLists = new Dictionary <AssetsFileInstance, List <AssetsReplacer> >(); foreach (LoadModPackageTreeFileInfo fileItem in affectedFiles.Items) { if (fileItem.selected && File.Exists(fileItem.fullPath)) { AssetsFileInstance fileInst = am.LoadAssetsFile(fileItem.fullPath, true); fileInsts.Add(fileInst); if (!replacerLists.ContainsKey(fileInst)) { replacerLists[fileInst] = new List <AssetsReplacer>(); } foreach (AssetsReplacer replacer in fileItem.assetDesc.replacers) { replacerLists[fileInst].Add(replacer); } } } if (fileInsts.Count == 0) { await MessageBoxUtil.ShowDialog(this, "Error", "Did not load any files. Did you select any (double click) or set the correct base path?"); return; } if (!await LoadOrAskTypeData(fileInsts[0])) { Close(false); return; } InfoWindow info = new InfoWindow(am, fileInsts, false); foreach (KeyValuePair <AssetsFileInstance, List <AssetsReplacer> > kvp in replacerLists) { AssetsFileInstance fileInst = kvp.Key; List <AssetsReplacer> replacerList = kvp.Value; foreach (AssetsReplacer replacer in replacerList) { info.Workspace.AddReplacer(fileInst, replacer); } } info.Show(); //temporary hack Hide(); info.Closed += (object?sender, EventArgs e) => { Close(true); }; }
private async void BtnInfo_Click(object?sender, RoutedEventArgs e) { if (bundleInst != null && comboBox.SelectedItem != null) { int index = (int)((ComboBoxItem)comboBox.SelectedItem).Tag; string bunAssetName = bundleInst.file.bundleInf6.dirInf[index].name; //when we make a modification to an assets file in the bundle, //we replace the assets file in the manager. this way, all we //have to do is not reload from the bundle if our assets file //has been modified MemoryStream assetStream; if (!newFiles.ContainsKey(bunAssetName)) { byte[] assetData = BundleHelper.LoadAssetDataFromBundle(bundleInst.file, index); assetStream = new MemoryStream(assetData); } else { //unused if the file already exists assetStream = null; } //warning: does not update if you import an assets file onto //a file that wasn't originally an assets file var fileInf = BundleHelper.GetDirInfo(bundleInst.file, index); bool isAssetsFile = bundleInst.file.IsAssetsFile(bundleInst.file.reader, fileInf); if (isAssetsFile) { string assetMemPath = Path.Combine(bundleInst.path, bunAssetName); AssetsFileInstance fileInst = am.LoadAssetsFile(assetStream, assetMemPath, true); if (!await LoadOrAskTypeData(fileInst)) { return; } if (bundleInst != null && fileInst.parentBundle == null) { fileInst.parentBundle = bundleInst; } InfoWindow info = new InfoWindow(am, new List <AssetsFileInstance> { fileInst }, true); info.Closing += InfoWindow_Closing; info.Show(); } else { await MessageBoxUtil.ShowDialog(this, "Error", "This doesn't seem to be a valid assets file.\n" + "If you want to export a non-assets file,\n" + "use Export."); } } }
private async Task AskForLocationAndCompress() { if (bundleInst != null) { //temporary, maybe I should just write to a memory stream or smth //edit: looks like uabe just asks you to open a file instead of //using your currently opened one, so that may be the workaround if (changesMade) { ButtonResult continueWithChanges = await MessageBoxUtil.ShowDialog( this, "Note", "You've modified this file, but only file before changes is loaded. If you want to compress the file with " + "changes, please close this bundle and open the new file. Click Ok to compress the file without changes.", ButtonEnum.OkCancel); if (continueWithChanges == ButtonResult.Cancel) { return; } } SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Save as..."; string file = await sfd.ShowAsync(this); if (file == null) { return; } const string lz4Option = "LZ4"; const string lzmaOption = "LZMA"; const string cancelOption = "Cancel"; string result = await MessageBoxUtil.ShowDialogCustom( this, "Note", "What compression method do you want to use?\nLZ4: Faster but larger size\nLZMA: Slower but smaller size", lz4Option, lzmaOption, cancelOption); AssetBundleCompressionType compType = result switch { lz4Option => AssetBundleCompressionType.LZ4, lzmaOption => AssetBundleCompressionType.LZMA, _ => AssetBundleCompressionType.NONE }; if (compType != AssetBundleCompressionType.NONE) { CompressBundle(bundleInst, file, compType); } } else { await MessageBoxUtil.ShowDialog(this, "Note", "Please open a bundle file before using compress."); } }
private async Task AskForSave() { if (modified && bundleInst != null) { ButtonResult choice = await MessageBoxUtil.ShowDialog(this, "Changes made", "You've modified this file. Would you like to save?", ButtonEnum.YesNo); if (choice == ButtonResult.Yes) { await AskForSaveLocation(); } } }
private async void MenuClose_Click(object?sender, Avalonia.Interactivity.RoutedEventArgs e) { if (modified) { ButtonResult choice = await MessageBoxUtil.ShowDialog(this, "Changes made", "You've modified this file. Would you like to save?", ButtonEnum.YesNo); if (choice == ButtonResult.Yes) { await SaveFile(); } } CloseFile(); }
private async Task <string?> AskLoadSplitFile(string selectedFile) { ButtonResult splitRes = await MessageBoxUtil.ShowDialog(this, "Split file detected", "This file ends with .split0. Create merged file?\n", ButtonEnum.YesNoCancel); if (splitRes == ButtonResult.Yes) { SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Select location for merged file"; sfd.Directory = Path.GetDirectoryName(selectedFile); sfd.InitialFileName = Path.GetFileName(selectedFile.Substring(0, selectedFile.Length - ".split0".Length)); string splitFilePath = await sfd.ShowAsync(this); if (splitFilePath != null && splitFilePath != string.Empty) { using (FileStream mergeFile = File.OpenWrite(splitFilePath)) { int idx = 0; string thisSplitFileNoNum = selectedFile.Substring(0, selectedFile.Length - 1); string thisSplitFileNum = selectedFile; while (File.Exists(thisSplitFileNum)) { using (FileStream thisSplitFile = File.OpenRead(thisSplitFileNum)) { thisSplitFile.CopyTo(mergeFile); } idx++; thisSplitFileNum = $"{thisSplitFileNoNum}{idx}"; } ; } return(splitFilePath); } else { return(null); } } else if (splitRes == ButtonResult.No) { return(selectedFile); } else //if (splitRes == ButtonResult.Cancel) { return(null); } }
private async void MainWindow_Initialized(object?sender, EventArgs e) { am = new AssetsManager(); if (File.Exists("classdata.tpk")) { am.LoadClassPackage("classdata.tpk"); } else { await MessageBoxUtil.ShowDialog(this, "Error", "Missing classdata.tpk by exe.\nPlease make sure it exists."); Close(); Environment.Exit(1); } }
private async void BtnInfo_Click(object?sender, RoutedEventArgs e) { //when dependency loading is supported: //make sure cab:// dependencies in the bundle are loaded as well if (bundleInst != null && comboBox.SelectedItem != null) { int index = (int)((ComboBoxItem)comboBox.SelectedItem).Tag; string bunAssetName = bundleInst.file.bundleInf6.dirInf[index].name; //when we make a modification to an assets file in the bundle, //we replace the assets file in the manager. this way, all we //have to do is not reload from the bundle if our assets file //has been modified MemoryStream assetStream; if (!newFiles.ContainsKey(bunAssetName)) { byte[] assetData = BundleHelper.LoadAssetDataFromBundle(bundleInst.file, index); assetStream = new MemoryStream(assetData); } else { //unused if the file already exists assetStream = null; } //warning: does not update if you import an assets file onto //a file that wasn't originally an assets file var fileInf = BundleHelper.GetDirInfo(bundleInst.file, index); bool isAssetsFile = bundleInst.file.IsAssetsFile(bundleInst.file.reader, fileInf); if (isAssetsFile) { AssetsFileInstance fileInst = am.LoadAssetsFile(assetStream, bundleInst.path, true); am.LoadClassDatabaseFromPackage(fileInst.file.typeTree.unityVersion); InfoWindow info = new InfoWindow(am, fileInst, bunAssetName, true); info.Closing += InfoWindowClosing; info.Show(); } else { await MessageBoxUtil.ShowDialog(this, "Error", "This doesn't seem to be a valid assets file.\n" + "If you want to export a non-assets file,\n" + "use Export."); } } }
private async void BtnExportDump_Click(object?sender, Avalonia.Interactivity.RoutedEventArgs e) { if (await FailIfNothingSelected()) { return; } SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Save As"; sfd.Filters = new List <FileDialogFilter>() { new FileDialogFilter() { Name = "UABE text dump", Extensions = new List <string>() { "txt" } }, new FileDialogFilter() { Name = "UABE json dump", Extensions = new List <string>() { "json" } } }; string file = await sfd.ShowAsync(this); if (file != null && file != string.Empty) { if (file.EndsWith(".json")) { await MessageBoxUtil.ShowDialog(this, "Not implemented", "There's no json dump support yet, sorry. Exporting as .txt anyway."); file = file.Substring(0, file.Length - 5) + ".txt"; } using (FileStream fs = File.OpenWrite(file)) using (StreamWriter sw = new StreamWriter(fs)) { AssetImportExport dumper = new AssetImportExport(); dumper.DumpTextAsset(sw, GetSelectedField()); } } }
private async void AskLoadCompressedBundle(BundleFileInstance bundleInst) { const string fileOption = "File"; const string memoryOption = "Memory"; const string cancelOption = "Cancel"; string result = await MessageBoxUtil.ShowDialogCustom( this, "Note", "This bundle is compressed. Decompress to file or memory?", fileOption, memoryOption, cancelOption); if (result == fileOption) { SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Save as..."; sfd.Filters = new List <FileDialogFilter>() { new FileDialogFilter() { Name = "All files", Extensions = new List <string>() { "*" } } }; string savePath = await sfd.ShowAsync(this); if (savePath == null) { return; } DecompressToFile(bundleInst, savePath); } else if (result == memoryOption) { DecompressToMemory(bundleInst); } else //if (result == cancelOption || result == closeOption) { return; } LoadBundle(bundleInst); }
private async void ReturnAssetToGoTo() { int fileId = ddFileId.SelectedIndex; //hopefully in order string pathIdText = boxPathId.Text; if (fileId < 0) { await MessageBoxUtil.ShowDialog(this, "Bad input", "File was invalid."); return; } if (!long.TryParse(pathIdText, out long pathId)) { await MessageBoxUtil.ShowDialog(this, "Bad input", "Path ID was invalid."); return; } AssetPPtr pptr = new AssetPPtr(fileId, pathId); Close(pptr); }
private async void ReturnAssetToAdd() { int fileId = ddFileId.SelectedIndex; //hopefully in order string pathIdText = boxPathId.Text; string typeIdText = boxTypeId.Text; string monoIdText = boxMonoId.Text; bool createBlankAsset = chkCreateZerodAsset.IsChecked ?? false; AssetsFileInstance file = workspace.LoadedFiles[fileId]; AssetTypeTemplateField tempField; byte[] assetBytes; long pathId; int typeId; ushort monoId; if (!long.TryParse(pathIdText, out pathId)) { await MessageBoxUtil.ShowDialog(this, "Bad input", "Path ID was invalid."); return; } if (file.file.typeTree.hasTypeTree) { if (!TryParseTypeTree(file, typeIdText, createBlankAsset, out tempField, out typeId)) { if (!TryParseClassDatabase(typeIdText, createBlankAsset, out tempField, out typeId)) { await MessageBoxUtil.ShowDialog(this, "Bad input", "Class type was invalid."); return; } else { //has typetree but had to lookup to cldb //we need to add a new typetree entry because this is //probably not a type that existed in this bundle file.file.typeTree.unity5Types.Add(C2T5.Cldb2TypeTree(workspace.am.classFile, typeId)); } } } else { if (!TryParseClassDatabase(typeIdText, createBlankAsset, out tempField, out typeId)) { await MessageBoxUtil.ShowDialog(this, "Bad input", "Class type was invalid."); return; } } if (monoIdText == "-1") { monoId = 0xffff; } else if (!ushort.TryParse(monoIdText, out monoId)) { await MessageBoxUtil.ShowDialog(this, "Bad input", "Mono ID was invalid."); return; } if (createBlankAsset) { AssetTypeValueField baseField = ValueBuilder.DefaultValueFieldFromTemplate(tempField); assetBytes = baseField.WriteToByteArray(); } else { assetBytes = new byte[0]; } workspace.AddReplacer(file, new AssetsReplacerFromMemory(0, pathId, typeId, monoId, assetBytes), new MemoryStream(assetBytes)); Close(true); }
private async void BtnImportDump_Click(object?sender, Avalonia.Interactivity.RoutedEventArgs e) { if (await FailIfNothingSelected()) { return; } OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "Open"; ofd.Filters = new List <FileDialogFilter>() { new FileDialogFilter() { Name = "UABE text dump", Extensions = new List <string>() { "txt" } }, new FileDialogFilter() { Name = "UABE json dump", Extensions = new List <string>() { "json" } } }; string[] fileList = await ofd.ShowAsync(this); if (fileList.Length == 0) { return; } string file = fileList[0]; if (file != null && file != string.Empty) { if (file.EndsWith(".json")) { await MessageBoxUtil.ShowDialog(this, "Not implemented", "There's no json dump support yet, sorry."); return; } using (FileStream fs = File.OpenRead(file)) using (StreamReader sr = new StreamReader(fs)) { AssetFileInfoEx selectedInfo = GetSelectedInfo(); long selectedId = selectedInfo.index; AssetImportExport importer = new AssetImportExport(); byte[]? bytes = importer.ImportTextAsset(sr); if (bytes == null) { await MessageBoxUtil.ShowDialog(this, "Parse error", "Something went wrong when reading the dump file."); return; } AssetsReplacer replacer = AssetImportExport.CreateAssetReplacer(assetsFile.file, selectedInfo, bytes); newAssets[selectedId] = replacer; newAssetDatas[selectedId] = new MemoryStream(bytes); SetSelectedFieldModified(); modified = true; } } }