Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Fixed

- Issue where the IL post-processor could not resolve core library types, such as `Guid` and `List<T>`, in assemblies compiled against .NET reference assemblies, for example when targeting .NET 10. Those split the core library across `System.Runtime`, `System.Collections` and other assemblies.
- Fixed issue where a prefab added to a `NetworkPrefabsList` while a session was running was registered more than once and logged a duplicate `GlobalObjectIdHash` error. (#4184)
- Issue where moving a `NetworkObject` into another scene made the clients that did not observe it log "Trying to synchronize NetworkObjectId but it was not spawned". The scene migration is now only sent to the clients that observe the `NetworkObject`. (#4176)
- Issue where a `NetworkObject` that was moved into another scene while hidden from a client spawned in that client's active scene when it was shown with `NetworkShow`, instead of the scene it is in on the server. (#4176)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Mono.Cecil;
Expand All @@ -8,15 +10,74 @@ internal class PostProcessorReflectionImporter : DefaultReflectionImporter
{
private const string k_SystemPrivateCoreLib = "System.Private.CoreLib";
private readonly AssemblyNameReference m_CorrectCorlib;
private readonly Dictionary<string, AssemblyNameReference> m_CorlibTypeScopes = new Dictionary<string, AssemblyNameReference>();

public PostProcessorReflectionImporter(ModuleDefinition module) : base(module)
{
m_CorrectCorlib = module.AssemblyReferences.FirstOrDefault(a => a.Name == "mscorlib" || a.Name == "netstandard" || a.Name == k_SystemPrivateCoreLib);
}

// .NET reference packs split System.Private.CoreLib across System.Runtime, System.Collections and others,
// so a module that references none of the assemblies above needs the one that defines or forwards the type.
protected override IMetadataScope ImportScope(Type type)
{
if (m_CorrectCorlib == null && type.Assembly.GetName().Name == k_SystemPrivateCoreLib)
{
var outermost = type;
while (outermost.DeclaringType != null)
{
outermost = outermost.DeclaringType;
}

var reference = FindReferenceDefining(outermost.FullName);
if (reference != null)
{
return reference;
}
}

return base.ImportScope(type);
}

public override AssemblyNameReference ImportReference(AssemblyName reference)
{
return m_CorrectCorlib != null && reference.Name == k_SystemPrivateCoreLib ? m_CorrectCorlib : base.ImportReference(reference);
}

private AssemblyNameReference FindReferenceDefining(string fullName)
{
if (m_CorlibTypeScopes.TryGetValue(fullName, out var cached))
{
return cached;
}

AssemblyNameReference found = null;
foreach (var reference in module.AssemblyReferences)
{
AssemblyDefinition assembly;
try
{
assembly = module.AssemblyResolver.Resolve(reference);
}
catch (AssemblyResolutionException)
{
continue;
}

if (assembly == null)
{
continue;
}

if (assembly.MainModule.GetType(fullName) != null || assembly.MainModule.ExportedTypes.Any(t => t.FullName == fullName))
{
found = reference;
break;
}
}

m_CorlibTypeScopes[fullName] = found;
return found;
}
}
}
Loading