/// <summary> /// Processes state sync sent by server. /// </summary> public void ProcessStateSync(MyPacket packet) { LastMessageFromServer = DateTime.UtcNow; // Simulated packet loss // if (MyRandom.Instance.NextFloat() > 0.3f) return; m_receiveStream.ResetRead(packet); bool isStreaming = m_receiveStream.ReadBool(); m_lastStateSyncPacketId = m_receiveStream.ReadByte(); try { while (m_receiveStream.BytePosition < m_receiveStream.ByteLength) { NetworkId networkID = m_receiveStream.ReadNetworkId(); IMyStateGroup obj = GetObjectByNetworkId(networkID) as IMyStateGroup; if (obj == null) { if (isStreaming == false) { Debug.Fail("IMyStateGroup not found by NetworkId"); break; } else { return; } } if (isStreaming && obj.GroupType != StateGroupEnum.Streamining) { Debug.Fail("group type mismatch !"); MyLog.Default.WriteLine("received streaming flag but group is not streaming !"); return; } if (!isStreaming && obj.GroupType == StateGroupEnum.Streamining) { Debug.Fail("group type mismatch !"); MyLog.Default.WriteLine("received non streaming flag but group wants to stream !"); return; } var pos = m_receiveStream.BytePosition; NetProfiler.Begin(obj.GetType().Name); obj.Serialize(m_receiveStream, ClientState.EndpointId, 0, m_lastStateSyncPacketId, 0); NetProfiler.End(m_receiveStream.ByteLength - pos); if (!m_acks.Contains(m_lastStateSyncPacketId)) { m_acks.Add(m_lastStateSyncPacketId); } } } catch (BitStreamException) { } }
private void AddNetworkObject(NetworkId networkID, IMyNetObject obj) { IMyNetObject foundObj; networkObjectLock.AcquireExclusiveUsing(); if (!m_networkIDToObject.TryGetValue(networkID, out foundObj)) { m_networkIDToObject.Add(networkID, obj); m_objectToNetworkID.Add(obj, networkID); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null!"); Debug.Assert(!m_proxyToTarget.ContainsKey(proxyTarget.Target), "Proxy is already added to list!"); if (proxyTarget.Target != null && !m_proxyToTarget.ContainsKey(proxyTarget.Target)) { m_proxyToTarget.Add(proxyTarget.Target, proxyTarget); } } } else { if (obj != null && foundObj != null) { MyLog.Default.WriteLine("Replicated object already exists adding : " + obj.ToString() + " existing : " + foundObj.ToString() + " id : " + networkID.ToString()); } Debug.Fail("Replicated object already exists!"); } networkObjectLock.ReleaseExclusive(); }
protected virtual void ProcessEvent(BitStream stream, NetworkId networkId, uint eventId, EndpointId sender) { CallSite site; IMyNetObject sendAs; object obj; if (networkId.IsInvalid) // Static event { site = m_typeTable.StaticEventTable.Get(eventId); sendAs = null; obj = null; } else // Instance event { sendAs = GetObjectByNetworkId(networkId); var typeInfo = m_typeTable.Get(sendAs.GetType()); int eventCount = typeInfo.EventTable.Count; if (eventId < eventCount) // Directly { obj = sendAs; site = typeInfo.EventTable.Get(eventId); } else // Through proxy { obj = ((IMyProxyTarget)sendAs).Target; typeInfo = m_typeTable.Get(obj.GetType()); site = typeInfo.EventTable.Get(eventId - (uint)eventCount); // Subtract max id of Proxy Debug.Assert(object.ReferenceEquals(GetProxyTarget(((IMyProxyTarget)sendAs).Target), sendAs), "There must be one-to-one relationship between IMyEventProxy and IMyEventTarget. Proxy.EventTarget.Target == Proxy"); } } ProcessEvent(stream, site, obj, sendAs, sender); }
public void RemoveFixedObject(uint id, IMyNetObject obj) { var netId = new NetworkId(id); m_fixedObjects.Remove(obj); RemoveNetworkedObject(netId, obj); }
/// <summary> /// Processes state sync sent by server. /// </summary> public void ProcessStateSync(MyPacket packet) { // Simulated packet loss // if (MyRandom.Instance.NextFloat() > 0.05f) return; m_receiveStream.ResetRead(packet); m_lastStateSyncPacketId = m_receiveStream.ReadByte(); while (m_receiveStream.BytePosition < m_receiveStream.ByteLength) { NetworkId networkID = m_receiveStream.ReadNetworkId(); IMyNetObject obj = GetObjectByNetworkId(networkID); var pos = m_receiveStream.BytePosition; NetProfiler.Begin(obj.GetType().Name); Debug.Assert(obj != null && obj is IMyStateGroup, "IMyStateGroup not found by NetworkId"); ((IMyStateGroup)obj).Serialize(m_receiveStream, null, m_lastStateSyncPacketId, 0); NetProfiler.End(m_receiveStream.ByteLength - pos); } if (!m_acks.Contains(m_lastStateSyncPacketId)) { m_acks.Add(m_lastStateSyncPacketId); } }
public void ProcessReplicationCreate(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; pendingReplicable.IsStreaming = false; m_pendingReplicables.Add(networkID, pendingReplicable); replicable.OnLoad(m_receiveStream, (loaded) => SetReplicableReady(networkID, replicable, loaded)); }
void ProcessEvent(BitStream stream, EndpointId sender) { NetworkId networkId = stream.ReadNetworkId(); uint eventId = (uint)stream.ReadByte(); // TODO: Compress eventId to necessary number of bits ProcessEvent(stream, networkId, eventId, sender); }
public MyStateDataEntry(IMyReplicable owner, NetworkId groupId, IMyStateGroup group) { Priority = 0; Owner = owner; GroupId = groupId; Group = group; }
private void AddNetworkObject(NetworkId networkID, IMyNetObject obj) { IMyNetObject foundObj; if (!m_networkIDToObject.TryGetValue(networkID, out foundObj)) { m_networkIDToObject.Add(networkID, obj); m_objectToNetworkID.Add(obj, networkID); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null!"); if (proxyTarget.Target != null) { m_proxyToTarget.Add(proxyTarget.Target, proxyTarget); } } } else { if (obj != null && foundObj != null) { MyLog.Default.WriteLine("Replicated object already exists adding : " + obj.ToString() + " existing : " + foundObj.ToString() + " id : " + networkID.ToString()); } Debug.Fail("Replicated object already exists!"); } }
protected NetworkId AddNetworkObjectServer(IMyNetObject obj) { Debug.Assert(m_isNetworkAuthority); var id = new NetworkId(m_networkIdGenerator.NextId()); AddNetworkObject(id, obj); return(id); }
public MyStateDataEntry(IMyReplicable owner, NetworkId groupId, IMyStateGroup group, IMyReplicable parent) { Priority = 0; Owner = owner; GroupId = groupId; Group = group; GroupType = group.GroupType; Parent = parent; }
public void ProcessReplicationDestroy(MyPacket packet) { m_receiveStream.ResetRead(packet); NetworkId networkID = m_receiveStream.ReadNetworkId(); MyPendingReplicable pendingReplicable; if (!m_pendingReplicables.TryGetValue(networkID, out pendingReplicable)) // When it wasn't in pending replicables, it's already active and in scene, destroy it { IMyReplicable replicable = (IMyReplicable)GetObjectByNetworkId(networkID); // Debug.Assert(replicable != null, "Client received ReplicationDestroy, but object no longer exists (removed locally?)"); if (replicable != null) { using (m_tmpGroups) { var streamable = replicable as IMyStreamableReplicable; if (streamable != null && streamable.NeedsToBeStreamed) { m_tmpGroups.Add(streamable.GetStreamingStateGroup()); } replicable.GetStateGroups(m_tmpGroups); foreach (var g in m_tmpGroups) { if (g == null) { continue; } if (g != replicable) { RemoveNetworkedObject(g); } g.Destroy(); } } RemoveNetworkedObject(replicable); replicable.OnDestroy(); } } else { m_pendingReplicables.Remove(networkID); if (pendingReplicable.IsStreaming) { IMyStateGroup group = (IMyStateGroup)GetObjectByNetworkId(pendingReplicable.StreamingGroupId); if (group != null) { RemoveNetworkedObject(group); group.Destroy(); } } m_eventBuffer.RemoveEvents(networkID); } }
/// <summary> /// Add network object with fixed ID. /// </summary> public void AddFixedNetworkObject(uint id, IMyNetObject obj) { Debug.Assert(id != 0, "Zero is invalid id, it cannot be used."); Debug.Assert(id <= m_networkIdGenerator.ReservedCount, "Fixed id not reserved, call ReserveFixedIds"); var netId = new NetworkId(id); AddNetworkObject(netId, obj); m_fixedObjects.Add(obj); }
protected override void ProcessEvent(BitStream stream, NetworkId networkId, uint eventId, EndpointId sender) { if (networkId.IsValid && m_pendingReplicables.ContainsKey(networkId)) { m_eventBuffer.EnqueueEvent(stream, networkId, eventId, sender); } else { base.ProcessEvent(stream, networkId, eventId, sender); } }
public bool TryGetNetworkIdByObject(IMyNetObject obj, out NetworkId networkId) { System.Diagnostics.Debug.Assert(obj != null, "NULL in replicables"); if (obj == null) { networkId = NetworkId.Invalid; return(false); } return(m_objectToNetworkID.TryGetValue(obj, out networkId)); }
/// <summary> /// Checks if network id is blocked by other network id. /// </summary> /// <param name="networkId">Target network id.</param> /// <param name="blockedNetId">Blocking network id.</param> /// <returns></returns> private bool IsBlocked(NetworkId networkId, NetworkId blockedNetId) { bool anyReplPending = m_pendingReplicables.ContainsKey(networkId) || m_pendingReplicables.ContainsKey(blockedNetId); bool anyDoesNotExist = GetObjectByNetworkId(networkId) == null || (blockedNetId.IsValid && GetObjectByNetworkId(blockedNetId) == null); if (networkId.IsValid && (anyReplPending || anyDoesNotExist)) { return(true); } return(false); }
protected IMyNetObject RemoveNetworkedObject(NetworkId networkID) { IMyNetObject obj; if (m_networkIDToObject.TryGetValue(networkID, out obj)) { RemoveNetworkedObject(networkID, obj); } else { Debug.Fail("RemoveNetworkedObject, object not found!"); } return(obj); }
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)); }
public void Replicate(IMyReplicable obj) { if (!IsTypeReplicated(obj.GetType())) { Debug.Fail(String.Format("Type '{0}' not replicated, this should be checked before calling Replicate", obj.GetType().Name)); return; } NetworkId networkId = AddNetworkObjectServer(obj); m_replicables.Add(networkId, obj); AddStateGroups(obj); // HACK: test serialization //m_sendStream.ResetWrite(MessageIDEnum.REPLICATION_CREATE); //stateData.Replicate(m_sendStream); }
protected override void ProcessEvent(BitStream stream, NetworkId networkId, NetworkId blockedNetId, uint eventId, EndpointId sender) { // Check if any of them is not blocked already. bool anyContainsEvents = m_eventBuffer.ContainsEvents(networkId) || m_eventBuffer.ContainsEvents(blockedNetId); if (this.IsBlocked(networkId, blockedNetId) || anyContainsEvents) { m_eventBuffer.EnqueueEvent(stream, networkId, blockedNetId, eventId, sender); // Only enqueue barrier if blocking network id is set if (blockedNetId.IsValid) { m_eventBuffer.EnqueueBarrier(blockedNetId, networkId); } } else { base.ProcessEvent(stream, networkId, blockedNetId, eventId, sender); } }
protected void RemoveNetworkedObject(NetworkId networkID, IMyNetObject obj) { bool removedId = m_objectToNetworkID.Remove(obj); bool removedObj = m_networkIDToObject.Remove(networkID); Debug.Assert(removedId && removedObj, "Networked object was not removed because it was not in collection"); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null during object remove!"); if (proxyTarget.Target != null) { bool removedProxy = m_proxyToTarget.Remove(proxyTarget.Target); Debug.Assert(removedProxy, "Network object proxy was not removed because it was not in collection"); } } m_networkIdGenerator.Return(networkID.Value); }
/// <summary> /// Marks replicable as successfully created, ready to receive events and state groups data. /// </summary> void SetReplicableReady(NetworkId networkId, IMyReplicable replicable) { MyPendingReplicable pendingReplicable; if (m_pendingReplicables.TryGetValue(networkId, out pendingReplicable)) { var ids = pendingReplicable.StateGroupIds; AddNetworkObjectClient(networkId, replicable); using (m_tmpGroups) { 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) { AddNetworkObjectClient(ids[i], m_tmpGroups[i]); } } } m_pendingReplicables.Remove(networkId); m_eventBuffer.ProcessEvents(networkId, m_eventHandler); m_sendStream.ResetWrite(); m_sendStream.WriteNetworkId(networkId); m_callback.SendReplicableReady(m_sendStream); } else { // Replicable was already destroyed on server, during it's load on client m_eventBuffer.RemoveEvents(networkId); replicable.OnDestroy(); } }
private void AddNetworkObject(NetworkId networkID, IMyNetObject obj) { IMyNetObject foundObj; if (!m_networkIDToObject.TryGetValue(networkID, out foundObj)) { m_networkIDToObject.Add(networkID, obj); m_objectToNetworkID.Add(obj, networkID); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null!"); if (proxyTarget.Target != null) { m_proxyToTarget.Add(proxyTarget.Target, proxyTarget); } } } else { Debug.Fail("Replicated object already exists!"); } }
public void ProcessReplicationDestroy(MyPacket packet) { m_receiveStream.ResetRead(packet); NetworkId networkID = m_receiveStream.ReadNetworkId(); if (!m_pendingReplicables.Remove(networkID)) // When it wasn't in pending replicables, it's already active and in scene, destroy it { IMyReplicable replicable = (IMyReplicable)GetObjectByNetworkId(networkID); using (m_tmpGroups) { replicable.GetStateGroups(m_tmpGroups); foreach (var g in m_tmpGroups) { if (g != replicable) { RemoveNetworkedObject(g); } } } RemoveNetworkedObject(replicable); replicable.OnDestroy(); } }
public static void WriteNetworkId(this VRage.Library.Collections.BitStream stream, NetworkId networkId) { stream.WriteVariant((uint)networkId.Value); }
public MyStateDataEntry(NetworkId groupId, IMyStateGroup group) { Priority = 0; GroupId = groupId; Group = group; }
/// <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(); } }
protected void AddNetworkObjectClient(NetworkId networkId, IMyNetObject obj) { Debug.Assert(!m_isNetworkAuthority); AddNetworkObject(networkId, obj); }
public IMyNetObject GetObjectByNetworkId(NetworkId id) { return(m_networkIDToObject.GetValueOrDefault(id)); }
public bool TryGetNetworkIdByObject(IMyNetObject obj, out NetworkId networkId) { return(m_objectToNetworkID.TryGetValue(obj, out networkId)); }