diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT.bytes index 89250dab9..e914f83b1 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/Assembly-CSharp.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/Assembly-CSharp.dll.bytes index 7561714f8..8a95cf056 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/Assembly-CSharp.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/Assembly-CSharp.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/HybridCLR.Runtime.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/HybridCLR.Runtime.dll.bytes index 15f2cffd1..bce482448 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/HybridCLR.Runtime.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/HybridCLR.Runtime.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/IngameDebugConsole.Runtime.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/IngameDebugConsole.Runtime.dll.bytes index b0c0b5783..2b9f096ed 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/IngameDebugConsole.Runtime.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/IngameDebugConsole.Runtime.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/JEngine.Core.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/JEngine.Core.dll.bytes index 20b4217f1..cde1efd9c 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/JEngine.Core.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/JEngine.Core.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/JEngine.UI.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/JEngine.UI.dll.bytes index 40b39cc00..246610820 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/JEngine.UI.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/JEngine.UI.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/Nino.Core.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/Nino.Core.dll.bytes index 7e95f4d0c..5d8899c51 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/Nino.Core.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/Nino.Core.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/Obfuz.Generated.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/Obfuz.Generated.dll.bytes index 77b856d60..1f06a51f9 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/Obfuz.Generated.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/Obfuz.Generated.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/Obfuz.Runtime.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/Obfuz.Runtime.dll.bytes index 16ff9c86e..e2c31c83c 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/Obfuz.Runtime.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/Obfuz.Runtime.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/UniTask.YooAsset.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/UniTask.YooAsset.dll.bytes index 925274f86..340591f99 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/UniTask.YooAsset.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/UniTask.YooAsset.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/UniTask.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/UniTask.dll.bytes index f25f83010..c771e3685 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/UniTask.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/UniTask.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/Unity.TextMeshPro.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/Unity.TextMeshPro.dll.bytes index 630292fc1..d4c9829f4 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/Unity.TextMeshPro.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/Unity.TextMeshPro.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/UnityEngine.UI.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/UnityEngine.UI.dll.bytes index df63abbc3..b91eb26df 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/UnityEngine.UI.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/UnityEngine.UI.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.MiniGame.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.MiniGame.dll.bytes index 54b58054f..dd3a4a4da 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.MiniGame.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.MiniGame.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.RuntimeExtension.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.RuntimeExtension.dll.bytes index 2ad3cc9e4..298c41598 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.RuntimeExtension.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.RuntimeExtension.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.dll.bytes index 0f9b656a4..bc093ee46 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/AOT/YooAsset.dll.bytes differ diff --git a/UnityProject/Assets/HotUpdate/Compiled/HotUpdate.Code.dll.bytes b/UnityProject/Assets/HotUpdate/Compiled/HotUpdate.Code.dll.bytes index 9c830aef3..4214b3a86 100644 Binary files a/UnityProject/Assets/HotUpdate/Compiled/HotUpdate.Code.dll.bytes and b/UnityProject/Assets/HotUpdate/Compiled/HotUpdate.Code.dll.bytes differ diff --git a/UnityProject/Assets/Init.unity b/UnityProject/Assets/Init.unity index 6311e2cb5..06c9920f5 100644 --- a/UnityProject/Assets/Init.unity +++ b/UnityProject/Assets/Init.unity @@ -858,6 +858,40 @@ MonoBehaviour: downloadProgressText: {fileID: 1384766990} downloadProgressBar: {fileID: 1847636611} startButton: {fileID: 1079429684} + text: + initializingPackage: Initializing resource package... + gettingVersion: Getting resource package version... + updatingManifest: Updating resource manifest... + checkingUpdate: Checking resources to download... + downloadingResources: Downloading resources... + packageCompleted: Resource package initialization completed + initializationFailed: Initialization failed + unknownPackageStatus: Unknown status + sceneLoading: Loading scene... + sceneCompleted: Scene loading completed + sceneFailed: Scene loading failed + unknownSceneStatus: Unknown status + initializing: Initializing... + downloading: Downloading... + downloadCompletedLoading: Download completed, loading... + loadingCode: Loading code... + decryptingResources: Decrypting resources... + loadingScene: Loading scene... + dialogTitleError: Error + dialogTitleWarning: Warning + dialogTitleNotice: Notice + buttonOk: OK + buttonCancel: Cancel + buttonDownload: Download + buttonRetry: Retry + buttonExit: Exit + dialogInitFailed: 'Initialization failed: {0}' + dialogDownloadPrompt: Need to download {0} files, total size {1}MB. Start download? + dialogDownloadProgress: Downloading file {0}/{1} ({2}MB/{3}MB) + dialogSceneLoadFailed: 'Scene loading failed: {0}' + dialogInitException: 'Exception occurred during initialization: {0}' + dialogCodeException: Code exception, please contact customer service + dialogFunctionCallFailed: 'Function call failed: {0}' useEditorDevMode: 0 --- !u!1 &1033013693 GameObject: diff --git a/UnityProject/Assets/Obfuz/SymbolObfus/symbol-mapping.xml b/UnityProject/Assets/Obfuz/SymbolObfus/symbol-mapping.xml index 452886b4e..b96951aed 100644 --- a/UnityProject/Assets/Obfuz/SymbolObfus/symbol-mapping.xml +++ b/UnityProject/Assets/Obfuz/SymbolObfus/symbol-mapping.xml @@ -302,18 +302,18 @@ - + - - - + + + - - - + + + - + @@ -418,6 +418,8 @@ + + @@ -514,6 +516,7 @@ + @@ -589,7 +592,7 @@ - + diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/3050e56ae07e86927996878bb1a5e4ce.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/3050e56ae07e86927996878bb1a5e4ce.bundle new file mode 100644 index 000000000..8acd14b22 Binary files /dev/null and b/UnityProject/Assets/StreamingAssets/yoo/main/3050e56ae07e86927996878bb1a5e4ce.bundle differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/ec451612fae802d07094821d3808809f.bundle.meta b/UnityProject/Assets/StreamingAssets/yoo/main/3050e56ae07e86927996878bb1a5e4ce.bundle.meta similarity index 74% rename from UnityProject/Assets/StreamingAssets/yoo/main/ec451612fae802d07094821d3808809f.bundle.meta rename to UnityProject/Assets/StreamingAssets/yoo/main/3050e56ae07e86927996878bb1a5e4ce.bundle.meta index 53fd0a836..50ad5a679 100644 --- a/UnityProject/Assets/StreamingAssets/yoo/main/ec451612fae802d07094821d3808809f.bundle.meta +++ b/UnityProject/Assets/StreamingAssets/yoo/main/3050e56ae07e86927996878bb1a5e4ce.bundle.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d36862f8c80594046b66470b69bc88ae +guid: 5caad75796c4d4834adefe2344359c2c DefaultImporter: externalObjects: {} userData: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/3fbfdf48f0b37821c942c9be8002d286.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/3fbfdf48f0b37821c942c9be8002d286.bundle new file mode 100644 index 000000000..c8e22e1de Binary files /dev/null and b/UnityProject/Assets/StreamingAssets/yoo/main/3fbfdf48f0b37821c942c9be8002d286.bundle differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/4abd3c5f4f01b40f54c4a348b24ead49.bundle.meta b/UnityProject/Assets/StreamingAssets/yoo/main/3fbfdf48f0b37821c942c9be8002d286.bundle.meta similarity index 74% rename from UnityProject/Assets/StreamingAssets/yoo/main/4abd3c5f4f01b40f54c4a348b24ead49.bundle.meta rename to UnityProject/Assets/StreamingAssets/yoo/main/3fbfdf48f0b37821c942c9be8002d286.bundle.meta index cd7e49741..37ac4e6ec 100644 --- a/UnityProject/Assets/StreamingAssets/yoo/main/4abd3c5f4f01b40f54c4a348b24ead49.bundle.meta +++ b/UnityProject/Assets/StreamingAssets/yoo/main/3fbfdf48f0b37821c942c9be8002d286.bundle.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 921643076c5e940629df9ff840da556d +guid: f4976efb134c44468a274eaf7aadb888 DefaultImporter: externalObjects: {} userData: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/463a37fa048a6a552f76991c14fae884.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/463a37fa048a6a552f76991c14fae884.bundle new file mode 100644 index 000000000..374f3c3e5 Binary files /dev/null and b/UnityProject/Assets/StreamingAssets/yoo/main/463a37fa048a6a552f76991c14fae884.bundle differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.bytes.meta b/UnityProject/Assets/StreamingAssets/yoo/main/463a37fa048a6a552f76991c14fae884.bundle.meta similarity index 74% rename from UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.bytes.meta rename to UnityProject/Assets/StreamingAssets/yoo/main/463a37fa048a6a552f76991c14fae884.bundle.meta index c2fc90301..9a7b135e9 100644 --- a/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.bytes.meta +++ b/UnityProject/Assets/StreamingAssets/yoo/main/463a37fa048a6a552f76991c14fae884.bundle.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2f4124e6754aa47e696d655d5e28dd78 +guid: ff8b503f3fee84d389f55b13a42144cd DefaultImporter: externalObjects: {} userData: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/4abd3c5f4f01b40f54c4a348b24ead49.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/4abd3c5f4f01b40f54c4a348b24ead49.bundle deleted file mode 100644 index df66425e7..000000000 Binary files a/UnityProject/Assets/StreamingAssets/yoo/main/4abd3c5f4f01b40f54c4a348b24ead49.bundle and /dev/null differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/4cec6d96ce074cd2e4a452dd8f93a44f.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/4cec6d96ce074cd2e4a452dd8f93a44f.bundle new file mode 100644 index 000000000..0c663fa9d Binary files /dev/null and b/UnityProject/Assets/StreamingAssets/yoo/main/4cec6d96ce074cd2e4a452dd8f93a44f.bundle differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/a08587b61b8accf9b169ccdf828176f6.bundle.meta b/UnityProject/Assets/StreamingAssets/yoo/main/4cec6d96ce074cd2e4a452dd8f93a44f.bundle.meta similarity index 74% rename from UnityProject/Assets/StreamingAssets/yoo/main/a08587b61b8accf9b169ccdf828176f6.bundle.meta rename to UnityProject/Assets/StreamingAssets/yoo/main/4cec6d96ce074cd2e4a452dd8f93a44f.bundle.meta index 8b27aa7d6..ab9fb23f8 100644 --- a/UnityProject/Assets/StreamingAssets/yoo/main/a08587b61b8accf9b169ccdf828176f6.bundle.meta +++ b/UnityProject/Assets/StreamingAssets/yoo/main/4cec6d96ce074cd2e4a452dd8f93a44f.bundle.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: bb82bd11c6eb54d0cbe0c30fef98a7d4 +guid: 97c6fa700146d480bb1f068348b2725f DefaultImporter: externalObjects: {} userData: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/8c8afa4493431415b8e6e4b9aa9e7616.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/8c8afa4493431415b8e6e4b9aa9e7616.bundle new file mode 100644 index 000000000..783275174 Binary files /dev/null and b/UnityProject/Assets/StreamingAssets/yoo/main/8c8afa4493431415b8e6e4b9aa9e7616.bundle differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/8c8afa4493431415b8e6e4b9aa9e7616.bundle.meta b/UnityProject/Assets/StreamingAssets/yoo/main/8c8afa4493431415b8e6e4b9aa9e7616.bundle.meta new file mode 100644 index 000000000..47d07b642 --- /dev/null +++ b/UnityProject/Assets/StreamingAssets/yoo/main/8c8afa4493431415b8e6e4b9aa9e7616.bundle.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0fd9469001b13414e8fa7fcb20b95c5f +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/BuildinCatalog.bytes b/UnityProject/Assets/StreamingAssets/yoo/main/BuildinCatalog.bytes index a76e75272..025c6762a 100644 Binary files a/UnityProject/Assets/StreamingAssets/yoo/main/BuildinCatalog.bytes and b/UnityProject/Assets/StreamingAssets/yoo/main/BuildinCatalog.bytes differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/BuildinCatalog.json b/UnityProject/Assets/StreamingAssets/yoo/main/BuildinCatalog.json index bd82f2921..f53fc26cd 100644 --- a/UnityProject/Assets/StreamingAssets/yoo/main/BuildinCatalog.json +++ b/UnityProject/Assets/StreamingAssets/yoo/main/BuildinCatalog.json @@ -1,7 +1,7 @@ { "FileVersion": "1.0.0", "PackageName": "main", - "PackageVersion": "260208479", + "PackageVersion": "260424255", "Wrappers": [ { "BundleGUID": "1832d193ad604c285e2456ba2a7855c7", @@ -11,13 +11,25 @@ "BundleGUID": "20c6686ce660502e16a881f74dde76d7", "FileName": "20c6686ce660502e16a881f74dde76d7.bundle" }, + { + "BundleGUID": "3050e56ae07e86927996878bb1a5e4ce", + "FileName": "3050e56ae07e86927996878bb1a5e4ce.bundle" + }, + { + "BundleGUID": "3fbfdf48f0b37821c942c9be8002d286", + "FileName": "3fbfdf48f0b37821c942c9be8002d286.bundle" + }, + { + "BundleGUID": "463a37fa048a6a552f76991c14fae884", + "FileName": "463a37fa048a6a552f76991c14fae884.bundle" + }, { "BundleGUID": "490ed19cf4dd5e128fb13cf883211456", "FileName": "490ed19cf4dd5e128fb13cf883211456.bundle" }, { - "BundleGUID": "4abd3c5f4f01b40f54c4a348b24ead49", - "FileName": "4abd3c5f4f01b40f54c4a348b24ead49.bundle" + "BundleGUID": "4cec6d96ce074cd2e4a452dd8f93a44f", + "FileName": "4cec6d96ce074cd2e4a452dd8f93a44f.bundle" }, { "BundleGUID": "56d90d09aba519ecd1cba11dfc31f5d8", @@ -28,8 +40,8 @@ "FileName": "85bf7a8000e78a0640dd575c462d71de.bundle" }, { - "BundleGUID": "a08587b61b8accf9b169ccdf828176f6", - "FileName": "a08587b61b8accf9b169ccdf828176f6.bundle" + "BundleGUID": "8c8afa4493431415b8e6e4b9aa9e7616", + "FileName": "8c8afa4493431415b8e6e4b9aa9e7616.bundle" }, { "BundleGUID": "ae16386504461146b4ec88eabc7de89f", @@ -43,6 +55,10 @@ "BundleGUID": "c9cd151a5606eec7bf47ac8d9401fb94", "FileName": "c9cd151a5606eec7bf47ac8d9401fb94.bundle" }, + { + "BundleGUID": "c9f5f10f27a7b78065e5943aa413b8e0", + "FileName": "c9f5f10f27a7b78065e5943aa413b8e0.bundle" + }, { "BundleGUID": "cde787d0afee29507a54189b7372cf14", "FileName": "cde787d0afee29507a54189b7372cf14.bundle" @@ -52,8 +68,8 @@ "FileName": "dcb1b5ed74667265ec98799a1576d5d3.bundle" }, { - "BundleGUID": "ec451612fae802d07094821d3808809f", - "FileName": "ec451612fae802d07094821d3808809f.bundle" + "BundleGUID": "f568ec9e573cad91faed8ed55942d5c1", + "FileName": "f568ec9e573cad91faed8ed55942d5c1.bundle" } ] } \ No newline at end of file diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/a08587b61b8accf9b169ccdf828176f6.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/a08587b61b8accf9b169ccdf828176f6.bundle deleted file mode 100644 index 053e4cbb8..000000000 Binary files a/UnityProject/Assets/StreamingAssets/yoo/main/a08587b61b8accf9b169ccdf828176f6.bundle and /dev/null differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/c9f5f10f27a7b78065e5943aa413b8e0.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/c9f5f10f27a7b78065e5943aa413b8e0.bundle new file mode 100644 index 000000000..5c237f22b Binary files /dev/null and b/UnityProject/Assets/StreamingAssets/yoo/main/c9f5f10f27a7b78065e5943aa413b8e0.bundle differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/c9f5f10f27a7b78065e5943aa413b8e0.bundle.meta b/UnityProject/Assets/StreamingAssets/yoo/main/c9f5f10f27a7b78065e5943aa413b8e0.bundle.meta new file mode 100644 index 000000000..ca56218f0 --- /dev/null +++ b/UnityProject/Assets/StreamingAssets/yoo/main/c9f5f10f27a7b78065e5943aa413b8e0.bundle.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0da0a1b9e8c5c4b30b921f1e09f5d301 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/ec451612fae802d07094821d3808809f.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/ec451612fae802d07094821d3808809f.bundle deleted file mode 100644 index d1eece83b..000000000 Binary files a/UnityProject/Assets/StreamingAssets/yoo/main/ec451612fae802d07094821d3808809f.bundle and /dev/null differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/f568ec9e573cad91faed8ed55942d5c1.bundle b/UnityProject/Assets/StreamingAssets/yoo/main/f568ec9e573cad91faed8ed55942d5c1.bundle new file mode 100644 index 000000000..19e8bfedd Binary files /dev/null and b/UnityProject/Assets/StreamingAssets/yoo/main/f568ec9e573cad91faed8ed55942d5c1.bundle differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/f568ec9e573cad91faed8ed55942d5c1.bundle.meta b/UnityProject/Assets/StreamingAssets/yoo/main/f568ec9e573cad91faed8ed55942d5c1.bundle.meta new file mode 100644 index 000000000..3f3e54f80 --- /dev/null +++ b/UnityProject/Assets/StreamingAssets/yoo/main/f568ec9e573cad91faed8ed55942d5c1.bundle.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: afc2c1fda74ae41bda27d10679f39689 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main.version b/UnityProject/Assets/StreamingAssets/yoo/main/main.version index f960c074f..bf0509867 100644 --- a/UnityProject/Assets/StreamingAssets/yoo/main/main.version +++ b/UnityProject/Assets/StreamingAssets/yoo/main/main.version @@ -1 +1 @@ -260208479 \ No newline at end of file +260424255 \ No newline at end of file diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.bytes b/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.bytes deleted file mode 100644 index 913ef75d7..000000000 Binary files a/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.bytes and /dev/null differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.hash b/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.hash deleted file mode 100644 index 1bc5d2d89..000000000 --- a/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.hash +++ /dev/null @@ -1 +0,0 @@ -120fa27e \ No newline at end of file diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.hash.meta b/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.hash.meta deleted file mode 100644 index b68807bb1..000000000 --- a/UnityProject/Assets/StreamingAssets/yoo/main/main_260208479.hash.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 30cc906e1c1894181ad12bc06845c3d2 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.bytes b/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.bytes new file mode 100644 index 000000000..963d37dd8 Binary files /dev/null and b/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.bytes differ diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.bytes.meta b/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.bytes.meta new file mode 100644 index 000000000..ee460d1ae --- /dev/null +++ b/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.bytes.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6fd9282f1cf3144fe9f83f9fce394a52 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.hash b/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.hash new file mode 100644 index 000000000..a6614b221 --- /dev/null +++ b/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.hash @@ -0,0 +1 @@ +c317c44d \ No newline at end of file diff --git a/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.hash.meta b/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.hash.meta new file mode 100644 index 000000000..bf585d9ba --- /dev/null +++ b/UnityProject/Assets/StreamingAssets/yoo/main/main_260424255.hash.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 57ccac8f3f8714b6aabcd9206185886a +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/BuildManager.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/BuildManager.cs index 1c442ba9d..019bc08d7 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/BuildManager.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/BuildManager.cs @@ -406,6 +406,7 @@ private ScriptableBuildParameters CreateBuildParameters(int packageVersion) BuildTarget = _settings.buildTarget, PackageName = _settings.packageName, PackageVersion = packageVersion.ToString(), + EnableSharePackRule = true, VerifyBuildingResult = true, FileNameStyle = EFileNameStyle.HashName, BuildinFileCopyOption = copyOption, diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/Panel.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/Panel.cs index 0170619d6..8cec0a13d 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/Panel.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/Panel.cs @@ -73,6 +73,20 @@ private void CreateGUI() CreateDefaultGUI(); } + /// + /// Rebuilds the panel when it regains focus so dropdown choices (e.g. YooAsset + /// packages, hot scenes) reflect changes made in other editor windows. Skipped mid-build + /// to avoid losing state or the log view contents. + /// + private void OnFocus() + { + if (_root == null) return; + if (_buildManager != null && _buildManager.IsBuilding) return; + + _root.Clear(); + CreateGUI(); + } + private void CreateDefaultGUI() { // Load stylesheets - Panel first, then Common to override diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/SettingsUIBuilder.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/SettingsUIBuilder.cs index c6424506b..1f90c577e 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/SettingsUIBuilder.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/CustomEditor/SettingsUIBuilder.cs @@ -46,18 +46,19 @@ public static VisualElement CreatePackageSettingsGroup(Settings settings) // Package Name field (dropdown or text field based on useDropdown) var packageNameRow = EditorUIUtils.CreateFormRow("Package"); - // Use PopupField for Panel (with available packages) - var packageChoices = EditorUtils.GetAvailableYooAssetPackages(); + // Prepend a "None" sentinel so renamed/missing packages surface as "None" instead of + // silently desyncing with the serialized value. + var packageOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableYooAssetPackages()); var packageNameField = new PopupField() { - choices = packageChoices.Count > 0 ? packageChoices : new List { settings.packageName }, - value = settings.packageName + choices = packageOptions, + value = EditorUtils.ResolveDropdownValue(settings.packageName, packageOptions) }; packageNameField.AddToClassList("form-control"); EditorUIUtils.MakeTextResponsive(packageNameField); packageNameField.RegisterValueChangedCallback(evt => { - settings.packageName = evt.newValue; + settings.packageName = EditorUtils.NormalizeDropdownSelection(evt.newValue); settings.Save(); }); packageNameRow.Add(packageNameField); diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/EditorUtils.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/EditorUtils.cs index 3346425a4..b26465c6f 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/EditorUtils.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Editor/EditorUtils.cs @@ -36,6 +36,45 @@ namespace JEngine.Core.Editor { public static class EditorUtils { + /// + /// Sentinel shown in dropdowns when the stored value is missing or no longer in the + /// available choices (e.g. a YooAsset package was renamed). Guarantees >=2 entries and + /// gives the user an explicit "clear" option. + /// + public const string NoneDropdownOption = "None"; + + /// + /// Returns a new list with prepended to the given + /// choices. Safe to call with a null choices list. + /// + public static List WithNoneOption(IList choices) + { + var options = new List { NoneDropdownOption }; + if (choices != null) options.AddRange(choices); + return options; + } + + /// + /// Returns the value that should be displayed in a dropdown. Falls back to + /// when the stored value is empty or no longer present + /// in the current options. + /// + public static string ResolveDropdownValue(string storedValue, List options) + { + return string.IsNullOrEmpty(storedValue) || options == null || !options.Contains(storedValue) + ? NoneDropdownOption + : storedValue; + } + + /// + /// Converts a dropdown selection into the value to persist. The sentinel + /// is mapped to an empty string. + /// + public static string NormalizeDropdownSelection(string value) + { + return value == NoneDropdownOption ? string.Empty : value; + } + public static List GetAvailableYooAssetPackages() { var packages = new List(); diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/AesBundle.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/AesBundle.cs index e2660d567..87b19f603 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/AesBundle.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/AesBundle.cs @@ -43,6 +43,9 @@ public class AesEncryptionServices : IEncryptionServices { private readonly AesConfig _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public AesEncryptionServices() : this(AesConfig.Instance) { } + public AesEncryptionServices(AesConfig config) { _config = config; diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/ChaCha20Bundle.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/ChaCha20Bundle.cs index 08ab80667..067bed0ef 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/ChaCha20Bundle.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/ChaCha20Bundle.cs @@ -43,6 +43,9 @@ public class ChaCha20EncryptionServices : IEncryptionServices { private readonly ChaCha20Config _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public ChaCha20EncryptionServices() : this(ChaCha20Config.Instance) { } + public ChaCha20EncryptionServices(ChaCha20Config config) { _config = config; diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/XorBundle.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/XorBundle.cs index 42d05d679..d7b7fa94b 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/XorBundle.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Bundle/XorBundle.cs @@ -43,6 +43,9 @@ public class XorEncryptionServices : IEncryptionServices { private readonly XorConfig _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public XorEncryptionServices() : this(XorConfig.Instance) { } + public XorEncryptionServices(XorConfig config) { _config = config; diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/AesManifest.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/AesManifest.cs index db77e9ab8..fb6981792 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/AesManifest.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/AesManifest.cs @@ -40,6 +40,9 @@ public class AesManifestProcess : IManifestProcessServices { private readonly AesConfig _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public AesManifestProcess() : this(AesConfig.Instance) { } + public AesManifestProcess(AesConfig config) { _config = config; @@ -60,6 +63,9 @@ public class AesManifestRestore : IManifestRestoreServices { private readonly AesConfig _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public AesManifestRestore() : this(AesConfig.Instance) { } + public AesManifestRestore(AesConfig config) { _config = config; diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/ChaCha20Manifest.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/ChaCha20Manifest.cs index 0166cb7f9..737ab4935 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/ChaCha20Manifest.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/ChaCha20Manifest.cs @@ -40,6 +40,9 @@ public class ChaCha20ManifestProcess : IManifestProcessServices { private readonly ChaCha20Config _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public ChaCha20ManifestProcess() : this(ChaCha20Config.Instance) { } + public ChaCha20ManifestProcess(ChaCha20Config config) { _config = config; @@ -60,6 +63,9 @@ public class ChaCha20ManifestRestore : IManifestRestoreServices { private readonly ChaCha20Config _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public ChaCha20ManifestRestore() : this(ChaCha20Config.Instance) { } + public ChaCha20ManifestRestore(ChaCha20Config config) { _config = config; diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/XorManifest.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/XorManifest.cs index 55d7092ee..b989f1397 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/XorManifest.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Encrypt/Manifest/XorManifest.cs @@ -40,6 +40,9 @@ public class XorManifestProcess : IManifestProcessServices { private readonly XorConfig _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public XorManifestProcess() : this(XorConfig.Instance) { } + public XorManifestProcess(XorConfig config) { _config = config; @@ -66,6 +69,9 @@ public class XorManifestRestore : IManifestRestoreServices { private readonly XorConfig _config; + // Required by YooAsset's AssetBundleBuilder (Activator.CreateInstance with no args). + public XorManifestRestore() : this(XorConfig.Instance) { } + public XorManifestRestore(XorConfig config) { _config = config; diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Editor/Internal/BootstrapEditorUI.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Editor/Internal/BootstrapEditorUI.cs index fc08e5b0c..170c6f103 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Editor/Internal/BootstrapEditorUI.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Editor/Internal/BootstrapEditorUI.cs @@ -54,6 +54,10 @@ internal static class BootstrapEditorUI private static VisualElement _fallbackContainer; private static VisualElement _currentRoot; + // Signature of the last-seen external data (available packages / scenes / etc.) so the + // inspector can detect renames and additions made in other windows and rebuild. + private static string _lastExternalDataSignature; + /// /// Creates the enhanced Bootstrap inspector. /// @@ -62,8 +66,9 @@ public static VisualElement CreateInspector(SerializedObject serializedObject, B _serializedObject = serializedObject; _bootstrap = bootstrap; - // Unregister previous undo callback if exists + // Unregister previous callbacks if they exist (inspector may be recreated). Undo.undoRedoPerformed -= OnUndoRedo; + EditorApplication.focusChanged -= OnEditorFocusChanged; var root = new VisualElement(); _currentRoot = root; @@ -77,87 +82,106 @@ public static VisualElement CreateInspector(SerializedObject serializedObject, B root.style.paddingRight = Tokens.Spacing.MD; root.style.paddingBottom = Tokens.Spacing.MD; - // Centered container for compact inspector layout - var container = new JContainer(ContainerSize.Xs); + BuildContent(root); + + // Rebuild on undo/redo and on editor focus regained (picks up renames made in + // other windows like the AssetBundle Collector). + Undo.undoRedoPerformed += OnUndoRedo; + EditorApplication.focusChanged += OnEditorFocusChanged; + // Seed the signature and poll periodically so renames made in another Unity window + // (not just another app) propagate without the user having to reselect the asset. + _lastExternalDataSignature = ComputeExternalDataSignature(); + root.schedule.Execute(CheckForExternalDataChanges).Every(500); + + // Cleanup callback when element is detached. + root.RegisterCallback(OnDetachFromPanel); + + return root; + } + + /// + /// Builds the inspector content into the given root. Used by both initial create and + /// subsequent rebuilds (undo/redo, focus refresh). + /// + private static void BuildContent(VisualElement root) + { + var container = new JContainer(ContainerSize.Xs); var content = new JStack(GapSize.Sm); - // Header content.Add(CreateHeader()); - #if UNITY_EDITOR - // Development Settings content.Add(CreateDevelopmentSettingsSection()); #endif - - // Server Settings content.Add(CreateServerSettingsSection()); - - // Asset Settings content.Add(CreateAssetSettingsSection()); - - // Security Settings content.Add(CreateSecuritySettingsSection()); - - // UI Settings content.Add(CreateUISettingsSection()); - - // Text Settings content.Add(CreateTextSettingsSection()); container.Add(content); root.Add(container); + } - // Register undo/redo callback - Undo.undoRedoPerformed += OnUndoRedo; - - // Cleanup callback when element is detached (no closure) - root.RegisterCallback(OnDetachFromPanel, OnUndoRedo); + private static void RebuildContent() + { + if (_currentRoot == null || _serializedObject == null || _bootstrap == null) + return; - return root; + _serializedObject.Update(); + _currentRoot.Clear(); + BuildContent(_currentRoot); } /// /// Called when element is detached from panel. Cleanup callback. /// - private static void OnDetachFromPanel(DetachFromPanelEvent evt, Undo.UndoRedoCallback undoCallback) + private static void OnDetachFromPanel(DetachFromPanelEvent evt) { - Undo.undoRedoPerformed -= undoCallback; + Undo.undoRedoPerformed -= OnUndoRedo; + EditorApplication.focusChanged -= OnEditorFocusChanged; } - /// - /// Called when undo/redo is performed. Rebuilds the inspector UI. - /// - private static void OnUndoRedo() - { - if (_currentRoot == null || _serializedObject == null || _bootstrap == null) - return; - - // Update serialized object to reflect undo/redo changes - _serializedObject.Update(); - - // Rebuild the entire UI - _currentRoot.Clear(); + private static void OnUndoRedo() => RebuildContent(); - // Centered container for compact inspector layout - var container = new JContainer(ContainerSize.Xs); - - // Recreate content - var content = new JStack(GapSize.Sm); + private static void OnEditorFocusChanged(bool hasFocus) + { + if (hasFocus) RebuildContent(); + } - content.Add(CreateHeader()); + private static void CheckForExternalDataChanges() + { + if (_bootstrap == null) return; + var signature = ComputeExternalDataSignature(); + if (signature == _lastExternalDataSignature) return; + _lastExternalDataSignature = signature; + RebuildContent(); + } -#if UNITY_EDITOR - content.Add(CreateDevelopmentSettingsSection()); -#endif - content.Add(CreateServerSettingsSection()); - content.Add(CreateAssetSettingsSection()); - content.Add(CreateSecuritySettingsSection()); - content.Add(CreateUISettingsSection()); - content.Add(CreateTextSettingsSection()); + /// + /// Concatenates the external data the dropdowns depend on (packages, asmdefs, scenes, + /// classes/methods for the current assembly, AOT files, dynamic keys) into a signature + /// string. When any of these change — e.g. a YooAsset package is renamed — the + /// inspector rebuilds so stale values fall back to "None". + /// + private static string ComputeExternalDataSignature() + { + var sb = new System.Text.StringBuilder(); + AppendList(sb, EditorUtils.GetAvailableYooAssetPackages()); + AppendList(sb, EditorUtils.GetAvailableAsmdefFiles()); + AppendList(sb, EditorUtils.GetAvailableHotScenes()); + AppendList(sb, EditorUtils.GetAvailableHotClasses(_bootstrap.hotCodeName)); + AppendList(sb, EditorUtils.GetAvailableHotMethods(_bootstrap.hotCodeName, _bootstrap.hotUpdateClassName)); + AppendList(sb, EditorUtils.GetAvailableAOTDataFiles()); + AppendList(sb, EditorUtils.GetAvailableDynamicSecretKeys()); + return sb.ToString(); + } - container.Add(content); - _currentRoot.Add(container); + private static void AppendList(System.Text.StringBuilder sb, List items) + { + sb.Append('|'); + if (items == null) return; + foreach (var item in items) sb.Append(item).Append(';'); } private static VisualElement CreateHeader() @@ -276,79 +300,79 @@ private static VisualElement CreateAssetSettingsSection() section.Add(new JFormField("Platform", targetPlatformField)); // Package Name - var packageChoices = EditorUtils.GetAvailableYooAssetPackages(); + var packageOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableYooAssetPackages()); var packageNameField = new JDropdown( - packageChoices.Count > 0 ? packageChoices : new List { _bootstrap.packageName }, - _bootstrap.packageName + packageOptions, + EditorUtils.ResolveDropdownValue(_bootstrap.packageName, packageOptions) ); packageNameField.OnValueChanged(value => { - _serializedObject.FindProperty(nameof(_bootstrap.packageName)).stringValue = value; + _serializedObject.FindProperty(nameof(_bootstrap.packageName)).stringValue = EditorUtils.NormalizeDropdownSelection(value); _serializedObject.ApplyModifiedProperties(); }); section.Add(new JFormField("Package", packageNameField)); // Hot Code Assembly - var hotCodeChoices = EditorUtils.GetAvailableAsmdefFiles(); + var hotCodeOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableAsmdefFiles()); var hotCodeField = new JDropdown( - hotCodeChoices.Count > 0 ? hotCodeChoices : new List { _bootstrap.hotCodeName }, - _bootstrap.hotCodeName + hotCodeOptions, + EditorUtils.ResolveDropdownValue(_bootstrap.hotCodeName, hotCodeOptions) ); hotCodeField.OnValueChanged(value => { - _serializedObject.FindProperty(nameof(_bootstrap.hotCodeName)).stringValue = value; + _serializedObject.FindProperty(nameof(_bootstrap.hotCodeName)).stringValue = EditorUtils.NormalizeDropdownSelection(value); _serializedObject.ApplyModifiedProperties(); }); section.Add(new JFormField("Code Assembly", hotCodeField)); // Hot Scene - var hotSceneChoices = EditorUtils.GetAvailableHotScenes(); + var hotSceneOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableHotScenes()); var hotSceneField = new JDropdown( - hotSceneChoices.Count > 0 ? hotSceneChoices : new List { _bootstrap.selectedHotScene }, - _bootstrap.selectedHotScene + hotSceneOptions, + EditorUtils.ResolveDropdownValue(_bootstrap.selectedHotScene, hotSceneOptions) ); hotSceneField.OnValueChanged(value => { - _serializedObject.FindProperty(nameof(_bootstrap.selectedHotScene)).stringValue = value; + _serializedObject.FindProperty(nameof(_bootstrap.selectedHotScene)).stringValue = EditorUtils.NormalizeDropdownSelection(value); _serializedObject.ApplyModifiedProperties(); }); section.Add(new JFormField("Scene", hotSceneField)); // Hot Update Entry Class - var hotClassChoices = EditorUtils.GetAvailableHotClasses(_bootstrap.hotCodeName); + var hotClassOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableHotClasses(_bootstrap.hotCodeName)); var hotClassField = new JDropdown( - hotClassChoices.Count > 0 ? hotClassChoices : new List { _bootstrap.hotUpdateClassName }, - _bootstrap.hotUpdateClassName + hotClassOptions, + EditorUtils.ResolveDropdownValue(_bootstrap.hotUpdateClassName, hotClassOptions) ); hotClassField.OnValueChanged(value => { - _serializedObject.FindProperty(nameof(_bootstrap.hotUpdateClassName)).stringValue = value; + _serializedObject.FindProperty(nameof(_bootstrap.hotUpdateClassName)).stringValue = EditorUtils.NormalizeDropdownSelection(value); _serializedObject.ApplyModifiedProperties(); }); section.Add(new JFormField("Entry Class", hotClassField)); // Hot Update Entry Method - var hotMethodChoices = EditorUtils.GetAvailableHotMethods(_bootstrap.hotCodeName, _bootstrap.hotUpdateClassName); + var hotMethodOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableHotMethods(_bootstrap.hotCodeName, _bootstrap.hotUpdateClassName)); var hotMethodField = new JDropdown( - hotMethodChoices.Count > 0 ? hotMethodChoices : new List { _bootstrap.hotUpdateMethodName }, - _bootstrap.hotUpdateMethodName + hotMethodOptions, + EditorUtils.ResolveDropdownValue(_bootstrap.hotUpdateMethodName, hotMethodOptions) ); hotMethodField.OnValueChanged(value => { - _serializedObject.FindProperty(nameof(_bootstrap.hotUpdateMethodName)).stringValue = value; + _serializedObject.FindProperty(nameof(_bootstrap.hotUpdateMethodName)).stringValue = EditorUtils.NormalizeDropdownSelection(value); _serializedObject.ApplyModifiedProperties(); }); section.Add(new JFormField("Entry Method", hotMethodField)); // AOT DLL List File - var aotChoices = EditorUtils.GetAvailableAOTDataFiles(); + var aotOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableAOTDataFiles()); var aotField = new JDropdown( - aotChoices.Count > 0 ? aotChoices : new List { _bootstrap.aotDllListFilePath }, - _bootstrap.aotDllListFilePath + aotOptions, + EditorUtils.ResolveDropdownValue(_bootstrap.aotDllListFilePath, aotOptions) ); aotField.OnValueChanged(value => { - _serializedObject.FindProperty(nameof(_bootstrap.aotDllListFilePath)).stringValue = value; + _serializedObject.FindProperty(nameof(_bootstrap.aotDllListFilePath)).stringValue = EditorUtils.NormalizeDropdownSelection(value); _serializedObject.ApplyModifiedProperties(); }); section.Add(new JFormField("AOT DLL List", aotField)); @@ -361,14 +385,14 @@ private static VisualElement CreateSecuritySettingsSection() var section = new JSection("Security Settings"); // Dynamic Secret Key - var dynamicKeyChoices = EditorUtils.GetAvailableDynamicSecretKeys(); + var dynamicKeyOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableDynamicSecretKeys()); var dynamicKeyField = new JDropdown( - dynamicKeyChoices.Count > 0 ? dynamicKeyChoices : new List { _bootstrap.dynamicSecretKeyPath }, - _bootstrap.dynamicSecretKeyPath + dynamicKeyOptions, + EditorUtils.ResolveDropdownValue(_bootstrap.dynamicSecretKeyPath, dynamicKeyOptions) ); dynamicKeyField.OnValueChanged(value => { - _serializedObject.FindProperty(nameof(_bootstrap.dynamicSecretKeyPath)).stringValue = value; + _serializedObject.FindProperty(nameof(_bootstrap.dynamicSecretKeyPath)).stringValue = EditorUtils.NormalizeDropdownSelection(value); _serializedObject.ApplyModifiedProperties(); }); section.Add(new JFormField("Secret Key", dynamicKeyField)); diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Editor/Internal/PanelUI.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Editor/Internal/PanelUI.cs index 95d393853..5ea87e34e 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Editor/Internal/PanelUI.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Editor/Internal/PanelUI.cs @@ -177,14 +177,14 @@ private static VisualElement CreatePackageSettingsSection(Settings settings) var section = new JSection("Package Settings"); // Package Name - var packageChoices = EditorUtils.GetAvailableYooAssetPackages(); + var packageOptions = EditorUtils.WithNoneOption(EditorUtils.GetAvailableYooAssetPackages()); var packageNameField = new JDropdown( - packageChoices.Count > 0 ? packageChoices : new List { settings.packageName }, - settings.packageName + packageOptions, + EditorUtils.ResolveDropdownValue(settings.packageName, packageOptions) ); packageNameField.OnValueChanged(value => { - settings.packageName = value; + settings.packageName = EditorUtils.NormalizeDropdownSelection(value); settings.Save(); }); section.Add(new JFormField("Package", packageNameField)); diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Internal/BootstrapEditorUITests.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Internal/BootstrapEditorUITests.cs index 8b9864573..a4bffed4b 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Internal/BootstrapEditorUITests.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Internal/BootstrapEditorUITests.cs @@ -773,8 +773,71 @@ public void OnDetachFromPanel_DoesNotThrow() BindingFlags.NonPublic | BindingFlags.Static); Assert.IsNotNull(method, "OnDetachFromPanel method should exist"); - Undo.UndoRedoCallback callback = () => { }; - Assert.DoesNotThrow(() => method.Invoke(null, new object[] { null, callback })); + // Signature changed to take only the DetachFromPanelEvent (callbacks are now + // unregistered from statically-known handlers rather than via a user token). + Assert.DoesNotThrow(() => method.Invoke(null, new object[] { null })); + } + + [Test] + public void OnEditorFocusChanged_WithFocus_RebuildsContent() + { + var root = BootstrapEditorUI.CreateInspector(_serializedObject, _bootstrap); + + var method = typeof(BootstrapEditorUI).GetMethod("OnEditorFocusChanged", + BindingFlags.NonPublic | BindingFlags.Static); + Assert.IsNotNull(method, "OnEditorFocusChanged method should exist"); + + Assert.DoesNotThrow(() => method.Invoke(null, new object[] { true })); + Assert.IsTrue(root.childCount > 0, "Inspector should still have content after refocus rebuild"); + } + + [Test] + public void OnEditorFocusChanged_WithoutFocus_DoesNotRebuild() + { + BootstrapEditorUI.CreateInspector(_serializedObject, _bootstrap); + + var method = typeof(BootstrapEditorUI).GetMethod("OnEditorFocusChanged", + BindingFlags.NonPublic | BindingFlags.Static); + + // hasFocus=false should early-return without rebuilding (no exception). + Assert.DoesNotThrow(() => method.Invoke(null, new object[] { false })); + } + + [Test] + public void ComputeExternalDataSignature_IsStableAcrossCalls() + { + BootstrapEditorUI.CreateInspector(_serializedObject, _bootstrap); + + var method = typeof(BootstrapEditorUI).GetMethod("ComputeExternalDataSignature", + BindingFlags.NonPublic | BindingFlags.Static); + Assert.IsNotNull(method, "ComputeExternalDataSignature method should exist"); + + var a = (string)method.Invoke(null, null); + var b = (string)method.Invoke(null, null); + + Assert.IsNotNull(a); + Assert.AreEqual(a, b, "Signature should be deterministic for unchanged external data"); + Assert.IsTrue(a.Contains("|"), "Signature should contain section separators"); + } + + [Test] + public void CheckForExternalDataChanges_DoesNotThrow() + { + BootstrapEditorUI.CreateInspector(_serializedObject, _bootstrap); + + var method = typeof(BootstrapEditorUI).GetMethod("CheckForExternalDataChanges", + BindingFlags.NonPublic | BindingFlags.Static); + Assert.IsNotNull(method, "CheckForExternalDataChanges method should exist"); + + // First call after CreateInspector: signature matches seeded value, early return. + Assert.DoesNotThrow(() => method.Invoke(null, null)); + + // Force a mismatch so the rebuild branch executes. + var sigField = typeof(BootstrapEditorUI).GetField("_lastExternalDataSignature", + BindingFlags.NonPublic | BindingFlags.Static); + sigField.SetValue(null, "stale-signature"); + + Assert.DoesNotThrow(() => method.Invoke(null, null)); } [Test] diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Internal/PanelUITests.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Internal/PanelUITests.cs index 1d07affb8..92967d558 100644 --- a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Internal/PanelUITests.cs +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Internal/PanelUITests.cs @@ -670,5 +670,64 @@ private static Button FindButtonByText(VisualElement root, string text) } #endregion + + #region Panel.OnFocus Tests + + [Test] + public void Panel_OnFocus_WithoutRoot_DoesNotThrow() + { + // Instantiate Panel without showing the window; _root is null, so OnFocus should + // early-return without touching anything. + var panel = ScriptableObject.CreateInstance(); + try + { + var method = typeof(Panel).GetMethod("OnFocus", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + Assert.IsNotNull(method, "Panel.OnFocus should exist"); + Assert.DoesNotThrow(() => method.Invoke(panel, null)); + } + finally + { + UnityEngine.Object.DestroyImmediate(panel); + } + } + + [Test] + public void Panel_OnFocus_DuringBuild_SkipsRebuild() + { + var panel = ScriptableObject.CreateInstance(); + try + { + // Stub a root and a BuildManager that reports "building" to exercise the guard. + var rootField = typeof(Panel).GetField("_root", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + var stubRoot = new VisualElement(); + stubRoot.Add(new Label("sentinel")); + rootField.SetValue(panel, stubRoot); + + // Starting a build on a stub BuildManager will flip IsBuilding without actually + // invoking Unity build steps; the Update loop never runs in tests. + var bmField = typeof(Panel).GetField("_buildManager", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + var bm = new BuildManager(_settings, (m, e) => { }); + bm.StartBuildCodeOnly(() => { }, _ => { }); + bmField.SetValue(panel, bm); + + var method = typeof(Panel).GetMethod("OnFocus", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + method.Invoke(panel, null); + + // Root should still contain the sentinel child - OnFocus must not rebuild + // while a build is in progress. + Assert.AreEqual(1, stubRoot.childCount, + "OnFocus should skip rebuild when BuildManager.IsBuilding is true"); + } + finally + { + UnityEngine.Object.DestroyImmediate(panel); + } + } + + #endregion } } diff --git a/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Utilities/EditorUtilsTests.cs b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Utilities/EditorUtilsTests.cs new file mode 100644 index 000000000..06b0641dc --- /dev/null +++ b/UnityProject/Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Utilities/EditorUtilsTests.cs @@ -0,0 +1,149 @@ +// EditorUtilsTests.cs +// EditMode unit tests for JEngine.Core.Editor.EditorUtils dropdown helpers. + +using System.Collections.Generic; +using NUnit.Framework; +using JEngine.Core.Editor; + +namespace JEngine.UI.Tests.Editor.Utilities +{ + [TestFixture] + public class EditorUtilsTests + { + #region WithNoneOption Tests + + [Test] + public void WithNoneOption_NullChoices_ReturnsSingletonNone() + { + var result = EditorUtils.WithNoneOption(null); + + Assert.AreEqual(1, result.Count); + Assert.AreEqual(EditorUtils.NoneDropdownOption, result[0]); + } + + [Test] + public void WithNoneOption_EmptyChoices_ReturnsSingletonNone() + { + var result = EditorUtils.WithNoneOption(new List()); + + Assert.AreEqual(1, result.Count); + Assert.AreEqual(EditorUtils.NoneDropdownOption, result[0]); + } + + [Test] + public void WithNoneOption_PopulatedChoices_PrependsNoneInOrder() + { + var result = EditorUtils.WithNoneOption(new List { "main", "addon1", "raw" }); + + Assert.AreEqual(4, result.Count); + Assert.AreEqual(EditorUtils.NoneDropdownOption, result[0]); + Assert.AreEqual("main", result[1]); + Assert.AreEqual("addon1", result[2]); + Assert.AreEqual("raw", result[3]); + } + + [Test] + public void WithNoneOption_ReturnsNewList_DoesNotMutateInput() + { + var input = new List { "a", "b" }; + var result = EditorUtils.WithNoneOption(input); + + Assert.AreEqual(2, input.Count, "Input list should not be modified"); + Assert.AreNotSame(input, result); + } + + #endregion + + #region ResolveDropdownValue Tests + + [Test] + public void ResolveDropdownValue_StoredValuePresent_ReturnsStoredValue() + { + var options = new List { EditorUtils.NoneDropdownOption, "main", "addon1" }; + var result = EditorUtils.ResolveDropdownValue("main", options); + + Assert.AreEqual("main", result); + } + + [Test] + public void ResolveDropdownValue_StoredValueMissing_ReturnsNone() + { + var options = new List { EditorUtils.NoneDropdownOption, "game" }; + var result = EditorUtils.ResolveDropdownValue("main", options); + + Assert.AreEqual(EditorUtils.NoneDropdownOption, result); + } + + [Test] + public void ResolveDropdownValue_StoredValueEmpty_ReturnsNone() + { + var options = new List { EditorUtils.NoneDropdownOption, "main" }; + + Assert.AreEqual(EditorUtils.NoneDropdownOption, EditorUtils.ResolveDropdownValue("", options)); + Assert.AreEqual(EditorUtils.NoneDropdownOption, EditorUtils.ResolveDropdownValue(null, options)); + } + + [Test] + public void ResolveDropdownValue_OptionsNull_ReturnsNone() + { + var result = EditorUtils.ResolveDropdownValue("main", null); + + Assert.AreEqual(EditorUtils.NoneDropdownOption, result); + } + + #endregion + + #region NormalizeDropdownSelection Tests + + [Test] + public void NormalizeDropdownSelection_NoneSentinel_ReturnsEmpty() + { + var result = EditorUtils.NormalizeDropdownSelection(EditorUtils.NoneDropdownOption); + + Assert.AreEqual(string.Empty, result); + } + + [Test] + public void NormalizeDropdownSelection_RealValue_ReturnsAsIs() + { + Assert.AreEqual("main", EditorUtils.NormalizeDropdownSelection("main")); + Assert.AreEqual("HotUpdate.Code.dll", EditorUtils.NormalizeDropdownSelection("HotUpdate.Code.dll")); + } + + [Test] + public void NormalizeDropdownSelection_EmptyString_ReturnsEmpty() + { + Assert.AreEqual(string.Empty, EditorUtils.NormalizeDropdownSelection(string.Empty)); + } + + #endregion + + #region Roundtrip Tests + + [Test] + public void Roundtrip_StoredValuePresent_PreservesValue() + { + var options = EditorUtils.WithNoneOption(new List { "main", "addon1" }); + var current = EditorUtils.ResolveDropdownValue("main", options); + var normalized = EditorUtils.NormalizeDropdownSelection(current); + + Assert.AreEqual("main", normalized); + } + + [Test] + public void Roundtrip_StoredValueMissing_NormalizesToEmpty() + { + // Simulates the package-renamed case: "main" was stored but current choices only + // contain "game" after the rename - the dropdown should display "None" and, if the + // user confirms, the stored value should be cleared to empty. + var options = EditorUtils.WithNoneOption(new List { "game" }); + var current = EditorUtils.ResolveDropdownValue("main", options); + var normalized = EditorUtils.NormalizeDropdownSelection(current); + + Assert.AreEqual(EditorUtils.NoneDropdownOption, current); + Assert.AreEqual(string.Empty, normalized); + } + + #endregion + } +}