/// <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)
            {
            }
        }
Exemple #2
0
        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);
        }
Exemple #4
0
        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);
            }
        }
Exemple #6
0
        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!");
            }
        }
Exemple #10
0
        protected NetworkId AddNetworkObjectServer(IMyNetObject obj)
        {
            Debug.Assert(m_isNetworkAuthority);
            var id = new NetworkId(m_networkIdGenerator.NextId());

            AddNetworkObject(id, obj);
            return(id);
        }
Exemple #11
0
 public MyStateDataEntry(IMyReplicable owner, NetworkId groupId, IMyStateGroup group, IMyReplicable parent)
 {
     Priority  = 0;
     Owner     = owner;
     GroupId   = groupId;
     Group     = group;
     GroupType = group.GroupType;
     Parent    = parent;
 }
Exemple #12
0
        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);
            }
        }
Exemple #13
0
        /// <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);
     }
 }
Exemple #15
0
        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));
        }
Exemple #16
0
        /// <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);
        }
Exemple #17
0
        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);
        }
Exemple #18
0
        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);
        }
Exemple #20
0
        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();
            }
        }
Exemple #25
0
 public static void WriteNetworkId(this VRage.Library.Collections.BitStream stream, NetworkId networkId)
 {
     stream.WriteVariant((uint)networkId.Value);
 }
Exemple #26
0
 public MyStateDataEntry(NetworkId groupId, IMyStateGroup group)
 {
     Priority = 0;
     GroupId  = groupId;
     Group    = group;
 }
Exemple #27
0
        /// <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();
            }
        }
Exemple #28
0
 protected void AddNetworkObjectClient(NetworkId networkId, IMyNetObject obj)
 {
     Debug.Assert(!m_isNetworkAuthority);
     AddNetworkObject(networkId, obj);
 }
Exemple #29
0
 public IMyNetObject GetObjectByNetworkId(NetworkId id)
 {
     return(m_networkIDToObject.GetValueOrDefault(id));
 }
Exemple #30
0
 public bool TryGetNetworkIdByObject(IMyNetObject obj, out NetworkId networkId)
 {
     return(m_objectToNetworkID.TryGetValue(obj, out networkId));
 }