private async Task <bool> ImportTextures(Window win, List <ImportBatchInfo> batchInfos) { StringBuilder errorBuilder = new StringBuilder(); foreach (ImportBatchInfo batchInfo in batchInfos) { AssetContainer cont = batchInfo.cont; string errorAssetName = $"{Path.GetFileName(cont.FileInstance.path)}/{cont.PathId}"; string selectedFilePath = batchInfo.importFile; if (!cont.HasInstance) { continue; } AssetTypeValueField baseField = cont.TypeInstance.GetBaseField(); TextureFormat fmt = (TextureFormat)baseField.Get("m_TextureFormat").GetValue().AsInt(); byte[] encImageBytes = TextureImportExport.ImportPng(selectedFilePath, fmt, out int width, out int height); if (encImageBytes == null) { errorBuilder.AppendLine($"[{errorAssetName}]: Failed to encode texture format {fmt}"); continue; } AssetTypeValueField m_StreamData = baseField.Get("m_StreamData"); m_StreamData.Get("offset").GetValue().Set(0); m_StreamData.Get("size").GetValue().Set(0); m_StreamData.Get("path").GetValue().Set(""); baseField.Get("m_TextureFormat").GetValue().Set((int)fmt); baseField.Get("m_Width").GetValue().Set(width); baseField.Get("m_Height").GetValue().Set(height); AssetTypeValueField image_data = baseField.Get("image data"); image_data.GetValue().type = EnumValueTypes.ByteArray; image_data.templateField.valueType = EnumValueTypes.ByteArray; AssetTypeByteArray byteArray = new AssetTypeByteArray() { size = (uint)encImageBytes.Length, data = encImageBytes }; image_data.GetValue().Set(byteArray); } if (errorBuilder.Length > 0) { string[] firstLines = errorBuilder.ToString().Split('\n').Take(20).ToArray(); string firstLinesStr = string.Join('\n', firstLines); await MessageBoxUtil.ShowDialog(win, "Some errors occurred while exporting", firstLinesStr); } return(true); }
public async Task <bool> SingleExport(Window win, AssetWorkspace workspace, List <AssetContainer> selection) { AssetContainer cont = selection[0]; AssetTypeValueField texBaseField = TextureHelper.GetByteArrayTexture(workspace, cont).GetBaseField(); TextureFile texFile = TextureFile.ReadTextureFile(texBaseField); SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Save texture"; sfd.Filters = new List <FileDialogFilter>() { new FileDialogFilter() { Name = "PNG file", Extensions = new List <string>() { "png" } } }; sfd.InitialFileName = $"{texFile.m_Name}-{Path.GetFileName(cont.FileInstance.path)}-{cont.PathId}.png"; string file = await sfd.ShowAsync(win); if (file != null && file != string.Empty) { string errorAssetName = $"{Path.GetFileName(cont.FileInstance.path)}/{cont.PathId}"; //bundle resS if (!GetResSTexture(texFile, cont)) { string resSName = Path.GetFileName(texFile.m_StreamData.path); await MessageBoxUtil.ShowDialog(win, "Error", $"[{errorAssetName}]: resS was detected but {resSName} was not found in bundle"); return(false); } byte[] data = TextureHelper.GetRawTextureBytes(texFile, cont.FileInstance); if (data == null) { string resSName = Path.GetFileName(texFile.m_StreamData.path); await MessageBoxUtil.ShowDialog(win, "Error", $"[{errorAssetName}]: resS was detected but {resSName} was not found on disk"); return(false); } bool success = TextureImportExport.ExportPng(data, file, texFile.m_Width, texFile.m_Height, (TextureFormat)texFile.m_TextureFormat); if (!success) { string texFormat = ((TextureFormat)texFile.m_TextureFormat).ToString(); await MessageBoxUtil.ShowDialog(win, "Error", $"[{errorAssetName}]: Failed to decode texture format {texFormat}"); } return(success); } return(false); }
public async Task <bool> BatchExport(Window win, AssetWorkspace workspace, List <AssetContainer> selection) { for (int i = 0; i < selection.Count; i++) { selection[i] = new AssetContainer(selection[i], TextureHelper.GetByteArrayTexture(workspace, selection[i])); } OpenFolderDialog ofd = new OpenFolderDialog(); ofd.Title = "Select export directory"; string dir = await ofd.ShowAsync(win); if (dir != null && dir != string.Empty) { StringBuilder errorBuilder = new StringBuilder(); foreach (AssetContainer cont in selection) { string errorAssetName = $"{Path.GetFileName(cont.FileInstance.path)}/{cont.PathId}"; AssetTypeValueField texBaseField = cont.TypeInstance.GetBaseField(); TextureFile texFile = TextureFile.ReadTextureFile(texBaseField); //0x0 texture, usually called like Font Texture or smth if (texFile.m_Width == 0 && texFile.m_Height == 0) { continue; } string file = Path.Combine(dir, $"{texFile.m_Name}-{Path.GetFileName(cont.FileInstance.path)}-{cont.PathId}.png"); //bundle resS if (!GetResSTexture(texFile, cont)) { string resSName = Path.GetFileName(texFile.m_StreamData.path); errorBuilder.AppendLine($"[{errorAssetName}]: resS was detected but {resSName} was not found in bundle"); continue; } byte[] data = TextureHelper.GetRawTextureBytes(texFile, cont.FileInstance); if (data == null) { string resSName = Path.GetFileName(texFile.m_StreamData.path); errorBuilder.AppendLine($"[{errorAssetName}]: resS was detected but {resSName} was not found on disk"); continue; } bool success = TextureImportExport.ExportPng(data, file, texFile.m_Width, texFile.m_Height, (TextureFormat)texFile.m_TextureFormat); if (!success) { string texFormat = ((TextureFormat)texFile.m_TextureFormat).ToString(); errorBuilder.AppendLine($"[{errorAssetName}]: Failed to decode texture format {texFormat}"); continue; } } if (errorBuilder.Length > 0) { string[] firstLines = errorBuilder.ToString().Split('\n').Take(20).ToArray(); string firstLinesStr = string.Join('\n', firstLines); await MessageBoxUtil.ShowDialog(win, "Some errors occurred while exporting", firstLinesStr); } return(true); } return(false); }
public async Task <bool> ExecutePlugin(Window win, AssetWorkspace workspace, List <AssetExternal> selection) { AssetExternal tex = selection[0]; AssetTypeValueField texBaseField = GetByteArrayTexture(workspace, tex); TextureFile texFile = TextureFile.ReadTextureFile(texBaseField); SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Save texture"; sfd.Filters = new List <FileDialogFilter>() { new FileDialogFilter() { Name = "PNG file", Extensions = new List <string>() { "png" } } }; string file = await sfd.ShowAsync(win); if (file != null && file != string.Empty) { //bundle resS TextureFile.StreamingInfo streamInfo = texFile.m_StreamData; if (streamInfo.path != null && streamInfo.path != "" && tex.file.parentBundle != null) { //some versions apparently don't use archive:/ string searchPath = streamInfo.path; if (searchPath.StartsWith("archive:/")) { searchPath = searchPath.Substring(9); } searchPath = Path.GetFileName(searchPath); AssetBundleFile bundle = tex.file.parentBundle.file; AssetsFileReader reader = bundle.reader; AssetBundleDirectoryInfo06[] dirInf = bundle.bundleInf6.dirInf; bool foundFile = false; for (int i = 0; i < dirInf.Length; i++) { AssetBundleDirectoryInfo06 info = dirInf[i]; if (info.name == searchPath) { reader.Position = bundle.bundleHeader6.GetFileDataOffset() + info.offset + streamInfo.offset; texFile.pictureData = reader.ReadBytes((int)streamInfo.size); texFile.m_StreamData.offset = 0; texFile.m_StreamData.size = 0; texFile.m_StreamData.path = ""; foundFile = true; break; } } if (!foundFile) { await MessageBoxUtil.ShowDialog(win, "Error", "resS was detected but no file was found in bundle"); return(false); } } byte[] data = GetRawTextureBytes(texFile, tex.file); bool success = await TextureImportExport.ExportPng(data, file, texFile.m_Width, texFile.m_Height, (TextureFormat)texFile.m_TextureFormat); return(success); } return(false); }