mirror of
				https://github.com/DerTyp7/defrain-shooter-unity.git
				synced 2025-10-31 21:47:07 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			190 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| // for Unity 2020+ we use ILPostProcessor.
 | |
| // only automatically invoke it for older versions.
 | |
| #if !UNITY_2020_3_OR_NEWER
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.IO;
 | |
| using System.Linq;
 | |
| using Mono.CecilX;
 | |
| using UnityEditor;
 | |
| using UnityEditor.Compilation;
 | |
| using UnityEngine;
 | |
| using UnityAssembly = UnityEditor.Compilation.Assembly;
 | |
| 
 | |
| namespace Mirror.Weaver
 | |
| {
 | |
|     public static class CompilationFinishedHook
 | |
|     {
 | |
|         // needs to be the same as Weaver.MirrorAssemblyName!
 | |
|         const string MirrorRuntimeAssemblyName = "Mirror";
 | |
|         const string MirrorWeaverAssemblyName = "Mirror.Weaver";
 | |
| 
 | |
|         // global weaver define so that tests can use it
 | |
|         internal static Weaver weaver;
 | |
| 
 | |
|         // delegate for subscription to Weaver warning messages
 | |
|         public static Action<string> OnWeaverWarning;
 | |
|         // delete for subscription to Weaver error messages
 | |
|         public static Action<string> OnWeaverError;
 | |
| 
 | |
|         // controls weather Weaver errors are reported direct to the Unity console (tests enable this)
 | |
|         public static bool UnityLogEnabled = true;
 | |
| 
 | |
|         [InitializeOnLoadMethod]
 | |
|         public static void OnInitializeOnLoad()
 | |
|         {
 | |
|             CompilationPipeline.assemblyCompilationFinished += OnCompilationFinished;
 | |
| 
 | |
|             // We only need to run this once per session
 | |
|             // after that, all assemblies will be weaved by the event
 | |
|             if (!SessionState.GetBool("MIRROR_WEAVED", false))
 | |
|             {
 | |
|                 // reset session flag
 | |
|                 SessionState.SetBool("MIRROR_WEAVED", true);
 | |
|                 SessionState.SetBool("MIRROR_WEAVE_SUCCESS", true);
 | |
| 
 | |
|                 WeaveExistingAssemblies();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static void WeaveExistingAssemblies()
 | |
|         {
 | |
|             foreach (UnityAssembly assembly in CompilationPipeline.GetAssemblies())
 | |
|             {
 | |
|                 if (File.Exists(assembly.outputPath))
 | |
|                 {
 | |
|                     OnCompilationFinished(assembly.outputPath, new CompilerMessage[0]);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
| #if UNITY_2019_3_OR_NEWER
 | |
|             EditorUtility.RequestScriptReload();
 | |
| #else
 | |
|             UnityEditorInternal.InternalEditorUtility.RequestScriptReload();
 | |
| #endif
 | |
|         }
 | |
| 
 | |
|         static Assembly FindCompilationPipelineAssembly(string assemblyName) =>
 | |
|             CompilationPipeline.GetAssemblies().First(assembly => assembly.name == assemblyName);
 | |
| 
 | |
|         static bool CompilerMessagesContainError(CompilerMessage[] messages) =>
 | |
|             messages.Any(msg => msg.type == CompilerMessageType.Error);
 | |
| 
 | |
|         public static void OnCompilationFinished(string assemblyPath, CompilerMessage[] messages)
 | |
|         {
 | |
|             // Do nothing if there were compile errors on the target
 | |
|             if (CompilerMessagesContainError(messages))
 | |
|             {
 | |
|                 Debug.Log("Weaver: stop because compile errors on target");
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             // Should not run on the editor only assemblies
 | |
|             if (assemblyPath.Contains("-Editor") || assemblyPath.Contains(".Editor"))
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             // don't weave mirror files
 | |
|             string assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
 | |
|             if (assemblyName == MirrorRuntimeAssemblyName || assemblyName == MirrorWeaverAssemblyName)
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             // find Mirror.dll
 | |
|             Assembly mirrorAssembly = FindCompilationPipelineAssembly(MirrorRuntimeAssemblyName);
 | |
|             if (mirrorAssembly == null)
 | |
|             {
 | |
|                 Debug.LogError("Failed to find Mirror runtime assembly");
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             string mirrorRuntimeDll = mirrorAssembly.outputPath;
 | |
|             if (!File.Exists(mirrorRuntimeDll))
 | |
|             {
 | |
|                 // this is normal, it happens with any assembly that is built before mirror
 | |
|                 // such as unity packages or your own assemblies
 | |
|                 // those don't need to be weaved
 | |
|                 // if any assembly depends on mirror, then it will be built after
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             // find UnityEngine.CoreModule.dll
 | |
|             string unityEngineCoreModuleDLL = UnityEditorInternal.InternalEditorUtility.GetEngineCoreModuleAssemblyPath();
 | |
|             if (string.IsNullOrEmpty(unityEngineCoreModuleDLL))
 | |
|             {
 | |
|                 Debug.LogError("Failed to find UnityEngine assembly");
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             HashSet<string> dependencyPaths = GetDependencyPaths(assemblyPath);
 | |
|             dependencyPaths.Add(Path.GetDirectoryName(mirrorRuntimeDll));
 | |
|             dependencyPaths.Add(Path.GetDirectoryName(unityEngineCoreModuleDLL));
 | |
| 
 | |
|             if (!WeaveFromFile(assemblyPath, dependencyPaths.ToArray()))
 | |
|             {
 | |
|                 // Set false...will be checked in \Editor\EnterPlayModeSettingsCheck.CheckSuccessfulWeave()
 | |
|                 SessionState.SetBool("MIRROR_WEAVE_SUCCESS", false);
 | |
|                 if (UnityLogEnabled) Debug.LogError($"Weaving failed for {assemblyPath}");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static HashSet<string> GetDependencyPaths(string assemblyPath)
 | |
|         {
 | |
|             // build directory list for later asm/symbol resolving using CompilationPipeline refs
 | |
|             HashSet<string> dependencyPaths = new HashSet<string>
 | |
|             {
 | |
|                 Path.GetDirectoryName(assemblyPath)
 | |
|             };
 | |
|             foreach (Assembly assembly in CompilationPipeline.GetAssemblies())
 | |
|             {
 | |
|                 if (assembly.outputPath == assemblyPath)
 | |
|                 {
 | |
|                     foreach (string reference in assembly.compiledAssemblyReferences)
 | |
|                     {
 | |
|                         dependencyPaths.Add(Path.GetDirectoryName(reference));
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return dependencyPaths;
 | |
|         }
 | |
|         // helper function to invoke Weaver with an AssemblyDefinition from a
 | |
|         // file path, with dependencies added.
 | |
|         static bool WeaveFromFile(string assemblyPath, string[] dependencies)
 | |
|         {
 | |
|             // resolve assembly from stream
 | |
|             using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver())
 | |
|             using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters{ ReadWrite = true, ReadSymbols = true, AssemblyResolver = asmResolver }))
 | |
|             {
 | |
|                 // add this assembly's path and unity's assembly path
 | |
|                 asmResolver.AddSearchDirectory(Path.GetDirectoryName(assemblyPath));
 | |
|                 asmResolver.AddSearchDirectory(Helpers.UnityEngineDllDirectoryName());
 | |
| 
 | |
|                 // add dependencies
 | |
|                 if (dependencies != null)
 | |
|                 {
 | |
|                     foreach (string path in dependencies)
 | |
|                     {
 | |
|                         asmResolver.AddSearchDirectory(path);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 // create weaver with logger
 | |
|                 weaver = new Weaver(new CompilationFinishedLogger());
 | |
|                 if (weaver.Weave(assembly, asmResolver, out bool modified))
 | |
|                 {
 | |
|                     // write changes to file if modified
 | |
|                     if (modified)
 | |
|                         assembly.Write(new WriterParameters{WriteSymbols = true});
 | |
| 
 | |
|                     return true;
 | |
|                 }
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| #endif
 | 
