From c7969860ec40e16dbe69b4074309375241780760 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 28 Dec 2025 17:38:59 +0000 Subject: [PATCH] fix: Include packed assets in Package Update when asset packaging is enabled Fixed an issue where the Package Update button was excluding both the packed assets AND the source files when asset packaging was enabled, resulting in no assets being included in the update package. Changes: - Added check for PackageUpdateAssets preference in createUpdate method - Made editorExcludeDirectories conditional based on packaging settings - When packaging is enabled: includes packs directory, excludes source files - When packaging is disabled: excludes packs directory, excludes pack files - Now matches the behavior of Upload to Server functionality This ensures that when asset packaging is enabled, the packaged assets in the resources/packs directory are included in the update, and the source asset files are excluded (to avoid duplication). --- Intersect.Editor/Forms/frmMain.cs | 183 +++++++++++++++++++++--------- 1 file changed, 128 insertions(+), 55 deletions(-) diff --git a/Intersect.Editor/Forms/frmMain.cs b/Intersect.Editor/Forms/frmMain.cs index a6d5ade189..12618b82b9 100644 --- a/Intersect.Editor/Forms/frmMain.cs +++ b/Intersect.Editor/Forms/frmMain.cs @@ -2133,6 +2133,11 @@ private void createUpdate(string sourceDirectory, string targetDirectory, Update targetSubdirectoryInfo.Delete(true); } + // Check if asset packaging is enabled + var packageUpdateAssets = Preferences.LoadPreference("PackageUpdateAssets"); + var packagingEnabled = !string.IsNullOrWhiteSpace(packageUpdateAssets) && + Convert.ToBoolean(packageUpdateAssets, CultureInfo.InvariantCulture); + // Intersect excluded files var editorBaseName = Process.GetCurrentProcess().ProcessName.ToLowerInvariant(); var editorFileNameExe = $"{editorBaseName}.exe"; @@ -2160,10 +2165,7 @@ private void createUpdate(string sourceDirectory, string targetDirectory, Update [ "resources/client_strings.json", ]; - List editorExcludeDirectories = - [ - "resources/packs", - ]; + List editorExcludeDirectories = new(); string[] excludeExtensions = [ ".dll", @@ -2180,81 +2182,152 @@ private void createUpdate(string sourceDirectory, string targetDirectory, Update const string resourcesDirectoryName = "resources"; var pathToResourcesDirectory = Path.Combine(sourceDirectory, resourcesDirectoryName); var pathToPacksDirectory = Path.Combine(pathToResourcesDirectory, "packs"); - if (Directory.Exists(pathToPacksDirectory)) + if (packagingEnabled && Directory.Exists(pathToPacksDirectory)) { + // When packaging is enabled: include packs, exclude source files var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); - editorExcludeFiles.AddRange(packFileNames); + + // Exclude source texture files that were packed clientExcludeFiles.AddRange( - packFileNames.Select( - pack => + packFileNames.SelectMany( + pack => + { + try { var tokenPack = JToken.Parse(GzipCompression.ReadDecompressedString(pack)); - if (tokenPack is not JObject objectPack) + if (tokenPack is not JObject objectPack || !objectPack.TryGetValue("frames", out var tokenFrames)) { - return null; + return Enumerable.Empty(); } - return objectPack.TryGetValue("frames", out var tokenFrames) ? tokenFrames : null; + return tokenFrames.Children() + .OfType() + .Where(frameObject => frameObject.TryGetValue("filename", out _)) + .Select(frameObject => frameObject["filename"]?.Value()) + .Where(filename => !string.IsNullOrWhiteSpace(filename)) + .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/')) + .OfType(); + } + catch + { + return Enumerable.Empty(); } - ) - .SelectMany( - token => token?.Children() ?? [], - (_, frameToken) => - frameToken is JObject frameObject && - frameObject.TryGetValue("filename", out var tokenFilename) - ? tokenFilename.Value() - : null - ) - .Where(filename => !string.IsNullOrWhiteSpace(filename)) - .OfType() + } + ) ); + // Exclude source sound files that were packed var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); if (File.Exists(soundIndex)) { - editorExcludeFiles.Add(soundIndex); - using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); - editorExcludeFiles.AddRange( - soundPacker.CachedPackages.Select( - cachedPackage => Path.Combine(soundPacker.PackageLocation, cachedPackage) - ) - ); - - clientExcludeFiles.AddRange( - soundPacker.FileList.Select( - sound => Path.Combine( - resourcesDirectoryName, - "sounds", - sound.ToLower(CultureInfo.CurrentCulture) - ) - .Replace('\\', '/') - ) - ); + try + { + using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); + clientExcludeFiles.AddRange( + soundPacker.FileList.Select( + sound => Path.Combine(resourcesDirectoryName, "sounds", sound.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') + ) + ); + } + catch + { + // Ignore packer errors + } } + // Exclude source music files that were packed var musicIndex = Path.Combine(pathToPacksDirectory, "music.index"); if (File.Exists(musicIndex)) { - editorExcludeFiles.Add(musicIndex); - using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); + try + { + using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); + clientExcludeFiles.AddRange( + musicPacker.FileList.Select( + music => Path.Combine(resourcesDirectoryName, "music", music.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') + ) + ); + } + catch + { + // Ignore packer errors + } + } + } + else if (!packagingEnabled) + { + // When packaging is disabled: exclude packs directory + editorExcludeDirectories.Add("resources/packs"); + + if (Directory.Exists(pathToPacksDirectory)) + { + var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); + editorExcludeFiles.AddRange(packFileNames.Select(f => Path.GetRelativePath(sourceDirectory, f).Replace('\\', '/'))); + + // Exclude texture source files referenced in pack metadata editorExcludeFiles.AddRange( - musicPacker.CachedPackages.Select( - cachedPackage => Path.Combine(musicPacker.PackageLocation, cachedPackage) - ) + packFileNames.SelectMany(pack => + { + try + { + var tokenPack = JToken.Parse(GzipCompression.ReadDecompressedString(pack)); + if (tokenPack is not JObject objectPack || !objectPack.TryGetValue("frames", out var tokenFrames)) + { + return Enumerable.Empty(); + } + + return tokenFrames.Children() + .OfType() + .Where(frameObject => frameObject.TryGetValue("filename", out _)) + .Select(frameObject => frameObject["filename"]?.Value()) + .Where(filename => !string.IsNullOrWhiteSpace(filename)) + .OfType(); + } + catch + { + return Enumerable.Empty(); + } + }) ); - clientExcludeFiles.AddRange( - musicPacker.FileList.Select( - music => Path.Combine( - resourcesDirectoryName, - "music", - music.ToLower(CultureInfo.CurrentCulture) + var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); + if (File.Exists(soundIndex)) + { + editorExcludeFiles.Add(Path.GetRelativePath(sourceDirectory, soundIndex).Replace('\\', '/')); + try + { + using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); + editorExcludeFiles.AddRange( + soundPacker.CachedPackages.Select( + cachedPackage => Path.Combine("resources/packs", cachedPackage).Replace('\\', '/') ) - .Replace('\\', '/') - ) - ); - } + ); + } + catch + { + // Ignore packer errors + } + } + var musicIndex = Path.Combine(pathToPacksDirectory, "music.index"); + if (File.Exists(musicIndex)) + { + editorExcludeFiles.Add(Path.GetRelativePath(sourceDirectory, musicIndex).Replace('\\', '/')); + try + { + using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); + editorExcludeFiles.AddRange( + musicPacker.CachedPackages.Select( + cachedPackage => Path.Combine("resources/packs", cachedPackage).Replace('\\', '/') + ) + ); + } + catch + { + // Ignore packer errors + } + } + } } var fileCount = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.*", SearchOption.AllDirectories).Length;