From 33c25b263f158b1db69f93785434cc9c5008571d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 28 Dec 2025 18:06:17 +0000 Subject: [PATCH 1/3] fix: Ensure only packed assets are uploaded when asset packaging is enabled This fixes two critical bugs that prevented packed assets from being uploaded correctly: 1. **Case sensitivity bug in Upload to Server**: Texture filenames were not being lowercased when added to the exclusion list, but the comparison logic used lowercase. This caused source texture files to NOT be excluded from uploads even when they should have been. 2. **Missing editor exclusions in Package Update**: When packaging was enabled, source files were only excluded from client updates, not editor updates. This caused editor update packages to include BOTH source files AND packed files instead of just packed files. Changes: - FrmUploadToServer.cs: Added .ToLower() to texture filename exclusions (lines 446, 601) to match the case-insensitive comparison in ShouldExcludeFile() - frmMain.cs: Modified Package Update to exclude source files from BOTH client and editor updates when packaging is enabled, ensuring only packed assets are included in both update types Now when asset packaging is enabled: - Upload to Server will upload ONLY packed assets (resources/packs/*), not source files - Package Update will package ONLY packed assets for both client and editor updates - Source texture/sound/music files will be properly excluded from all uploads/packages --- Intersect.Editor/Forms/FrmUploadToServer.cs | 4 +- Intersect.Editor/Forms/frmMain.cs | 66 ++++++++++----------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Intersect.Editor/Forms/FrmUploadToServer.cs b/Intersect.Editor/Forms/FrmUploadToServer.cs index fed1d09ef3..771ecdf80d 100644 --- a/Intersect.Editor/Forms/FrmUploadToServer.cs +++ b/Intersect.Editor/Forms/FrmUploadToServer.cs @@ -443,7 +443,7 @@ private async void btnUpload_Click(object sender, EventArgs e) .Where(frameObject => frameObject.TryGetValue("filename", out _)) .Select(frameObject => frameObject["filename"]?.Value()) .Where(filename => !string.IsNullOrWhiteSpace(filename)) - .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/')) + .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/').ToLower(CultureInfo.CurrentCulture)) .OfType(); } catch @@ -598,7 +598,7 @@ private async void btnUpload_Click(object sender, EventArgs e) .Where(frameObject => frameObject.TryGetValue("filename", out _)) .Select(frameObject => frameObject["filename"]?.Value()) .Where(filename => !string.IsNullOrWhiteSpace(filename)) - .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/')) + .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/').ToLower(CultureInfo.CurrentCulture)) .OfType(); } catch diff --git a/Intersect.Editor/Forms/frmMain.cs b/Intersect.Editor/Forms/frmMain.cs index 12618b82b9..d41bfff53e 100644 --- a/Intersect.Editor/Forms/frmMain.cs +++ b/Intersect.Editor/Forms/frmMain.cs @@ -2184,37 +2184,37 @@ private void createUpdate(string sourceDirectory, string targetDirectory, Update var pathToPacksDirectory = Path.Combine(pathToResourcesDirectory, "packs"); if (packagingEnabled && Directory.Exists(pathToPacksDirectory)) { - // When packaging is enabled: include packs, exclude source files + // When packaging is enabled: include packs, exclude source files for both client and editor var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); // Exclude source texture files that were packed - clientExcludeFiles.AddRange( - packFileNames.SelectMany( - pack => + var packedTextureFiles = packFileNames.SelectMany( + pack => + { + try { - 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)) - .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/')) - .OfType(); - } - catch + 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)) + .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/').ToLower(CultureInfo.CurrentCulture)) + .OfType(); } - ) - ); + catch + { + return Enumerable.Empty(); + } + } + ).ToList(); + clientExcludeFiles.AddRange(packedTextureFiles); + editorExcludeFiles.AddRange(packedTextureFiles); // Exclude source sound files that were packed var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); @@ -2223,11 +2223,11 @@ private void createUpdate(string sourceDirectory, string targetDirectory, Update try { using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); - clientExcludeFiles.AddRange( - soundPacker.FileList.Select( - sound => Path.Combine(resourcesDirectoryName, "sounds", sound.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') - ) - ); + var packedSoundFiles = soundPacker.FileList.Select( + sound => Path.Combine(resourcesDirectoryName, "sounds", sound.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') + ).ToList(); + clientExcludeFiles.AddRange(packedSoundFiles); + editorExcludeFiles.AddRange(packedSoundFiles); } catch { @@ -2242,11 +2242,11 @@ private void createUpdate(string sourceDirectory, string targetDirectory, Update try { using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); - clientExcludeFiles.AddRange( - musicPacker.FileList.Select( - music => Path.Combine(resourcesDirectoryName, "music", music.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') - ) - ); + var packedMusicFiles = musicPacker.FileList.Select( + music => Path.Combine(resourcesDirectoryName, "music", music.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') + ).ToList(); + clientExcludeFiles.AddRange(packedMusicFiles); + editorExcludeFiles.AddRange(packedMusicFiles); } catch { From c4d9b1b3b2ab54f4ccf41e4a4412c1c10e9afd74 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 28 Dec 2025 18:13:23 +0000 Subject: [PATCH 2/3] fix: Upload both packed assets and source files when asset packaging is enabled When asset packaging is enabled, both the packed assets (resources/packs/) AND the source texture/sound/music files should be uploaded/packaged. Changes: - FrmUploadToServer.cs: Removed logic that excluded source files when packaging is enabled, allowing both packed and source files to be uploaded - frmMain.cs: Removed logic that excluded source files from Package Update when packaging is enabled Now when asset packaging is enabled: - Upload to Server will upload both packed assets and source files - Package Update will package both packed assets and source files for client and editor - When packaging is disabled, the packs directory is excluded (as before) --- Intersect.Editor/Forms/FrmUploadToServer.cs | 72 +------------------- Intersect.Editor/Forms/frmMain.cs | 74 +-------------------- 2 files changed, 2 insertions(+), 144 deletions(-) diff --git a/Intersect.Editor/Forms/FrmUploadToServer.cs b/Intersect.Editor/Forms/FrmUploadToServer.cs index 771ecdf80d..f23bb75fe0 100644 --- a/Intersect.Editor/Forms/FrmUploadToServer.cs +++ b/Intersect.Editor/Forms/FrmUploadToServer.cs @@ -421,77 +421,7 @@ private async void btnUpload_Click(object sender, EventArgs e) var pathToResourcesDirectory = Path.Combine(sourceDirectory, resourcesDirectoryName); var pathToPacksDirectory = Path.Combine(pathToResourcesDirectory, "packs"); - if (packagingEnabled && Directory.Exists(pathToPacksDirectory)) - { - // When packaging is enabled, include the packs directory and exclude source files - var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); - - // Exclude source texture files that were packed - typeSpecificExcludeFiles.AddRange( - 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)) - .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/').ToLower(CultureInfo.CurrentCulture)) - .OfType(); - } - catch - { - return Enumerable.Empty(); - } - }) - ); - - // Exclude source sound files that were packed - var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); - if (File.Exists(soundIndex)) - { - try - { - using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); - typeSpecificExcludeFiles.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)) - { - try - { - using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); - typeSpecificExcludeFiles.AddRange( - musicPacker.FileList.Select( - music => Path.Combine(resourcesDirectoryName, "music", music.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') - ) - ); - } - catch - { - // Ignore packer errors - } - } - } - else if (!packagingEnabled) + if (!packagingEnabled) { // When packaging is disabled, exclude the packs directory entirely typeSpecificExcludeDirectories.Add("resources/packs"); diff --git a/Intersect.Editor/Forms/frmMain.cs b/Intersect.Editor/Forms/frmMain.cs index d41bfff53e..78f7d43099 100644 --- a/Intersect.Editor/Forms/frmMain.cs +++ b/Intersect.Editor/Forms/frmMain.cs @@ -2182,79 +2182,7 @@ 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 (packagingEnabled && Directory.Exists(pathToPacksDirectory)) - { - // When packaging is enabled: include packs, exclude source files for both client and editor - var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); - - // Exclude source texture files that were packed - var packedTextureFiles = 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)) - .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/').ToLower(CultureInfo.CurrentCulture)) - .OfType(); - } - catch - { - return Enumerable.Empty(); - } - } - ).ToList(); - clientExcludeFiles.AddRange(packedTextureFiles); - editorExcludeFiles.AddRange(packedTextureFiles); - - // Exclude source sound files that were packed - var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); - if (File.Exists(soundIndex)) - { - try - { - using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); - var packedSoundFiles = soundPacker.FileList.Select( - sound => Path.Combine(resourcesDirectoryName, "sounds", sound.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') - ).ToList(); - clientExcludeFiles.AddRange(packedSoundFiles); - editorExcludeFiles.AddRange(packedSoundFiles); - } - catch - { - // Ignore packer errors - } - } - - // Exclude source music files that were packed - var musicIndex = Path.Combine(pathToPacksDirectory, "music.index"); - if (File.Exists(musicIndex)) - { - try - { - using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); - var packedMusicFiles = musicPacker.FileList.Select( - music => Path.Combine(resourcesDirectoryName, "music", music.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') - ).ToList(); - clientExcludeFiles.AddRange(packedMusicFiles); - editorExcludeFiles.AddRange(packedMusicFiles); - } - catch - { - // Ignore packer errors - } - } - } - else if (!packagingEnabled) + if (!packagingEnabled) { // When packaging is disabled: exclude packs directory editorExcludeDirectories.Add("resources/packs"); From a60dbb9ffbdcafacb00dc39158087a986733ea72 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 28 Dec 2025 18:20:20 +0000 Subject: [PATCH 3/3] fix: Exclude source texture/sound/music files when asset packaging is enabled When asset packaging is enabled, only the packed assets should be uploaded/packaged, not the source files. This ensures efficient updates by avoiding duplicate data. Fixed two critical bugs: 1. Case sensitivity issue: Texture filenames weren't lowercased when added to exclusion list, preventing proper exclusion (added .ToLower()) 2. Missing editor exclusions: Source files were only excluded from client updates, not editor updates (now excluded from both) Changes: - FrmUploadToServer.cs: When packaging enabled, exclude source texture/sound/music files that have been packed, uploading only the packed assets - frmMain.cs: When packaging enabled, exclude source files from both client AND editor Package Updates Now when asset packaging is enabled: - Upload to Server: uploads only packed assets (resources/packs/*) - Package Update: packages only packed assets for both client and editor - Source files are properly excluded from all uploads/packages When packaging is disabled, packs directory is excluded (as before). --- Intersect.Editor/Forms/FrmUploadToServer.cs | 72 +++++++++++++++++++- Intersect.Editor/Forms/frmMain.cs | 74 ++++++++++++++++++++- 2 files changed, 144 insertions(+), 2 deletions(-) diff --git a/Intersect.Editor/Forms/FrmUploadToServer.cs b/Intersect.Editor/Forms/FrmUploadToServer.cs index f23bb75fe0..771ecdf80d 100644 --- a/Intersect.Editor/Forms/FrmUploadToServer.cs +++ b/Intersect.Editor/Forms/FrmUploadToServer.cs @@ -421,7 +421,77 @@ private async void btnUpload_Click(object sender, EventArgs e) var pathToResourcesDirectory = Path.Combine(sourceDirectory, resourcesDirectoryName); var pathToPacksDirectory = Path.Combine(pathToResourcesDirectory, "packs"); - if (!packagingEnabled) + if (packagingEnabled && Directory.Exists(pathToPacksDirectory)) + { + // When packaging is enabled, include the packs directory and exclude source files + var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); + + // Exclude source texture files that were packed + typeSpecificExcludeFiles.AddRange( + 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)) + .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/').ToLower(CultureInfo.CurrentCulture)) + .OfType(); + } + catch + { + return Enumerable.Empty(); + } + }) + ); + + // Exclude source sound files that were packed + var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); + if (File.Exists(soundIndex)) + { + try + { + using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); + typeSpecificExcludeFiles.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)) + { + try + { + using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); + typeSpecificExcludeFiles.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 the packs directory entirely typeSpecificExcludeDirectories.Add("resources/packs"); diff --git a/Intersect.Editor/Forms/frmMain.cs b/Intersect.Editor/Forms/frmMain.cs index 78f7d43099..d41bfff53e 100644 --- a/Intersect.Editor/Forms/frmMain.cs +++ b/Intersect.Editor/Forms/frmMain.cs @@ -2182,7 +2182,79 @@ 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 (!packagingEnabled) + if (packagingEnabled && Directory.Exists(pathToPacksDirectory)) + { + // When packaging is enabled: include packs, exclude source files for both client and editor + var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); + + // Exclude source texture files that were packed + var packedTextureFiles = 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)) + .Select(filename => Path.Combine(resourcesDirectoryName, filename!).Replace('\\', '/').ToLower(CultureInfo.CurrentCulture)) + .OfType(); + } + catch + { + return Enumerable.Empty(); + } + } + ).ToList(); + clientExcludeFiles.AddRange(packedTextureFiles); + editorExcludeFiles.AddRange(packedTextureFiles); + + // Exclude source sound files that were packed + var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); + if (File.Exists(soundIndex)) + { + try + { + using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); + var packedSoundFiles = soundPacker.FileList.Select( + sound => Path.Combine(resourcesDirectoryName, "sounds", sound.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') + ).ToList(); + clientExcludeFiles.AddRange(packedSoundFiles); + editorExcludeFiles.AddRange(packedSoundFiles); + } + catch + { + // Ignore packer errors + } + } + + // Exclude source music files that were packed + var musicIndex = Path.Combine(pathToPacksDirectory, "music.index"); + if (File.Exists(musicIndex)) + { + try + { + using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); + var packedMusicFiles = musicPacker.FileList.Select( + music => Path.Combine(resourcesDirectoryName, "music", music.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') + ).ToList(); + clientExcludeFiles.AddRange(packedMusicFiles); + editorExcludeFiles.AddRange(packedMusicFiles); + } + catch + { + // Ignore packer errors + } + } + } + else if (!packagingEnabled) { // When packaging is disabled: exclude packs directory editorExcludeDirectories.Add("resources/packs");