mirror of
				https://github.com/DerTyp7/defrain-shooter-unity.git
				synced 2025-10-31 05:27:07 +01:00 
			
		
		
		
	CHANGED TO MIRROR
This commit is contained in:
		
							
								
								
									
										214
									
								
								Assets/Mirror/Editor/Weaver/Weaver.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								Assets/Mirror/Editor/Weaver/Weaver.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,214 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using Mono.CecilX; | ||||
|  | ||||
| namespace Mirror.Weaver | ||||
| { | ||||
|     // not static, because ILPostProcessor is multithreaded | ||||
|     internal class Weaver | ||||
|     { | ||||
|         public const string InvokeRpcPrefix = "InvokeUserCode_"; | ||||
|  | ||||
|         // generated code class | ||||
|         public const string GeneratedCodeNamespace = "Mirror"; | ||||
|         public const string GeneratedCodeClassName = "GeneratedNetworkCode"; | ||||
|         TypeDefinition GeneratedCodeClass; | ||||
|  | ||||
|         // for resolving Mirror.dll in ReaderWriterProcessor, we need to know | ||||
|         // Mirror.dll name | ||||
|         public const string MirrorAssemblyName = "Mirror"; | ||||
|  | ||||
|         WeaverTypes weaverTypes; | ||||
|         SyncVarAccessLists syncVarAccessLists; | ||||
|         IAssemblyResolver Resolver; | ||||
|         AssemblyDefinition CurrentAssembly; | ||||
|         Writers writers; | ||||
|         Readers readers; | ||||
|         bool WeavingFailed; | ||||
|  | ||||
|         // logger functions can be set from the outside. | ||||
|         // for example, Debug.Log or ILPostProcessor Diagnostics log for | ||||
|         // multi threaded logging. | ||||
|         public Logger Log; | ||||
|  | ||||
|         public Weaver(Logger Log) | ||||
|         { | ||||
|             this.Log = Log; | ||||
|         } | ||||
|  | ||||
|         // returns 'true' if modified (=if we did anything) | ||||
|         bool WeaveNetworkBehavior(TypeDefinition td) | ||||
|         { | ||||
|             if (!td.IsClass) | ||||
|                 return false; | ||||
|  | ||||
|             if (!td.IsDerivedFrom<NetworkBehaviour>()) | ||||
|             { | ||||
|                 if (td.IsDerivedFrom<UnityEngine.MonoBehaviour>()) | ||||
|                     MonoBehaviourProcessor.Process(Log, td, ref WeavingFailed); | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // process this and base classes from parent to child order | ||||
|  | ||||
|             List<TypeDefinition> behaviourClasses = new List<TypeDefinition>(); | ||||
|  | ||||
|             TypeDefinition parent = td; | ||||
|             while (parent != null) | ||||
|             { | ||||
|                 if (parent.Is<NetworkBehaviour>()) | ||||
|                 { | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 try | ||||
|                 { | ||||
|                     behaviourClasses.Insert(0, parent); | ||||
|                     parent = parent.BaseType.Resolve(); | ||||
|                 } | ||||
|                 catch (AssemblyResolutionException) | ||||
|                 { | ||||
|                     // this can happen for plugins. | ||||
|                     //Console.WriteLine("AssemblyResolutionException: "+ ex.ToString()); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             bool modified = false; | ||||
|             foreach (TypeDefinition behaviour in behaviourClasses) | ||||
|             { | ||||
|                 modified |= new NetworkBehaviourProcessor(CurrentAssembly, weaverTypes, syncVarAccessLists, writers, readers, Log, behaviour).Process(ref WeavingFailed); | ||||
|             } | ||||
|             return modified; | ||||
|         } | ||||
|  | ||||
|         bool WeaveModule(ModuleDefinition moduleDefinition) | ||||
|         { | ||||
|             bool modified = false; | ||||
|  | ||||
|             Stopwatch watch = Stopwatch.StartNew(); | ||||
|             watch.Start(); | ||||
|  | ||||
|             foreach (TypeDefinition td in moduleDefinition.Types) | ||||
|             { | ||||
|                 if (td.IsClass && td.BaseType.CanBeResolved()) | ||||
|                 { | ||||
|                     modified |= WeaveNetworkBehavior(td); | ||||
|                     modified |= ServerClientAttributeProcessor.Process(weaverTypes, Log, td, ref WeavingFailed); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             watch.Stop(); | ||||
|             Console.WriteLine($"Weave behaviours and messages took {watch.ElapsedMilliseconds} milliseconds"); | ||||
|  | ||||
|             return modified; | ||||
|         } | ||||
|  | ||||
|         void CreateGeneratedCodeClass() | ||||
|         { | ||||
|             // create "Mirror.GeneratedNetworkCode" class which holds all | ||||
|             // Readers<T> and Writers<T> | ||||
|             GeneratedCodeClass = new TypeDefinition(GeneratedCodeNamespace, GeneratedCodeClassName, | ||||
|                 TypeAttributes.BeforeFieldInit | TypeAttributes.Class | TypeAttributes.AnsiClass | TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.Abstract | TypeAttributes.Sealed, | ||||
|                 weaverTypes.Import<object>()); | ||||
|         } | ||||
|  | ||||
|         // Weave takes an AssemblyDefinition to be compatible with both old and | ||||
|         // new weavers: | ||||
|         // * old takes a filepath, new takes a in-memory byte[] | ||||
|         // * old uses DefaultAssemblyResolver with added dependencies paths, | ||||
|         //   new uses ...? | ||||
|         // | ||||
|         // => assembly: the one we are currently weaving (MyGame.dll) | ||||
|         // => resolver: useful in case we need to resolve any of the assembly's | ||||
|         //              assembly.MainModule.AssemblyReferences. | ||||
|         //              -> we can resolve ANY of them given that the resolver | ||||
|         //                 works properly (need custom one for ILPostProcessor) | ||||
|         //              -> IMPORTANT: .Resolve() takes an AssemblyNameReference. | ||||
|         //                 those from assembly.MainModule.AssemblyReferences are | ||||
|         //                 guaranteed to be resolve-able. | ||||
|         //                 Parsing from a string for Library/.../Mirror.dll | ||||
|         //                 would not be guaranteed to be resolve-able because | ||||
|         //                 for ILPostProcessor we can't assume where Mirror.dll | ||||
|         //                 is etc. | ||||
|         public bool Weave(AssemblyDefinition assembly, IAssemblyResolver resolver, out bool modified) | ||||
|         { | ||||
|             WeavingFailed = false; | ||||
|             modified = false; | ||||
|             try | ||||
|             { | ||||
|                 Resolver = resolver; | ||||
|                 CurrentAssembly = assembly; | ||||
|  | ||||
|                 // fix "No writer found for ..." error | ||||
|                 // https://github.com/vis2k/Mirror/issues/2579 | ||||
|                 // -> when restarting Unity, weaver would try to weave a DLL | ||||
|                 //    again | ||||
|                 // -> resulting in two GeneratedNetworkCode classes (see ILSpy) | ||||
|                 // -> the second one wouldn't have all the writer types setup | ||||
|                 if (CurrentAssembly.MainModule.ContainsClass(GeneratedCodeNamespace, GeneratedCodeClassName)) | ||||
|                 { | ||||
|                     //Log.Warning($"Weaver: skipping {CurrentAssembly.Name} because already weaved"); | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 weaverTypes = new WeaverTypes(CurrentAssembly, Log, ref WeavingFailed); | ||||
|  | ||||
|                 // weaverTypes are needed for CreateGeneratedCodeClass | ||||
|                 CreateGeneratedCodeClass(); | ||||
|  | ||||
|                 // WeaverList depends on WeaverTypes setup because it uses Import | ||||
|                 syncVarAccessLists = new SyncVarAccessLists(); | ||||
|  | ||||
|                 // initialize readers & writers with this assembly. | ||||
|                 // we need to do this in every Process() call. | ||||
|                 // otherwise we would get | ||||
|                 // "System.ArgumentException: Member ... is declared in another module and needs to be imported" | ||||
|                 // errors when still using the previous module's reader/writer funcs. | ||||
|                 writers = new Writers(CurrentAssembly, weaverTypes, GeneratedCodeClass, Log); | ||||
|                 readers = new Readers(CurrentAssembly, weaverTypes, GeneratedCodeClass, Log); | ||||
|  | ||||
|                 Stopwatch rwstopwatch = Stopwatch.StartNew(); | ||||
|                 // Need to track modified from ReaderWriterProcessor too because it could find custom read/write functions or create functions for NetworkMessages | ||||
|                 modified = ReaderWriterProcessor.Process(CurrentAssembly, resolver, Log, writers, readers, ref WeavingFailed); | ||||
|                 rwstopwatch.Stop(); | ||||
|                 Console.WriteLine($"Find all reader and writers took {rwstopwatch.ElapsedMilliseconds} milliseconds"); | ||||
|  | ||||
|                 ModuleDefinition moduleDefinition = CurrentAssembly.MainModule; | ||||
|                 Console.WriteLine($"Script Module: {moduleDefinition.Name}"); | ||||
|  | ||||
|                 modified |= WeaveModule(moduleDefinition); | ||||
|  | ||||
|                 if (WeavingFailed) | ||||
|                 { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 if (modified) | ||||
|                 { | ||||
|                     SyncVarAttributeAccessReplacer.Process(moduleDefinition, syncVarAccessLists); | ||||
|  | ||||
|                     // add class that holds read/write functions | ||||
|                     moduleDefinition.Types.Add(GeneratedCodeClass); | ||||
|  | ||||
|                     ReaderWriterProcessor.InitializeReaderAndWriters(CurrentAssembly, weaverTypes, writers, readers, GeneratedCodeClass); | ||||
|  | ||||
|                     // DO NOT WRITE here. | ||||
|                     // CompilationFinishedHook writes to the file. | ||||
|                     // ILPostProcessor writes to in-memory assembly. | ||||
|                     // it depends on the caller. | ||||
|                     //CurrentAssembly.Write(new WriterParameters{ WriteSymbols = true }); | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 Log.Error($"Exception :{e}"); | ||||
|                 WeavingFailed = true; | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 DerTyp187
					DerTyp187