diff --git a/Assets/Mirror/Editor/Weaver/Processors/ReaderWriterProcessor.cs b/Assets/Mirror/Editor/Weaver/Processors/ReaderWriterProcessor.cs index 58a19d893..88543e0be 100644 --- a/Assets/Mirror/Editor/Weaver/Processors/ReaderWriterProcessor.cs +++ b/Assets/Mirror/Editor/Weaver/Processors/ReaderWriterProcessor.cs @@ -22,19 +22,47 @@ public static bool Process(AssemblyDefinition CurrentAssembly, IAssemblyResolver // fixes: https://github.com/MirrorNetworking/Mirror/issues/2503 // // find NetworkReader/Writer extensions in referenced assemblies - // save a copy of the collection enumerator since it appears to be modified at some point during iteration - IEnumerable assemblyReferences = CurrentAssembly.MainModule.AssemblyReferences.ToList(); - foreach (AssemblyNameReference assemblyNameReference in assemblyReferences) + IEnumerable assemblyReferences = FindProcessTargetAssemblies(CurrentAssembly, resolver) + .Where(assembly => assembly != null && assembly != CurrentAssembly); + + foreach (AssemblyDefinition referencedAssembly in assemblyReferences) + ProcessAssemblyClasses(CurrentAssembly, referencedAssembly, writers, readers, ref WeavingFailed); + + return ProcessAssemblyClasses(CurrentAssembly, CurrentAssembly, writers, readers, ref WeavingFailed); + } + + static List FindProcessTargetAssemblies(AssemblyDefinition assembly, IAssemblyResolver resolver) + { + HashSet processedAssemblies = new HashSet(); + List assemblies = new List(); + + ProcessAssembly(assembly); + + return assemblies; + + void ProcessAssembly(AssemblyDefinition current) { - AssemblyDefinition referencedAssembly = resolver.Resolve(assemblyNameReference); - if (referencedAssembly != null) + // If the assembly has already been processed, we skip it + if (current.FullName == Weaver.MirrorAssemblyName || !processedAssemblies.Add(current.FullName)) + return; + + IEnumerable references = current.MainModule.AssemblyReferences; + + // If there is no Mirror reference, there will be no ReaderWriter or NetworkMessage, so skip + if (references.All(reference => reference.Name != Weaver.MirrorAssemblyName)) + return; + + // Add the assembly to the processed set and list + assemblies.Add(current); + + // Process the references of the current assembly + foreach (AssemblyNameReference reference in references) { - ProcessAssemblyClasses(CurrentAssembly, referencedAssembly, writers, readers, ref WeavingFailed); + AssemblyDefinition referencedAssembly = resolver.Resolve(reference); + if (referencedAssembly != null) + ProcessAssembly(referencedAssembly); } } - - // find readers/writers in the assembly we are in right now. - return ProcessAssemblyClasses(CurrentAssembly, CurrentAssembly, writers, readers, ref WeavingFailed); } static void ProcessMirrorAssemblyClasses(AssemblyDefinition CurrentAssembly, IAssemblyResolver resolver, Logger Log, Writers writers, Readers readers, ref bool WeavingFailed)