private void ExtractMembers() { if (Members == null) { Members = new List <MemberInfo>(); DataConverters = new List <IMDDataConverter>(); List <MemberInfo> MemberInfos = typeof(T).GetMemberInfos(); foreach (MemberInfo Member in MemberInfos) { MDReplicated RepAttribute = Member.GetCustomAttribute(typeof(MDReplicated)) as MDReplicated; if (RepAttribute == null) { continue; } Members.Add(Member); DataConverters.Add(MDStatics.GetConverterForType(Member.GetUnderlyingType())); } } }
/// <summary> /// Can be overwritten to provide custom replication types /// </summary> /// <param name="Member">The member info to create a replicated member for</param> /// <param name="RepAttribute">The replication reliability we want</param> /// <param name="Instance">The node this member is on</param> /// <param name="Settings">Any settings we got for this member</param> /// <returns>A new replicated member</returns> protected virtual MDReplicatedMember CreateReplicatedMember(MemberInfo Member, MDReplicated RepAttribute, Node Instance, MDReplicatedSetting[] Settings) { MDReplicatedSetting[] ParsedSettings = ParseParameters(typeof(Settings), Settings); Type ReplicatedMemberTypeOverride = GetReplicatedMemberOverrideType(ParsedSettings); if (ReplicatedMemberTypeOverride != null && ReplicatedMemberTypeOverride.IsAssignableFrom(typeof(MDReplicatedMember))) { return(Activator.CreateInstance(ReplicatedMemberTypeOverride, new object[] { Member, RepAttribute.Reliability == MDReliability.Reliable, RepAttribute.ReplicatedType, WeakRef(Instance), Settings }) as MDReplicatedMember); } // Check if we got a Command Replicator if (Member.GetUnderlyingType().GetInterface(nameof(IMDCommandReplicator)) != null) { return(new MDReplicatedCommandReplicator(Member, RepAttribute.Reliability == MDReliability.Reliable, RepAttribute.ReplicatedType, WeakRef(Instance), Settings)); } // Check if we allow interpolation if (GetAllowsInterpolation(ParsedSettings)) { if (Member.GetUnderlyingType() == typeof(float)) { return(new MDCRMInterpolatedFloat(Member, RepAttribute.Reliability == MDReliability.Reliable, RepAttribute.ReplicatedType, WeakRef(Instance), Settings)); } if (Member.GetUnderlyingType() == typeof(Vector2)) { return(new MDCRMInterpolatedVector2(Member, RepAttribute.Reliability == MDReliability.Reliable, RepAttribute.ReplicatedType, WeakRef(Instance), Settings)); } if (Member.GetUnderlyingType() == typeof(Vector3)) { return(new MDCRMInterpolatedVector3(Member, RepAttribute.Reliability == MDReliability.Reliable, RepAttribute.ReplicatedType, WeakRef(Instance), Settings)); } } return(new MDReplicatedMember(Member, RepAttribute.Reliability == MDReliability.Reliable, RepAttribute.ReplicatedType, WeakRef(Instance), Settings)); }
/// <summary> /// Registers the given instance's fields marked with [MDReplicated()] /// </summary> /// <param name="Instance">The node to register</param> public void RegisterReplication(Node Instance) { List <MemberInfo> Members = MDStatics.GetTypeMemberInfos(Instance); List <MDReplicatedMember> NodeMembers = new List <MDReplicatedMember>(); foreach (MemberInfo Member in Members) { MDReplicated RepAttribute = Member.GetCustomAttribute(typeof(MDReplicated)) as MDReplicated; if (RepAttribute == null) { continue; } MDReplicatedSetting[] Settings = GetSettings(Member); MDReplicatedMember NodeMember = CreateReplicatedMember(Member, RepAttribute, Instance, Settings); NodeMembers.Add(NodeMember); ProcessSettingsForMember(NodeMember, ParseParameters(typeof(Settings), Settings)); GroupManager.AddReplicatedMember(NodeMember); MDLog.Debug(LOG_CAT, $"Adding Replicated Node {Instance.Name} Member {Member.Name}"); if (HasRPCModeSet(Member) == false) { Instance.RsetConfig(Member.Name, MultiplayerAPI.RPCMode.Puppet); } } if (NodeMembers.Count > 0) { NodeList.Add(new ReplicatedNode(Instance, NodeMembers)); List <object> networkIdUpdates = new List <object>(); foreach (MDReplicatedMember member in NodeMembers) { string MemberUniqueKey = member.GetUniqueKey(); KeyToMemberMap.Add(MemberUniqueKey, member); // Check if we have a buffer waiting for this member if (NetworkIdKeyMap.ContainsKey(MemberUniqueKey)) { NetworkIdKeyMap.CheckBuffer(NetworkIdKeyMap.GetValue(MemberUniqueKey), member); } if (MDStatics.IsServer()) { if (!NetworkIdKeyMap.ContainsKey(member.GetUniqueKey())) { uint networkid = GetReplicationId(); MDLog.Trace(LOG_CAT, $"Adding NetworkIdKeyMap key [{member.GetUniqueKey()}] with id [{networkid}]"); NetworkIdKeyMap.AddNetworkKeyIdPair(networkid, member.GetUniqueKey()); NetworkIdKeyMap.CheckBuffer(networkid, member); networkIdUpdates.Add(networkid); networkIdUpdates.Add(member.GetUniqueKey()); } } } if (MDStatics.IsNetworkActive() && networkIdUpdates.Count > 0) { Rpc(nameof(UpdateNetworkIdMap), networkIdUpdates); } } }