public void ProcessReplicationCreateBegin(MyPacket packet) { m_receiveStream.ResetRead(packet); TypeId typeId = m_receiveStream.ReadTypeId(); NetworkId networkID = m_receiveStream.ReadNetworkId(); byte groupCount = m_receiveStream.ReadByte(); var pendingReplicable = new MyPendingReplicable(); for (int i = 0; i < groupCount; i++) { var id = m_receiveStream.ReadNetworkId(); pendingReplicable.StateGroupIds.Add(id); } Type type = GetTypeByTypeId(typeId); IMyReplicable replicable = (IMyReplicable)Activator.CreateInstance(type); pendingReplicable.DebugObject = replicable; m_pendingReplicables.Add(networkID, pendingReplicable); var ids = pendingReplicable.StateGroupIds; using (m_tmpGroups) { IMyStreamableReplicable streamable = replicable as IMyStreamableReplicable; if (streamable != null) { pendingReplicable.IsStreaming = true; var group = streamable.GetStreamingStateGroup(); m_tmpGroups.Add(group); } for (int i = 0; i < m_tmpGroups.Count; i++) { if (m_tmpGroups[i] != replicable) { AddNetworkObjectClient(ids[i], m_tmpGroups[i]); pendingReplicable.StreamingGroupId = ids[i]; } } } replicable.OnLoadBegin(m_receiveStream, (loaded) => SetReplicableReady(networkID, replicable, loaded)); }
/// <summary> /// Marks replicable as successfully created, ready to receive events and state groups data. /// </summary> void SetReplicableReady(NetworkId networkId, IMyReplicable replicable, bool loaded) { MyPendingReplicable pendingReplicable; if (m_pendingReplicables.TryGetValue(networkId, out pendingReplicable)) { m_pendingReplicables.Remove(networkId); if (loaded) { var ids = pendingReplicable.StateGroupIds; AddNetworkObjectClient(networkId, replicable); using (m_tmpGroups) { IMyStreamableReplicable streamable = replicable as IMyStreamableReplicable; if (streamable != null && pendingReplicable.IsStreaming) { var group = streamable.GetStreamingStateGroup(); m_tmpGroups.Add(group); } replicable.GetStateGroups(m_tmpGroups); Debug.Assert(ids.Count == m_tmpGroups.Count, "Number of state groups on client and server for replicable does not match"); for (int i = 0; i < m_tmpGroups.Count; i++) { if (m_tmpGroups[i] != replicable && m_tmpGroups[i].GroupType != StateGroupEnum.Streamining) { AddNetworkObjectClient(ids[i], m_tmpGroups[i]); } } } m_eventBuffer.ProcessEvents(networkId, m_eventHandler, m_isBlockedHandler, NetworkId.Invalid); } else { MyLog.Default.WriteLine("Failed to create replicable ! Type : " + replicable.ToString()); m_eventBuffer.RemoveEvents(networkId); IMyStreamableReplicable streamable = replicable as IMyStreamableReplicable; if (streamable != null && pendingReplicable.IsStreaming) { var group = streamable.GetStreamingStateGroup(); group.Destroy(); NetworkId streaingGroupId; if (TryGetNetworkIdByObject(group, out streaingGroupId)) { RemoveNetworkedObject(group); } MyLog.Default.WriteLine("removing streaming group for not loaded replicable !"); } } m_sendStream.ResetWrite(); m_sendStream.WriteNetworkId(networkId); m_sendStream.WriteBool(loaded); m_callback.SendReplicableReady(m_sendStream); } else { m_pendingReplicables.Remove(networkId); using (m_tmpGroups) { IMyStreamableReplicable streamable = replicable as IMyStreamableReplicable; if (streamable != null && streamable.NeedsToBeStreamed) { var group = streamable.GetStreamingStateGroup(); m_tmpGroups.Add(group); MyLog.Default.WriteLine("removing streaming group for not loaded replicable !"); } replicable.GetStateGroups(m_tmpGroups); foreach (var g in m_tmpGroups) { if (g != null) // when terminal repblicable fails to attach to block its state group is null becouase its created inside hook method. { g.Destroy(); } } } replicable.OnDestroy(); } }