using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; using UwaProjScan.Tools; using UwaProjScan.Submodules.Shader_Analysis.Build; using System.IO; #if UNITY_2018_2_OR_NEWER using UnityEditor.Build; using UnityEditor.Build.Reporting; using UnityEditor.Build.Player; using UnityEditor.Rendering; #endif #if UNITY_2017_3_OR_NEWER using UnityEditor.Compilation; #endif namespace UwaProjScan { class ApiCompatibilityImp : ICompatApi { public static readonly ApiCompatibilityImp Instance = new ApiCompatibilityImp(); public ApiCompatibilityImp() { #if UNITY_2017_2_OR_NEWER EditorApplication.playModeStateChanged += EditorApplication_playmodeStateChanged; #else EditorApplication.playmodeStateChanged += EditorApplication_playmodeStateChanged; #endif } private Action _exitplaymodecb = null; private Action _pausemodecb = null; public Action> _onProcessShader = null; private bool _lastPauseState = false; #if UNITY_2017_2_OR_NEWER public void EditorApplication_playmodeStateChanged(PlayModeStateChange p) #else public void EditorApplication_playmodeStateChanged() #endif { if (EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode) { if (_exitplaymodecb != null) _exitplaymodecb(); } // invoke only when isPaused changed if (_lastPauseState != EditorApplication.isPaused) { if (_pausemodecb != null) _pausemodecb(EditorApplication.isPaused); } _lastPauseState = EditorApplication.isPaused; } #region interface imp public void RegisterEditorExitPlayMode(Action cb) { _exitplaymodecb += cb; } public void RegisterEditorPauseMode(Action cb) { _pausemodecb += cb; } public void RegisterProcessShader(Action> onProcessShaderInternal) { _onProcessShader += onProcessShaderInternal; } public void Reset() { _exitplaymodecb = null; _pausemodecb = null; _onProcessShader = null; } public void UPS_BuildPlayer(string[] scenesInBuild) { #if UNITY_2018_2_OR_NEWER BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.scenes = scenesInBuild; buildPlayerOptions.target = EditorUserBuildSettings.activeBuildTarget; switch (EditorUserBuildSettings.activeBuildTarget) { case BuildTarget.StandaloneWindows: case BuildTarget.StandaloneWindows64: buildPlayerOptions.locationPathName = "./UWAScan_SA_BuildTest_Standalone/UWAScan_SA_BuildTest.exe"; break; case BuildTarget.Android: buildPlayerOptions.locationPathName = "./UWAScan_SA_BuildTest_Android"; break; case BuildTarget.iOS: buildPlayerOptions.locationPathName = "./UWAScan_SA_BuildTest_iOS"; break; default: buildPlayerOptions.locationPathName = "./UWAScan_SA_Build_Test"; break; } buildPlayerOptions.options = BuildOptions.None; BuildPipeline.BuildPlayer(buildPlayerOptions); #endif } public string[] GetAssemblyPaths() { List list = new List(); #if UNITY_2017_3_OR_NEWER #if UNITY_2019_3_OR_NEWER var assemblies = CompilationPipeline.GetAssemblies(AssembliesType.PlayerWithoutTestAssemblies); #elif UNITY_2018_1_OR_NEWER var assemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player); #elif UNITY_2017_3_OR_NEWER var assemblies = CompilationPipeline.GetAssemblies(); #endif foreach(var asm in assemblies) { list.Add(asm.outputPath); } #endif return list.ToArray(); } public string GetAssemblyDefinitionFilePath(string asmName) { string dfPath = null; #if UNITY_2017_3_OR_NEWER dfPath = CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(asmName); #endif return dfPath; } public string[] CompileAssemblies(string folder) { #if UNITY_2018_2_OR_NEWER var input = new ScriptCompilationSettings { target = EditorUserBuildSettings.activeBuildTarget, group = EditorUserBuildSettings.selectedBuildTargetGroup }; List paths = new List(); var compilationResult = PlayerBuildInterface.CompilePlayerScripts(input, folder); foreach(var asm in compilationResult.assemblies) { paths.Add(System.IO.Path.Combine(folder, asm)); } return paths.ToArray(); #else return null; #endif } #endregion public string[] GetEnvironmentVariables() { List dirs = new List(); List assemblyPaths = new List(); #if UNITY_2019_1_OR_NEWER assemblyPaths.AddRange(CompilationPipeline.GetPrecompiledAssemblyPaths(CompilationPipeline.PrecompiledAssemblySources .UserAssembly)); assemblyPaths.AddRange(CompilationPipeline.GetPrecompiledAssemblyPaths(CompilationPipeline.PrecompiledAssemblySources .UnityEngine)); #elif UNITY_2018_4_OR_NEWER assemblyPaths.AddRange(CompilationPipeline.GetPrecompiledAssemblyNames() .Select(a => CompilationPipeline.GetPrecompiledAssemblyPathFromAssemblyName(a))); #endif #if UNITY_5_6 assemblyPaths.AddRange(Directory.GetFiles(Path.Combine(EditorApplication.applicationContentsPath, "Managed")).Where(path => Path.GetExtension(path).Equals(".dll"))); #else assemblyPaths.AddRange(Directory.GetFiles(Path.Combine(EditorApplication.applicationContentsPath, Path.Combine("Managed", "UnityEngine"))).Where(path => Path.GetExtension(path).Equals(".dll"))); #endif #if !UNITY_2019_2_OR_NEWER var files = Directory.GetFiles(Path.Combine(EditorApplication.applicationContentsPath, Path.Combine( "UnityExtensions", Path.Combine("Unity", "GUISystem")))); assemblyPaths.AddRange(files.Where(path => Path.GetExtension(path).Equals(".dll"))); #endif foreach (var dir in assemblyPaths.Select(path => Path.GetDirectoryName(path.Replace("\\", "/"))).Distinct()) { dirs.Add(dir); } return dirs.ToArray(); } public bool CheckStrippingManagedCode() { #if UNITY_2018_3_OR_NEWER ManagedStrippingLevel androidLevel = PlayerSettings.GetManagedStrippingLevel(BuildTargetGroup.Android); ManagedStrippingLevel iosLevel = PlayerSettings.GetManagedStrippingLevel(BuildTargetGroup.iOS); if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android) { if (androidLevel == ManagedStrippingLevel.Disabled || androidLevel == ManagedStrippingLevel.Low) return false; } else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS) { if (iosLevel == ManagedStrippingLevel.Low) return false; } return true; #else if (PlayerSettings.strippingLevel == StrippingLevel.Disabled) return false; else return true; #endif } } #if UNITY_2018_2_OR_NEWER class UPS_SA_BuildProcessor : IPreprocessShaders { public int callbackOrder { get { return 100; } } public void OnProcessShader( Shader shader, ShaderSnippetData snippet, IList shaderCompilerDatas) { if (!ApiCompatibilityUtils.UwaShaderProcessorOn) return; UPS_SSD u_snippet = new UPS_SSD(); u_snippet.shaderType = (UPS_SSD.UPS_ShaderType)Enum.Parse(typeof(UPS_SSD.UPS_ShaderType), snippet.shaderType.ToString()); List u_SCDs = new List(); for (int i = 0; i < shaderCompilerDatas.Count; ++i) { ShaderKeywordSet ks = shaderCompilerDatas[i].shaderKeywordSet; UPS_SCD u_SCD = new UPS_SCD(); foreach (ShaderKeyword kw in ks.GetShaderKeywords()) { string kname; #if UNITY_2019_3_OR_NEWER kname = ShaderKeyword.GetKeywordName(shader, kw); #elif UNITY_2018_3_OR_NEWER kname = kw.GetKeywordName(); #else kname = kw.GetName(); #endif u_SCD.shaderKeywordSet.Add(kname); } u_SCDs.Add(u_SCD); } ApiCompatibilityImp.Instance._onProcessShader.Invoke(shader, u_snippet, u_SCDs); shaderCompilerDatas.Clear(); } } #endif }