avatar/Assets/VRCSDK/Dependencies/VRChat/Scripts/Validation/WorldValidation.cs
2022-09-27 20:47:45 -07:00

697 lines
29 KiB
C#

using System;
using System.Collections.Generic;
using JetBrains.Annotations;
#if TextMeshPro
using TMPro;
#endif
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using UnityEngine.UI;
namespace VRC.SDKBase.Validation
{
public static class WorldValidation
{
private static readonly Lazy<int> _debugLevel = new Lazy<int>(InitializeLogging);
private static int DebugLevel => _debugLevel.Value;
private static int InitializeLogging()
{
int hashCode = typeof(WorldValidation).GetHashCode();
VRC.Core.Logger.DescribeDebugLevel(hashCode, "WorldValidation", VRC.Core.Logger.Color.red);
VRC.Core.Logger.AddDebugLevel(hashCode);
return hashCode;
}
static string[] ComponentTypeWhiteList = null;
public enum WhiteListConfiguration
{
None,
VRCSDK2,
VRCSDK3,
Unchanged
}
static WhiteListConfiguration ComponentTypeWhiteListConfiguration = WhiteListConfiguration.None;
static readonly string[] ComponentTypeWhiteListCommon = new string[]
{
#if UNITY_STANDALONE
"UnityEngine.Rendering.PostProcessing.PostProcessDebug",
"UnityEngine.Rendering.PostProcessing.PostProcessLayer",
"UnityEngine.Rendering.PostProcessing.PostProcessVolume",
#endif
"VRC.Core.PipelineManager",
"UiInputField",
"VRCProjectSettings",
"DynamicBone",
"DynamicBoneCollider",
"TMPro.TMP_Dropdown",
"TMPro.TMP_InputField",
"TMPro.TMP_ScrollbarEventHandler",
"TMPro.TMP_SelectionCaret",
"TMPro.TMP_SpriteAnimator",
"TMPro.TMP_SubMesh",
"TMPro.TMP_SubMeshUI",
"TMPro.TMP_Text",
"TMPro.TextMeshPro",
"TMPro.TextMeshProUGUI",
"TMPro.TextContainer",
"TMPro.TMP_Dropdown+DropdownItem",
"UnityEngine.EventSystems.EventSystem",
"UnityEngine.EventSystems.EventTrigger",
"UnityEngine.EventSystems.UIBehaviour",
"UnityEngine.EventSystems.BaseInput",
"UnityEngine.EventSystems.BaseInputModule",
"UnityEngine.EventSystems.PointerInputModule",
"UnityEngine.EventSystems.StandaloneInputModule",
"UnityEngine.EventSystems.TouchInputModule",
"UnityEngine.EventSystems.BaseRaycaster",
"UnityEngine.EventSystems.PhysicsRaycaster",
"UnityEngine.UI.Button",
"UnityEngine.UI.Dropdown",
"UnityEngine.UI.Dropdown+DropdownItem",
"UnityEngine.UI.Graphic",
"UnityEngine.UI.GraphicRaycaster",
"UnityEngine.UI.Image",
"UnityEngine.UI.InputField",
"UnityEngine.UI.Mask",
"UnityEngine.UI.MaskableGraphic",
"UnityEngine.UI.RawImage",
"UnityEngine.UI.RectMask2D",
"UnityEngine.UI.Scrollbar",
"UnityEngine.UI.ScrollRect",
"UnityEngine.UI.Selectable",
"UnityEngine.UI.Slider",
"UnityEngine.UI.Text",
"UnityEngine.UI.Toggle",
"UnityEngine.UI.ToggleGroup",
"UnityEngine.UI.AspectRatioFitter",
"UnityEngine.UI.CanvasScaler",
"UnityEngine.UI.ContentSizeFitter",
"UnityEngine.UI.GridLayoutGroup",
"UnityEngine.UI.HorizontalLayoutGroup",
"UnityEngine.UI.HorizontalOrVerticalLayoutGroup",
"UnityEngine.UI.LayoutElement",
"UnityEngine.UI.LayoutGroup",
"UnityEngine.UI.VerticalLayoutGroup",
"UnityEngine.UI.BaseMeshEffect",
"UnityEngine.UI.Outline",
"UnityEngine.UI.PositionAsUV1",
"UnityEngine.UI.Shadow",
"OVRLipSync",
"OVRLipSyncContext",
"OVRLipSyncContextBase",
"OVRLipSyncContextCanned",
"OVRLipSyncContextMorphTarget",
"OVRLipSyncContextTextureFlip",
"ONSPReflectionZone",
"OculusSpatializerUnity",
"ONSPAmbisonicsNative",
"ONSPAudioSource",
"RootMotion.FinalIK.BipedIK",
"RootMotion.FinalIK.FingerRig",
"RootMotion.FinalIK.Grounder",
"RootMotion.FinalIK.GrounderBipedIK",
"RootMotion.FinalIK.GrounderFBBIK",
"RootMotion.FinalIK.GrounderIK",
"RootMotion.FinalIK.GrounderQuadruped",
"RootMotion.FinalIK.GrounderVRIK",
"RootMotion.FinalIK.AimIK",
"RootMotion.FinalIK.CCDIK",
"RootMotion.FinalIK.FABRIK",
"RootMotion.FinalIK.FABRIKRoot",
"RootMotion.FinalIK.FullBodyBipedIK",
"RootMotion.FinalIK.IK",
"RootMotion.FinalIK.IKExecutionOrder",
"RootMotion.FinalIK.LegIK",
"RootMotion.FinalIK.LimbIK",
"RootMotion.FinalIK.LookAtIK",
"RootMotion.FinalIK.TrigonometricIK",
"RootMotion.FinalIK.VRIK",
"RootMotion.FinalIK.FBBIKArmBending",
"RootMotion.FinalIK.FBBIKHeadEffector",
"RootMotion.FinalIK.TwistRelaxer",
"RootMotion.FinalIK.InteractionObject",
"RootMotion.FinalIK.InteractionSystem",
"RootMotion.FinalIK.InteractionTarget",
"RootMotion.FinalIK.InteractionTrigger",
"RootMotion.FinalIK.GenericPoser",
"RootMotion.FinalIK.HandPoser",
"RootMotion.FinalIK.Poser",
"RootMotion.FinalIK.RagdollUtility",
"RootMotion.FinalIK.RotationLimit",
"RootMotion.FinalIK.RotationLimitAngle",
"RootMotion.FinalIK.RotationLimitHinge",
"RootMotion.FinalIK.RotationLimitPolygonal",
"RootMotion.FinalIK.RotationLimitSpline",
"RootMotion.FinalIK.AimPoser",
"RootMotion.FinalIK.Amplifier",
"RootMotion.FinalIK.BodyTilt",
"RootMotion.FinalIK.HitReaction",
"RootMotion.FinalIK.HitReactionVRIK",
"RootMotion.FinalIK.Inertia",
"RootMotion.FinalIK.OffsetModifier",
"RootMotion.FinalIK.OffsetModifierVRIK",
"RootMotion.FinalIK.OffsetPose",
"RootMotion.FinalIK.Recoil",
"RootMotion.FinalIK.ShoulderRotator",
"RootMotion.Dynamics.AnimationBlocker",
"RootMotion.Dynamics.BehaviourBase",
"RootMotion.Dynamics.BehaviourFall",
"RootMotion.Dynamics.BehaviourPuppet",
"RootMotion.Dynamics.JointBreakBroadcaster",
"RootMotion.Dynamics.MuscleCollisionBroadcaster",
"RootMotion.Dynamics.PressureSensor",
"RootMotion.Dynamics.Prop",
"RootMotion.Dynamics.PropRoot",
"RootMotion.Dynamics.PuppetMaster",
"RootMotion.Dynamics.PuppetMasterSettings",
// TODO: remove these if they are only needed in editor
"RootMotion.Dynamics.BipedRagdollCreator",
"RootMotion.Dynamics.RagdollCreator",
"RootMotion.Dynamics.RagdollEditor",
//
"RootMotion.SolverManager",
"RootMotion.TriggerEventBroadcaster",
"UnityEngine.WindZone",
"UnityEngine.Tilemaps.Tilemap",
"UnityEngine.Tilemaps.TilemapRenderer",
"UnityEngine.Terrain",
"UnityEngine.Tree",
"UnityEngine.SpriteMask",
"UnityEngine.Grid",
"UnityEngine.GridLayout",
"UnityEngine.AudioSource",
"UnityEngine.AudioReverbZone",
"UnityEngine.AudioLowPassFilter",
"UnityEngine.AudioHighPassFilter",
"UnityEngine.AudioDistortionFilter",
"UnityEngine.AudioEchoFilter",
"UnityEngine.AudioChorusFilter",
"UnityEngine.AudioReverbFilter",
"UnityEngine.Playables.PlayableDirector",
"UnityEngine.TerrainCollider",
"UnityEngine.Canvas",
"UnityEngine.CanvasGroup",
"UnityEngine.CanvasRenderer",
"UnityEngine.TextMesh",
"UnityEngine.Animator",
"UnityEngine.AI.NavMeshAgent",
"UnityEngine.AI.NavMeshObstacle",
"UnityEngine.AI.OffMeshLink",
"UnityEngine.Cloth",
"UnityEngine.WheelCollider",
"UnityEngine.Rigidbody",
"UnityEngine.Joint",
"UnityEngine.HingeJoint",
"UnityEngine.SpringJoint",
"UnityEngine.FixedJoint",
"UnityEngine.CharacterJoint",
"UnityEngine.ConfigurableJoint",
"UnityEngine.ConstantForce",
"UnityEngine.Collider",
"UnityEngine.BoxCollider",
"UnityEngine.SphereCollider",
"UnityEngine.MeshCollider",
"UnityEngine.CapsuleCollider",
"UnityEngine.CharacterController",
"UnityEngine.ParticleSystem",
"UnityEngine.ParticleSystemRenderer",
"UnityEngine.BillboardRenderer",
"UnityEngine.Camera",
"UnityEngine.FlareLayer",
"UnityEngine.SkinnedMeshRenderer",
"UnityEngine.Renderer",
"UnityEngine.TrailRenderer",
"UnityEngine.LineRenderer",
"UnityEngine.GUIElement",
"UnityEngine.GUILayer",
"UnityEngine.Light",
"UnityEngine.LightProbeGroup",
"UnityEngine.LightProbeProxyVolume",
"UnityEngine.LODGroup",
"UnityEngine.ReflectionProbe",
"UnityEngine.SpriteRenderer",
"UnityEngine.Transform",
"UnityEngine.RectTransform",
"UnityEngine.Rendering.SortingGroup",
"UnityEngine.Projector",
"UnityEngine.OcclusionPortal",
"UnityEngine.OcclusionArea",
"UnityEngine.LensFlare",
"UnityEngine.Skybox",
"UnityEngine.MeshFilter",
"UnityEngine.Halo",
"UnityEngine.MeshRenderer",
"UnityEngine.Collider2D",
"UnityEngine.Rigidbody2D",
"UnityEngine.CompositeCollider2D",
"UnityEngine.ConstantForce2D",
"UnityEngine.AreaEffector2D",
"UnityEngine.CapsuleCollider2D",
"UnityEngine.DistanceJoint2D",
"UnityEngine.EdgeCollider2D",
"UnityEngine.Effector2D",
"UnityEngine.BoxCollider2D",
"UnityEngine.CircleCollider2D",
"UnityEngine.FixedJoint2D",
"UnityEngine.HingeJoint2D",
"UnityEngine.FrictionJoint2D",
"UnityEngine.PlatformEffector2D",
"UnityEngine.PointEffector2D",
"UnityEngine.PolygonCollider2D",
"UnityEngine.SliderJoint2D",
"UnityEngine.SurfaceEffector2D",
"UnityEngine.RelativeJoint2D",
"UnityEngine.TargetJoint2D",
"UnityEngine.WheelJoint2D",
"UnityEngine.Joint2D",
"UnityEngine.ParticleSystemForceField"
};
static readonly string[] ComponentTypeWhiteListSdk2 = new string[]
{
#if UNITY_STANDALONE
"VRCSDK2.VRC_CustomRendererBehaviour",
"VRCSDK2.VRC_MidiNoteIn",
"VRCSDK2.scripts.Scenes.VRC_Panorama",
"VRCSDK2.VRC_Water",
"UnityStandardAssets.Water.WaterBasic",
"UnityStandardAssets.Water.Displace",
"UnityStandardAssets.Water.GerstnerDisplace",
"UnityStandardAssets.Water.PlanarReflection",
"UnityStandardAssets.Water.SpecularLighting",
"UnityStandardAssets.Water.Water",
"UnityStandardAssets.Water.WaterBase",
"UnityStandardAssets.Water.WaterTile",
#endif
"VRCSDK2.VRCTriggerRelay",
"VRCSDK2.VRC_AudioBank",
"VRCSDK2.VRC_DataStorage",
"VRCSDK2.VRC_EventHandler",
"VRCSDK2.VRC_IKFollower",
"VRCSDK2.VRC_Label",
"VRCSDK2.VRC_KeyEvents",
"VRCSDK2.VRC_PhysicsRoot",
"VRCSDK2.VRC_CombatSystem",
"VRCSDK2.VRC_DestructibleStandard",
"VRC_VisualDamage",
"VRCSDK2.VRC_OscButtonIn",
"VRCSDK2.VRC_GunStats",
"VRCSDK2.VRC_JukeBox",
"VRCSDK2.VRC_AddDamage",
"VRCSDK2.VRC_AddHealth",
"VRCSDK2.VRC_AvatarCalibrator",
"VRCSDK2.VRC_AvatarPedestal",
"VRCSDK2.VRC_NPCSpawn",
"VRCSDK2.VRC_ObjectSpawn",
"VRCSDK2.VRC_ObjectSync",
"VRCSDK2.VRC_Pickup",
"VRCSDK2.VRC_PortalMarker",
"VRCSDK2.VRC_SlideShow",
"VRCSDK2.VRC_SpatialAudioSource",
"VRCSDK2.VRC_StationInput",
"VRCSDK2.VRC_SyncAnimation",
"VRCSDK2.VRC_SyncVideoPlayer",
"VRCSDK2.VRC_SyncVideoStream",
"VRCSDK2.VRC_VideoScreen",
"VRCSDK2.VRC_VideoSpeaker",
"VRCSDK2.VRC_PlayerAudioOverride",
"VRCSDK2.VRC_MirrorReflection",
"VRCSDK2.VRC_PlayerMods",
"VRCSDK2.VRC_SceneDescriptor",
"VRCSDK2.VRC_SceneResetPosition",
"VRCSDK2.VRC_SceneSmoothShift",
"VRCSDK2.VRC_SpecialLayer",
"VRCSDK2.VRC_Station",
"VRCSDK2.VRC_StereoObject",
"VRCSDK2.VRC_TimedEvents",
"VRCSDK2.VRC_Trigger",
"VRCSDK2.VRC_TriggerColliderEventTrigger",
"VRCSDK2.VRC_UseEvents",
"VRCSDK2.VRC_UiShape",
"UnityEngine.Animation",
#if !UNITY_2019_4_OR_NEWER
"UnityEngine.GUIText",
"UnityEngine.GUITexture",
#endif
"UnityEngine.Video.VideoPlayer",
"PhysSound.PhysSoundBase",
"PhysSound.PhysSoundObject",
"PhysSound.PhysSoundTempAudio",
"PhysSound.PhysSoundTempAudioPool",
"PhysSound.PhysSoundTerrain",
"RealisticEyeMovements.EyeAndHeadAnimator",
"RealisticEyeMovements.LookTargetController",
"UnityStandardAssets.Cameras.AbstractTargetFollower",
"UnityStandardAssets.Cameras.AutoCam",
"UnityStandardAssets.Cameras.FreeLookCam",
"UnityStandardAssets.Cameras.HandHeldCam",
"UnityStandardAssets.Cameras.LookatTarget",
"UnityStandardAssets.Cameras.PivotBasedCameraRig",
"UnityStandardAssets.Cameras.ProtectCameraFromWallClip",
"UnityStandardAssets.Cameras.TargetFieldOfView",
"UnityStandardAssets.Characters.FirstPerson.FirstPersonController",
"UnityStandardAssets.Characters.FirstPerson.HeadBob",
"UnityStandardAssets.Characters.FirstPerson.RigidbodyFirstPersonController",
"UnityStandardAssets.Vehicles.Ball.Ball",
"UnityStandardAssets.Vehicles.Ball.BallUserControl",
"UnityStandardAssets.Characters.ThirdPerson.AICharacterControl",
"UnityStandardAssets.Characters.ThirdPerson.ThirdPersonCharacter",
"UnityStandardAssets.Characters.ThirdPerson.ThirdPersonUserControl",
"UnityStandardAssets.CrossPlatformInput.AxisTouchButton",
"UnityStandardAssets.CrossPlatformInput.ButtonHandler",
"UnityStandardAssets.CrossPlatformInput.InputAxisScrollbar",
"UnityStandardAssets.CrossPlatformInput.Joystick",
"UnityStandardAssets.CrossPlatformInput.MobileControlRig",
"UnityStandardAssets.CrossPlatformInput.TiltInput",
"UnityStandardAssets.CrossPlatformInput.TouchPad",
"UnityStandardAssets.Effects.AfterburnerPhysicsForce",
"UnityStandardAssets.Effects.ExplosionFireAndDebris",
"UnityStandardAssets.Effects.ExplosionPhysicsForce",
"UnityStandardAssets.Effects.Explosive",
"UnityStandardAssets.Effects.ExtinguishableParticleSystem",
"UnityStandardAssets.Effects.FireLight",
"UnityStandardAssets.Effects.Hose",
"UnityStandardAssets.Effects.ParticleSystemMultiplier",
"UnityStandardAssets.Effects.SmokeParticles",
"UnityStandardAssets.Effects.WaterHoseParticles",
"UnityStandardAssets.Utility.ActivateTrigger",
"UnityStandardAssets.Utility.AutoMoveAndRotate",
"UnityStandardAssets.Utility.DragRigidbody",
"UnityStandardAssets.Utility.DynamicShadowSettings",
"UnityStandardAssets.Utility.FollowTarget",
"UnityStandardAssets.Utility.FPSCounter",
"UnityStandardAssets.Utility.ObjectResetter",
"UnityStandardAssets.Utility.ParticleSystemDestroyer",
#if !UNITY_2019_4_OR_NEWER
"UnityStandardAssets.Utility.SimpleActivatorMenu",
#endif
"UnityStandardAssets.Utility.SimpleMouseRotator",
"UnityStandardAssets.Utility.SmoothFollow",
"UnityStandardAssets.Utility.TimedObjectActivator",
"UnityStandardAssets.Utility.TimedObjectDestructor",
"UnityStandardAssets.Utility.WaypointCircuit",
"UnityStandardAssets.Utility.WaypointProgressTracker",
"UnityStandardAssets.Vehicles.Aeroplane.AeroplaneAiControl",
"UnityStandardAssets.Vehicles.Aeroplane.AeroplaneAudio",
"UnityStandardAssets.Vehicles.Aeroplane.AeroplaneController",
"UnityStandardAssets.Vehicles.Aeroplane.AeroplaneControlSurfaceAnimator",
"UnityStandardAssets.Vehicles.Aeroplane.AeroplanePropellerAnimator",
"UnityStandardAssets.Vehicles.Aeroplane.AeroplaneUserControl2Axis",
"UnityStandardAssets.Vehicles.Aeroplane.AeroplaneUserControl4Axis",
"UnityStandardAssets.Vehicles.Aeroplane.JetParticleEffect",
"UnityStandardAssets.Vehicles.Aeroplane.LandingGear",
"UnityStandardAssets.Vehicles.Car.BrakeLight",
"UnityStandardAssets.Vehicles.Car.CarAIControl",
"UnityStandardAssets.Vehicles.Car.CarAudio",
"UnityStandardAssets.Vehicles.Car.CarController",
"UnityStandardAssets.Vehicles.Car.CarSelfRighting",
"UnityStandardAssets.Vehicles.Car.CarUserControl",
"UnityStandardAssets.Vehicles.Car.Mudguard",
"UnityStandardAssets.Vehicles.Car.SkidTrail",
"UnityStandardAssets.Vehicles.Car.Suspension",
"UnityStandardAssets.Vehicles.Car.WheelEffects",
"RenderHeads.Media.AVProVideo.ApplyToMaterial",
"RenderHeads.Media.AVProVideo.ApplyToMesh",
"RenderHeads.Media.AVProVideo.AudioOutput",
"RenderHeads.Media.AVProVideo.CubemapCube",
"RenderHeads.Media.AVProVideo.DebugOverlay",
"RenderHeads.Media.AVProVideo.DisplayBackground",
"RenderHeads.Media.AVProVideo.DisplayIMGUI",
"RenderHeads.Media.AVProVideo.DisplayUGUI",
"RenderHeads.Media.AVProVideo.MediaPlayer",
"RenderHeads.Media.AVProVideo.StreamParser",
"RenderHeads.Media.AVProVideo.SubtitlesUGUI",
"RenderHeads.Media.AVProVideo.UpdateStereoMaterial",
"AlphaButtonClickMask",
"EventSystemChecker",
"VirtualMarketplaceItem",
"SDK2UrlLauncher"
};
static readonly string[] ComponentTypeWhiteListSdk3 = new string[]
{
"VRC.SDK3.VRCDestructibleStandard",
"VRC.SDK3.Components.VRCVisualDamage",
"VRC.SDK3.Components.VRCAvatarPedestal",
"VRC.SDK3.Components.VRCPickup",
"VRC.SDK3.Components.VRCPortalMarker",
"VRC.SDK3.Components.VRCSpatialAudioSource",
"VRC.SDK3.Components.VRCMirrorReflection",
"VRC.SDK3.Components.VRCSceneDescriptor",
"VRC.SDK3.Components.VRCStation",
"VRC.SDK3.Components.VRCUiShape",
"VRC.SDK3.Components.VRCObjectSync",
"VRC.SDK3.Components.VRCObjectPool",
"VRC.SDK3.Video.Components.VRCUnityVideoPlayer",
"VRC.SDK3.Video.Components.AVPro.VRCAVProVideoPlayer",
"VRC.SDK3.Video.Components.AVPro.VRCAVProVideoScreen",
"VRC.SDK3.Video.Components.AVPro.VRCAVProVideoSpeaker",
"VRC.SDK3.Midi.VRCMidiListener",
"VRC.Udon.UdonBehaviour",
"VRC.Udon.AbstractUdonBehaviourEventProxy",
"UnityEngine.Animations.AimConstraint",
"UnityEngine.Animations.LookAtConstraint",
"UnityEngine.Animations.ParentConstraint",
"UnityEngine.Animations.PositionConstraint",
"UnityEngine.Animations.RotationConstraint",
"UnityEngine.Animations.ScaleConstraint",
"UnityEngine.ParticleSystemForceField",
"Cinemachine.Cinemachine3rdPersonAim",
"Cinemachine.CinemachineBlendListCamera",
"Cinemachine.CinemachineBrain",
"Cinemachine.CinemachineCameraOffset",
"Cinemachine.CinemachineClearShot",
"Cinemachine.CinemachineCollider",
"Cinemachine.CinemachineConfiner",
"Cinemachine.CinemachineDollyCart",
"Cinemachine.CinemachineExternalCamera",
"Cinemachine.CinemachineFollowZoom",
"Cinemachine.CinemachineFreeLook",
"Cinemachine.CinemachineMixingCamera",
"Cinemachine.CinemachinePath",
"Cinemachine.CinemachinePipeline",
"Cinemachine.CinemachinePixelPerfect",
"Cinemachine.CinemachineRecomposer",
"Cinemachine.CinemachineSmoothPath",
"Cinemachine.CinemachineStateDrivenCamera",
"Cinemachine.CinemachineStoryboard",
"Cinemachine.CinemachineTargetGroup",
"Cinemachine.CinemachineVirtualCamera",
"Cinemachine.Cinemachine3rdPersonFollow",
"Cinemachine.CinemachineBasicMultiChannelPerlin",
"Cinemachine.CinemachineComposer",
"Cinemachine.CinemachineFramingTransposer",
"Cinemachine.CinemachineGroupComposer",
"Cinemachine.CinemachineHardLockToTarget",
"Cinemachine.CinemachineHardLookAt",
"Cinemachine.CinemachineOrbitalTransposer",
"Cinemachine.CinemachinePOV",
"Cinemachine.CinemachineSameAsFollowTarget",
"Cinemachine.CinemachineTrackedDolly",
"Cinemachine.CinemachineTransposer",
"Cinemachine.CinemachineCore"
};
public static readonly string[] ShaderWhiteList = new string[]
{
"VRChat/Mobile/Standard Lite",
"VRChat/Mobile/Diffuse",
"VRChat/Mobile/Bumped Diffuse",
"VRChat/Mobile/Bumped Mapped Specular",
"VRChat/Mobile/Toon Lit",
"VRChat/Mobile/MatCap Lit",
"VRChat/Mobile/Lightmapped",
"VRChat/Mobile/Skybox",
"VRChat/Mobile/Particles/Additive",
"VRChat/Mobile/Particles/Multiply",
"FX/MirrorReflection",
"UI/Default",
};
private static readonly HashSet<int> scannedObjects = new HashSet<int>();
private static void ConfigureWhiteList(WhiteListConfiguration config)
{
if(ComponentTypeWhiteListConfiguration == config ||
config == WhiteListConfiguration.Unchanged)
{
return;
}
List<string> concatenation = new List<string>();
concatenation.AddRange(ComponentTypeWhiteListCommon);
switch(config)
{
case WhiteListConfiguration.VRCSDK2:
concatenation.AddRange(ComponentTypeWhiteListSdk2);
break;
case WhiteListConfiguration.VRCSDK3:
concatenation.AddRange(ComponentTypeWhiteListSdk3);
break;
}
ComponentTypeWhiteListConfiguration = config;
ComponentTypeWhiteList = concatenation.ToArray();
}
[PublicAPI]
public static void RemoveIllegalComponents(List<GameObject> targets, WhiteListConfiguration config, bool retry = true, HashSet<Type> tagWhitelistedTypes = null)
{
ConfigureWhiteList(config);
HashSet<Type> whitelist = ValidationUtils.WhitelistedTypes($"world{config}", ComponentTypeWhiteList);
// combine whitelist types from world tags with cached whitelist
tagWhitelistedTypes?.UnionWith(whitelist);
foreach (GameObject target in targets)
{
ValidationUtils.RemoveIllegalComponents(target, tagWhitelistedTypes ?? whitelist, retry, true);
SecurityScan(target);
AddScanned(target);
// Must be called after AddScanned to avoid infinite recursion.
ScanDropdownTemplates(target, whitelist, config == WhiteListConfiguration.VRCSDK3);
}
}
private static void AddScanned(GameObject obj)
{
if(obj == null)
return;
if(!scannedObjects.Contains(obj.GetInstanceID()))
scannedObjects.Add(obj.GetInstanceID());
for(int idx = 0; idx < obj.transform.childCount; ++idx)
AddScanned(obj.transform.GetChild(idx)?.gameObject);
}
private static bool WasScanned(GameObject obj)
{
return scannedObjects.Contains(obj.GetInstanceID());
}
[PublicAPI]
public static void ScanGameObject(GameObject target, WhiteListConfiguration config)
{
if(WasScanned(target))
{
return;
}
ConfigureWhiteList(config);
HashSet<Type> whitelist = ValidationUtils.WhitelistedTypes("world" + config, ComponentTypeWhiteList);
ScanGameObject(target, whitelist, config == WhiteListConfiguration.VRCSDK3);
}
private static void ScanGameObject(GameObject target, HashSet<Type> whitelist, bool isSDK3)
{
if (WasScanned(target))
{
return;
}
ValidationUtils.RemoveIllegalComponents(target, whitelist);
SecurityScan(target);
#if VRC_CLIENT && UDON
if (isSDK3)
{
Core.UnityEventFilter.FilterEvents(target);
}
#endif
AddScanned(target);
// Must be called after AddScanned to avoid infinite recursion.
ScanDropdownTemplates(target, whitelist, isSDK3);
}
[PublicAPI]
public static void ClearScannedGameObjectCache()
{
scannedObjects.Clear();
}
[PublicAPI]
public static IEnumerable<Shader> FindIllegalShaders(GameObject target)
{
return ShaderValidation.FindIllegalShaders(target, ShaderWhiteList);
}
private static void SecurityScan(GameObject target)
{
PlayableDirector[] playableDirectors = target.GetComponentsInChildren<PlayableDirector>(true);
foreach(PlayableDirector playableDirector in playableDirectors)
{
StripPlayableDirectorWithPrefabs(playableDirector);
}
}
private static void ScanDropdownTemplates(GameObject target, HashSet<Type> whitelist, bool isSDK3)
{
Dropdown[] dropdowns = target.GetComponentsInChildren<Dropdown>(true);
foreach(Dropdown dropdown in dropdowns)
{
if(dropdown == null)
{
continue;
}
RectTransform dropdownTemplate = dropdown.template;
if(dropdownTemplate == null)
{
continue;
}
ScanGameObject(dropdownTemplate.transform.root.gameObject, whitelist, isSDK3);
}
#if TextMeshPro
TMP_Dropdown[] tmpDropdowns = target.GetComponentsInChildren<TMP_Dropdown>(true);
foreach(TMP_Dropdown textMeshProDropdown in tmpDropdowns)
{
if(textMeshProDropdown == null)
{
continue;
}
RectTransform dropdownTemplate = textMeshProDropdown.template;
if(dropdownTemplate == null)
{
continue;
}
ScanGameObject(dropdownTemplate.transform.root.gameObject, whitelist, isSDK3);
}
#endif
}
private static void StripPlayableDirectorWithPrefabs(PlayableDirector playableDirector)
{
if(!(playableDirector.playableAsset is UnityEngine.Timeline.TimelineAsset timelineAsset))
return;
IEnumerable<TrackAsset> tracks = timelineAsset.GetOutputTracks();
foreach(TrackAsset track in tracks)
{
if(!(track is ControlTrack))
continue;
IEnumerable<TimelineClip> clips = track.GetClips();
foreach(TimelineClip clip in clips)
{
if(clip.asset is ControlPlayableAsset controlPlayableAsset && controlPlayableAsset.prefabGameObject != null)
{
UnityEngine.Object.Destroy(playableDirector);
VRC.Core.Logger.LogWarning("PlayableDirector containing prefab removed", DebugLevel, playableDirector.gameObject);
}
}
}
}
}
}