From d1288fd3357128aaa6faae82e45a336f2207c054 Mon Sep 17 00:00:00 2001 From: bd_ Date: Tue, 11 Apr 2023 20:21:00 +0900 Subject: [PATCH] fix: use IEditorOnly instead of mokeypatching the SDK (#274) Increased SDK version requirement to 3.1.13 accordingly. --- .../Editor/ComponentAllowlistPatch.cs | 132 ------------------ .../Editor/ComponentAllowlistPatch.cs.meta | 3 - .../Editor/Inspector/MAEditorBase.cs | 1 - .../Runtime/AvatarTagComponent.cs | 3 +- .../nadena.dev.modular-avatar/package.json | 2 +- 5 files changed, 3 insertions(+), 138 deletions(-) delete mode 100644 Packages/nadena.dev.modular-avatar/Editor/ComponentAllowlistPatch.cs delete mode 100644 Packages/nadena.dev.modular-avatar/Editor/ComponentAllowlistPatch.cs.meta diff --git a/Packages/nadena.dev.modular-avatar/Editor/ComponentAllowlistPatch.cs b/Packages/nadena.dev.modular-avatar/Editor/ComponentAllowlistPatch.cs deleted file mode 100644 index 62b389db..00000000 --- a/Packages/nadena.dev.modular-avatar/Editor/ComponentAllowlistPatch.cs +++ /dev/null @@ -1,132 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 bd_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using UnityEditor; -using UnityEngine; - -namespace nadena.dev.modular_avatar.core.editor -{ - [InitializeOnLoad] - internal static class ComponentAllowlistPatch - { - internal static readonly bool PATCH_OK; - - static ComponentAllowlistPatch() - { - try - { - PatchAllowlist(); - PATCH_OK = true; - } - catch (Exception e) - { - Debug.LogException(e); - PATCH_OK = false; - } - } - - static void PatchAllowlist() - { - // The below APIs are all public, but undocumented and likely to change in the future. - // As such, we use reflection to access them (allowing us to catch exceptions instead of just breaking the - // build - and allowing the user to manually bake as a workaround). - - // The basic idea is to retrieve the HashSet of whitelisted components, and add all components extending - // from AvatarTagComponent to it. This HashSet is cached on first access, but the lists of allowed - // components used to initially populate it are private. So, we'll start off by making a call that (as a - // side-effect) causes the list to be initially cached. This call will throw a NPE because we're passing - // a null GameObject, but that's okay. - - var avatarValidation = Util.FindType("VRC.SDK3.Validation.AvatarValidation"); - var findIllegalComponents = - avatarValidation?.GetMethod("FindIllegalComponents", BindingFlags.Public | BindingFlags.Static); - - if (findIllegalComponents == null) - { - Debug.LogError( - "[ModularAvatar] Unsupported VRCSDK version: Failed to find AvatarValidation.FindIllegalComponents"); - return; - } - - try - { - findIllegalComponents.Invoke(null, new[] {(object) null}); - } - catch (TargetInvocationException e) - { - if (e.InnerException is NullReferenceException) - { - // ok! - } - else - { - System.Diagnostics.Debug.Assert(e.InnerException != null, "e.InnerException != null"); - throw e.InnerException; - } - } - - // Now fetch the cached allowlist and add our components to it. - var validationUtils = Util.FindType("VRC.SDKBase.Validation.ValidationUtils"); - var whitelistedTypes = validationUtils?.GetMethod( - "WhitelistedTypes", - BindingFlags.Public | BindingFlags.Static, - null, - new[] {typeof(string), typeof(IEnumerable)}, - null - ); - - if (whitelistedTypes == null) - { - Debug.LogError( - "[ModularAvatar] Unsupported VRCSDK version: Failed to find ValidationUtils.WhitelistedTypes"); - return; - } - - var allowlist = whitelistedTypes.Invoke(null, new object[] {"avatar-sdk3", null}) as HashSet; - if (allowlist == null) - { - Debug.LogError("[ModularAvatar] Unsupported VRCSDK version: Failed to retrieve component whitelist"); - return; - } - - allowlist.Add(typeof(AvatarTagComponent)); - - // We'll need to find all types which derive from AvatarTagComponent and inject them into the allowlist - // as well. - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - foreach (var ty in assembly.GetTypes()) - { - if (typeof(AvatarTagComponent).IsAssignableFrom(ty)) - { - allowlist.Add(ty); - } - } - } - } - } -} \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Editor/ComponentAllowlistPatch.cs.meta b/Packages/nadena.dev.modular-avatar/Editor/ComponentAllowlistPatch.cs.meta deleted file mode 100644 index dcc967c0..00000000 --- a/Packages/nadena.dev.modular-avatar/Editor/ComponentAllowlistPatch.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 657f099f7fc04609a5cfc9ac5461d7e3 -timeCreated: 1661563992 \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Editor/Inspector/MAEditorBase.cs b/Packages/nadena.dev.modular-avatar/Editor/Inspector/MAEditorBase.cs index 3d9cd96e..275f2f71 100644 --- a/Packages/nadena.dev.modular-avatar/Editor/Inspector/MAEditorBase.cs +++ b/Packages/nadena.dev.modular-avatar/Editor/Inspector/MAEditorBase.cs @@ -116,7 +116,6 @@ namespace nadena.dev.modular_avatar.core.editor } InspectorCommon.DisplayOutOfAvatarWarning(targets); - if (!ComponentAllowlistPatch.PATCH_OK) InspectorCommon.DisplayVRCSDKVersionWarning(); OnInnerInspectorGUI(); } diff --git a/Packages/nadena.dev.modular-avatar/Runtime/AvatarTagComponent.cs b/Packages/nadena.dev.modular-avatar/Runtime/AvatarTagComponent.cs index f22b6402..c01387ec 100644 --- a/Packages/nadena.dev.modular-avatar/Runtime/AvatarTagComponent.cs +++ b/Packages/nadena.dev.modular-avatar/Runtime/AvatarTagComponent.cs @@ -24,6 +24,7 @@ using System; using UnityEngine; +using VRC.SDKBase; namespace nadena.dev.modular_avatar.core { @@ -31,7 +32,7 @@ namespace nadena.dev.modular_avatar.core * This abstract base class is injected into the VRCSDK avatar component allowlist to avoid */ [DefaultExecutionOrder(-9999)] // run before av3emu - public abstract class AvatarTagComponent : MonoBehaviour + public abstract class AvatarTagComponent : MonoBehaviour, IEditorOnly { internal static event Action OnChangeAction; diff --git a/Packages/nadena.dev.modular-avatar/package.json b/Packages/nadena.dev.modular-avatar/package.json index 476987c6..f9bedbf4 100644 --- a/Packages/nadena.dev.modular-avatar/package.json +++ b/Packages/nadena.dev.modular-avatar/package.json @@ -15,6 +15,6 @@ "com.unity.nuget.newtonsoft-json": "2.0.0" }, "vpmDependencies": { - "com.vrchat.avatars": ">=3.1.9" + "com.vrchat.avatars": ">=3.1.13" } }