From 3f5a53f61d93238045cce159a2bdd9a9ea7fe226 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 28 Dec 2025 17:13:48 +0000 Subject: [PATCH] fix: Upload packaged assets when asset packaging is enabled When the "Package Update Assets" setting is enabled, the system now correctly uploads the packaged assets from resources/packs/ instead of the original unpackaged files. Changes: - Modified BuildExclusionLists to accept packagingEnabled parameter - When packaging is enabled for editor uploads: - Include resources/packs directory in upload - Exclude source texture/sound/music files that were packed - When packaging is disabled for editor uploads: - Maintain original behavior (exclude packs directory) - Updated PerformUpload to pass packaging enabled status This fixes the issue where packaged assets were created but not uploaded to the server. --- Intersect.Editor/Forms/FrmUploadToServer.cs | 102 +++++++++++++++++--- 1 file changed, 91 insertions(+), 11 deletions(-) diff --git a/Intersect.Editor/Forms/FrmUploadToServer.cs b/Intersect.Editor/Forms/FrmUploadToServer.cs index 00b19c84bf..fed1d09ef3 100644 --- a/Intersect.Editor/Forms/FrmUploadToServer.cs +++ b/Intersect.Editor/Forms/FrmUploadToServer.cs @@ -376,7 +376,7 @@ private async void btnUpload_Click(object sender, EventArgs e) } } - private (HashSet excludeFiles, HashSet excludeExtensions, HashSet excludeDirectories, HashSet typeSpecificExcludeFiles, HashSet typeSpecificExcludeDirectories) BuildExclusionLists(string sourceDirectory, bool isEditorUpload) + private (HashSet excludeFiles, HashSet excludeExtensions, HashSet excludeDirectories, HashSet typeSpecificExcludeFiles, HashSet typeSpecificExcludeDirectories) BuildExclusionLists(string sourceDirectory, bool isEditorUpload, bool packagingEnabled) { // Base exclusions that apply to both client and editor var editorBaseName = Process.GetCurrentProcess().ProcessName.ToLowerInvariant(); @@ -415,18 +415,18 @@ private async void btnUpload_Click(object sender, EventArgs e) { // Editor upload - exclude client-specific files typeSpecificExcludeFiles.Add("resources/client_strings.json"); - typeSpecificExcludeDirectories.Add("resources/packs"); // Process packs if they exist 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 the packs directory and exclude source files var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); - typeSpecificExcludeFiles.AddRange(packFileNames.Select(f => Path.GetRelativePath(sourceDirectory, f).Replace('\\', '/'))); + // Exclude source texture files that were packed typeSpecificExcludeFiles.AddRange( packFileNames.SelectMany(pack => { @@ -443,6 +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('\\', '/')) .OfType(); } catch @@ -452,16 +453,16 @@ private async void btnUpload_Click(object sender, EventArgs e) }) ); + // Exclude source sound files that were packed var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); if (File.Exists(soundIndex)) { - typeSpecificExcludeFiles.Add(Path.GetRelativePath(sourceDirectory, soundIndex).Replace('\\', '/')); try { using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); typeSpecificExcludeFiles.AddRange( - soundPacker.CachedPackages.Select( - cachedPackage => Path.Combine("resources/packs", cachedPackage).Replace('\\', '/') + soundPacker.FileList.Select( + sound => Path.Combine(resourcesDirectoryName, "sounds", sound.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') ) ); } @@ -471,16 +472,16 @@ private async void btnUpload_Click(object sender, EventArgs e) } } + // Exclude source music files that were packed var musicIndex = Path.Combine(pathToPacksDirectory, "music.index"); if (File.Exists(musicIndex)) { - typeSpecificExcludeFiles.Add(Path.GetRelativePath(sourceDirectory, musicIndex).Replace('\\', '/')); try { using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); typeSpecificExcludeFiles.AddRange( - musicPacker.CachedPackages.Select( - cachedPackage => Path.Combine("resources/packs", cachedPackage).Replace('\\', '/') + musicPacker.FileList.Select( + music => Path.Combine(resourcesDirectoryName, "music", music.ToLower(CultureInfo.CurrentCulture)).Replace('\\', '/') ) ); } @@ -490,6 +491,80 @@ private async void btnUpload_Click(object sender, EventArgs e) } } } + else if (!packagingEnabled) + { + // When packaging is disabled, exclude the packs directory entirely + typeSpecificExcludeDirectories.Add("resources/packs"); + + if (Directory.Exists(pathToPacksDirectory)) + { + var packFileNames = Directory.GetFiles(pathToPacksDirectory, "*.meta"); + typeSpecificExcludeFiles.AddRange(packFileNames.Select(f => Path.GetRelativePath(sourceDirectory, f).Replace('\\', '/'))); + + 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)) + .OfType(); + } + catch + { + return Enumerable.Empty(); + } + }) + ); + + var soundIndex = Path.Combine(pathToPacksDirectory, "sound.index"); + if (File.Exists(soundIndex)) + { + typeSpecificExcludeFiles.Add(Path.GetRelativePath(sourceDirectory, soundIndex).Replace('\\', '/')); + try + { + using AssetPacker soundPacker = new(soundIndex, pathToPacksDirectory); + typeSpecificExcludeFiles.AddRange( + soundPacker.CachedPackages.Select( + cachedPackage => Path.Combine("resources/packs", cachedPackage).Replace('\\', '/') + ) + ); + } + catch + { + // Ignore packer errors + } + } + + var musicIndex = Path.Combine(pathToPacksDirectory, "music.index"); + if (File.Exists(musicIndex)) + { + typeSpecificExcludeFiles.Add(Path.GetRelativePath(sourceDirectory, musicIndex).Replace('\\', '/')); + try + { + using AssetPacker musicPacker = new(musicIndex, pathToPacksDirectory); + typeSpecificExcludeFiles.AddRange( + musicPacker.CachedPackages.Select( + cachedPackage => Path.Combine("resources/packs", cachedPackage).Replace('\\', '/') + ) + ); + } + catch + { + // Ignore packer errors + } + } + } + } } else { @@ -626,9 +701,14 @@ private async Task PerformUpload() var serverUrl = txtServerUrl.Text.TrimEnd('/'); var endpoint = $"{serverUrl}/api/v1/editor/updates/{uploadType}"; + // Check if packaging is enabled + var packageUpdateAssets = Preferences.LoadPreference("PackageUpdateAssets"); + var packagingEnabled = !string.IsNullOrWhiteSpace(packageUpdateAssets) && + Convert.ToBoolean(packageUpdateAssets, CultureInfo.InvariantCulture); + // Build exclusion lists var (excludeFiles, excludeExtensions, excludeDirectories, typeSpecificExcludeFiles, typeSpecificExcludeDirectories) = - BuildExclusionLists(_selectedDirectory!, isEditorUpload); + BuildExclusionLists(_selectedDirectory!, isEditorUpload, packagingEnabled); // Get all files and filter them var allFiles = Directory.GetFiles(