Example #1
0
        // unpack a message we received
        public static T UnpackFromByteArray <T>(byte[] data)
            where T : struct, NetworkMessage
        {
            using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(data))
            {
                int msgType = MessagePacker.GetId <T>();

                int id = networkReader.ReadUInt16();
                if (id != msgType)
                {
                    throw new FormatException("Invalid message,  could not unpack " + typeof(T).FullName);
                }

                return(networkReader.Read <T>());
            }
        }
        /// <summary>
        /// Internal method to get the current Queue Item from the stream at its current position
        /// </summary>
        /// <returns>FrameQueueItem</returns>
        private RpcFrameQueueItem GetCurrentQueueItem()
        {
            //Write the packed version of the queueItem to our current queue history buffer
            m_CurrentQueueItem.QueueItemType = (RpcQueueContainer.QueueItemType)QueueReader.ReadUInt16();
            m_CurrentQueueItem.Timestamp     = QueueReader.ReadSingle();
            m_CurrentQueueItem.NetworkId     = QueueReader.ReadUInt64();

            //Clear out any current value for the client ids
            m_CurrentQueueItem.ClientNetworkIds = new ulong[0];

            //If outbound, determine if any client ids needs to be added
            if (m_QueueFrameType == QueueFrameType.Outbound)
            {
                //Outbound we care about both channel and clients
                m_CurrentQueueItem.NetworkChannel = (NetworkChannel)QueueReader.ReadByteDirect();
                int numClients = QueueReader.ReadInt32();
                if (numClients > 0 && numClients < m_MaximumClients)
                {
                    ulong[] clientIdArray = new ulong[numClients];
                    for (int i = 0; i < numClients; i++)
                    {
                        clientIdArray[i] = QueueReader.ReadUInt64();
                    }

                    if (m_CurrentQueueItem.ClientNetworkIds == null)
                    {
                        m_CurrentQueueItem.ClientNetworkIds = clientIdArray;
                    }
                    else
                    {
                        m_CurrentQueueItem.ClientNetworkIds = clientIdArray;
                    }
                }
            }

            m_CurrentQueueItem.UpdateStage = m_StreamUpdateStage;

            //Get the stream size
            m_CurrentQueueItem.StreamSize = QueueReader.ReadInt64();

            //Sanity checking for boundaries
            if (m_CurrentQueueItem.StreamSize < m_MaxStreamBounds && m_CurrentQueueItem.StreamSize > k_MinStreamBounds)
            {
                //Inbound and Outbound message streams are handled differently
                if (m_QueueFrameType == QueueFrameType.Inbound)
                {
                    //Get our offset
                    long position = QueueReader.ReadInt64();

                    //Always make sure we are positioned at the start of the stream before we write
                    m_CurrentQueueItem.NetworkBuffer.Position = 0;

                    //Write the entire message to the m_CurrentQueueItem stream (1 stream is re-used for all incoming RPCs)
                    m_CurrentQueueItem.NetworkWriter.ReadAndWrite(QueueReader, m_CurrentQueueItem.StreamSize);

                    //Reset the position back to the offset so std rpc API can process the message properly
                    //(i.e. minus the already processed header)
                    m_CurrentQueueItem.NetworkBuffer.Position = position;
                }
                else
                {
                    //Create a byte array segment for outbound sending
                    m_CurrentQueueItem.MessageData = QueueReader.CreateArraySegment((int)m_CurrentQueueItem.StreamSize, (int)QueueBuffer.Position);
                }
            }
            else
            {
                UnityEngine.Debug.LogWarning($"{nameof(m_CurrentQueueItem)}.{nameof(RpcFrameQueueItem.StreamSize)} exceeds allowed size ({m_MaxStreamBounds} vs {m_CurrentQueueItem.StreamSize})! Exiting from the current RpcQueue enumeration loop!");
                m_CurrentQueueItem.QueueItemType = RpcQueueContainer.QueueItemType.None;
            }

            return(m_CurrentQueueItem);
        }