public void OnAck(MyClientStateBase forClient, byte packetId, bool delivered)
        {
            //streaming  is reliable don't care
            return;

            StreamClientData clientData = m_clientStreamData[forClient.EndpointId.Value];
            StreamPartInfo   packetInfo;

            if (clientData.SendPackets.TryGetValue(packetId, out packetInfo))
            {
                if (delivered)
                {
                    clientData.SendPackets.Remove(packetId);
                    if (clientData.SendPackets.Count == 0 && clientData.RemainingBits == 0)
                    {
                        clientData.Dirty     = false;
                        clientData.ForceSend = false;
                    }
                }
                else
                {
                    if (clientData.ObjectData != null)
                    {
                        clientData.FailedIncompletePackets.Add(packetInfo);
                        clientData.Dirty = true;
                        clientData.SendPackets.Remove(packetId);
                    }
                }
            }
        }
        public void ForceSend(MyClientStateBase clientData)
        {
            StreamClientData streamData = m_clientStreamData[clientData.EndpointId.Value];

            streamData.ForceSend = true;
            SaveReplicable(streamData);
        }
        private void WriteWhole(int bitsToSend, StreamClientData clientData, byte packetId, ref VRage.Library.Collections.BitStream stream)
        {
            StreamPartInfo info = new StreamPartInfo();

            info.StartIndex = 0;
            info.NumBits    = bitsToSend;
            info.Position   = 0;

            clientData.SendPackets[packetId] = info;
            clientData.RemainingBits         = 0;

            clientData.Dirty     = false;
            clientData.ForceSend = false;
            stream.WriteInt16(1);
            stream.WriteInt16(0);
            stream.WriteInt32(bitsToSend);

            unsafe
            {
                fixed(byte *dataPtr = clientData.ObjectData)
                {
                    stream.WriteMemory(dataPtr, bitsToSend);
                }
            }
        }
        private void SaveReplicable(StreamClientData clientData)
        {
            VRage.Library.Collections.BitStream str = new VRage.Library.Collections.BitStream();
            str.ResetWrite();
            Instance.Serialize(str);
            str.ResetRead();

            int numObjectBits = str.BitLength;

            byte[] uncompressedData = new byte[str.ByteLength];

            unsafe
            {
                fixed(byte *dataPtr = uncompressedData)
                {
                    str.SerializeMemory(dataPtr, numObjectBits);
                }
            }
            str.Dispose();

            clientData.CurrentPart      = 0;
            clientData.ObjectData       = MemoryCompressor.Compress(uncompressedData);
            clientData.UncompressedSize = numObjectBits;
            clientData.RemainingBits    = clientData.ObjectData.Length * 8;
        }
        private void WritePart(ref int bitsToSend, StreamClientData clientData, byte packetId, ref VRage.Library.Collections.BitStream stream)
        {
            bitsToSend = Math.Min(m_streamSize, clientData.RemainingBits);
            StreamPartInfo info = new StreamPartInfo();

            info.StartIndex = clientData.LastPosition;
            info.NumBits    = bitsToSend;

            clientData.LastPosition          = info.StartIndex + MyLibraryUtils.GetDivisionCeil(m_streamSize, 8);
            clientData.SendPackets[packetId] = info;
            clientData.RemainingBits         = Math.Max(0, clientData.RemainingBits - m_streamSize);

            stream.WriteInt16(clientData.NumParts);
            stream.WriteInt16(clientData.CurrentPart);
            info.Position = clientData.CurrentPart;

            clientData.CurrentPart++;

            stream.WriteInt32(bitsToSend);

            unsafe
            {
                fixed(byte *dataPtr = &clientData.ObjectData[info.StartIndex])
                {
                    stream.WriteMemory(dataPtr, bitsToSend);
                }
            }
        }
        private void WriteIncompletePacket(StreamClientData clientData, byte packetId, ref VRage.Library.Collections.BitStream stream)
        {
            if (clientData.ObjectData == null)
            {
                clientData.FailedIncompletePackets.Clear();
                return;
            }

            StreamPartInfo failedPart = clientData.FailedIncompletePackets[0];

            clientData.FailedIncompletePackets.Remove(failedPart);
            clientData.SendPackets[packetId] = failedPart;

            stream.WriteInt32(clientData.UncompressedSize);
            stream.WriteInt16(clientData.NumParts);
            stream.WriteInt16(failedPart.Position);
            stream.WriteInt32(failedPart.NumBits);

            unsafe
            {
                fixed(byte *dataPtr = &clientData.ObjectData[failedPart.StartIndex])
                {
                    stream.WriteMemory(dataPtr, failedPart.NumBits);
                }
            }
        }
예제 #7
0
        public float GetGroupPriority(int frameCountWithoutSync, MyClientInfo forClient)
        {
            ProfilerShort.Begin("MyStreamingEntityStateGroup::GetGroupPriority");

            StreamClientData clientData = m_clientStreamData[forClient.EndpointId.Value];

            if (forClient.IsReplicableReady(Instance as IMyReplicable))
            {
                clientData.CurrentPart = 0;
                clientData.ForceSend   = false;
                clientData.ObjectData  = null;
                clientData.FailedIncompletePackets.Clear();
                clientData.SendPackets.Clear();
                ProfilerShort.End();
                return(0.0f);
            }

            float priority = forClient.HasReplicable(Instance as IMyReplicable) && clientData.Dirty ? Instance.GetPriority(forClient, false) * Instance.PriorityScale() : 0.0f;

            if (priority < 0.01f && (clientData.ForceSend || clientData.FailedIncompletePackets.Count > 0))
            {
                priority = Instance.PriorityScale();
            }

            ProfilerShort.End();
            return(priority);
        }
        private void ProcessWrite(int maxBitPosition, ref VRage.Library.Collections.BitStream stream, EndpointId forClient, byte packetId)
        {
            m_streamSize = MyLibraryUtils.GetDivisionCeil(maxBitPosition - stream.BitPosition - HEADER_SIZE - SAFE_VALUE, 8) * 8;
            StreamClientData clientData = m_clientStreamData[forClient.Value];

            if (clientData.FailedIncompletePackets.Count > 0)
            {
                stream.WriteBool(true);
                WriteIncompletePacket(clientData, packetId, ref stream);
                return;
            }

            int  bitsToSend = 0;
            bool incomplete = false;

            if (clientData.ObjectData == null)
            {
                SaveReplicable(clientData);
            }
            else
            {
                incomplete = true;
            }

            clientData.NumParts = (short)MyLibraryUtils.GetDivisionCeil(clientData.ObjectData.Length * 8, m_streamSize);

            bitsToSend = clientData.RemainingBits;

            if (bitsToSend == 0)
            {
                clientData.ForceSend = false;
                clientData.Dirty     = false;

                stream.WriteBool(false);
                return;
            }

            stream.WriteBool(true);
            stream.WriteInt32(clientData.UncompressedSize);

            if (bitsToSend > m_streamSize || incomplete)
            {
                WritePart(ref bitsToSend, clientData, packetId, ref stream);
            }
            else
            {
                WriteWhole(bitsToSend, clientData, packetId, ref stream);
            }

            if (clientData.RemainingBits == 0)
            {
                clientData.Dirty     = false;
                clientData.ForceSend = false;
            }
        }
예제 #9
0
        public bool IsStillDirty(EndpointId forClient)
        {
            StreamClientData clientData = m_clientStreamData[forClient.Value];

            return(clientData.Dirty);
        }