fix(ReaderWriterProcessor) : When crossing assemblies problem (#3864)

* fix(ReaderWriterProcessor)

Recursively handle the Network Reader/Writer required by CurrentAssembly.AssemblyReferences.

* Remove brackets to one line statement.

#3864 suggestion
This commit is contained in:
pepoipod 2024-10-07 18:26:55 +09:00 committed by GitHub
parent f42eed3b16
commit cdc58fdba9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -22,19 +22,47 @@ public static bool Process(AssemblyDefinition CurrentAssembly, IAssemblyResolver
// fixes: https://github.com/MirrorNetworking/Mirror/issues/2503 // fixes: https://github.com/MirrorNetworking/Mirror/issues/2503
// //
// find NetworkReader/Writer extensions in referenced assemblies // 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<AssemblyDefinition> assemblyReferences = FindProcessTargetAssemblies(CurrentAssembly, resolver)
IEnumerable<AssemblyNameReference> assemblyReferences = CurrentAssembly.MainModule.AssemblyReferences.ToList(); .Where(assembly => assembly != null && assembly != CurrentAssembly);
foreach (AssemblyNameReference assemblyNameReference in assemblyReferences)
foreach (AssemblyDefinition referencedAssembly in assemblyReferences)
ProcessAssemblyClasses(CurrentAssembly, referencedAssembly, writers, readers, ref WeavingFailed);
return ProcessAssemblyClasses(CurrentAssembly, CurrentAssembly, writers, readers, ref WeavingFailed);
}
static List<AssemblyDefinition> FindProcessTargetAssemblies(AssemblyDefinition assembly, IAssemblyResolver resolver)
{
HashSet<string> processedAssemblies = new HashSet<string>();
List<AssemblyDefinition> assemblies = new List<AssemblyDefinition>();
ProcessAssembly(assembly);
return assemblies;
void ProcessAssembly(AssemblyDefinition current)
{ {
AssemblyDefinition referencedAssembly = resolver.Resolve(assemblyNameReference); // If the assembly has already been processed, we skip it
if (referencedAssembly != null) if (current.FullName == Weaver.MirrorAssemblyName || !processedAssemblies.Add(current.FullName))
return;
IEnumerable<AssemblyNameReference> 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) static void ProcessMirrorAssemblyClasses(AssemblyDefinition CurrentAssembly, IAssemblyResolver resolver, Logger Log, Writers writers, Readers readers, ref bool WeavingFailed)