Fix RegisterSyncField(Type, string) preserving caller targetType#2
Closed
Fix RegisterSyncField(Type, string) preserving caller targetType#2
Conversation
AccessTools.Field walks the inheritance chain, so the returned FieldInfo.ReflectedType collapses to the base type that declared the field. Routing the (Type, string) overload through RegisterSyncField( FieldInfo) silently discarded the caller's concrete Type, causing SyncField to store the base targetType and breaking SyncWorker lookups registered on the concrete subclass (rwmt#880). Keep the caller's Type for the instance path; use the FieldInfo only for existence validation and the static branch. Collapse the RegisterSyncField(FieldInfo) overload into a one-line delegate through (field.ReflectedType, field.Name), preserving its prior behavior.
fae36e9 to
75bd450
Compare
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MP.RegisterSyncField(Type, string)routed throughRegisterSyncField(FieldInfo), which keyed everything offFieldInfo.ReflectedType.AccessTools.Fieldwalks the inheritance chain, so for a private field declared on a base class the ReflectedType collapses to the base — silently discarding the concreteTypethe compat caller passed in.SyncFieldstored that basetargetTypeandDoSyncserializedtargetas the base, so SyncWorkers registered on the concrete subclass stopped matching. This is Registering sync field thhrough API doesn't allow for specifying the exact type of the target rwmt/Multiplayer#880 and is why the VGE oxygen gizmo compat patch currently needs a reflectionSetValuehack ontargetType.(Type, string)overload, look up theFieldInfoonly for validation and the static branch, but pass the caller'stargetTypethrough toSync.Fieldand thememberPathkey.RegisterSyncField(FieldInfo)behavior is unchanged.Test plan
dotnet build Source/Client/Multiplayer.csproj -c Release— 0 errorsSetValuehack is removed in a follow-upRegisterSyncField(Type, string)where caller Type == declaring type (no behavior change expected)