Example #1
0
        /// <summary>
        /// Request the ping from the server (pingReceived will be triggered if it receives it)
        ///
        /// This is not a reliable call
        /// </summary>
        public override void Ping()
        {
            BMSByte payload = new BMSByte();
            long    ticks   = DateTime.UtcNow.Ticks;

            payload.BlockCopy <long>(ticks, sizeof(long));
            Ping pingFrame = new Ping(Time.Timestep, false, payload, Receivers.Server, MessageGroupIds.PING, false);

            Send(pingFrame);
        }
Example #2
0
        /// <summary>
        /// Collect all of the data from all of the packets in this sequence and return it
        /// </summary>
        /// <returns>The complete packet sequence data</returns>
        public BMSByte GetData()
        {
            data.Clear();

            for (int i = 0; i < End; i++)
            {
                data.BlockCopy(packets[i].rawBytes, 0, packets[i].rawBytes.Length);
            }

            return(data);
        }
Example #3
0
        /// <summary>
        /// Gets the bytes for the Instance of an Object and appends them to a <c>BMSByte</c>.
        /// </summary>
        /// <param name="o">The Instance of the Object.</param>
        /// <param name="type">The Type of the Object.</param>
        /// <param name="bytes"><c>BMSByte</c> to which the bytes should be added.</param>
        protected virtual void GetBytes(object o, Type type, ref BMSByte bytes)
        {
            if (type == typeof(string))
            {
                var strBytes = Encoding.UTF8.GetBytes(o == null ? string.Empty : (string)o);
                // TODO:  Need to make custom string serialization to binary
                bytes.Append(BitConverter.GetBytes(strBytes.Length));

                if (strBytes.Length > 0)
                {
                    bytes.Append(strBytes);
                }
            }
            else if (type == typeof(Vector))
            {
                Vector vec = (Vector)o;
                bytes.Append(BitConverter.GetBytes(vec.x));
                bytes.Append(BitConverter.GetBytes(vec.y));
                bytes.Append(BitConverter.GetBytes(vec.z));
            }
            else if (type == null)             //TODO: Check if this causes other issues
            {
                bytes.Append(new byte[1] {
                    0
                });
            }
            else if (type == typeof(sbyte))
            {
                bytes.BlockCopy <sbyte>(o, 1);
            }
            else if (type == typeof(byte))
            {
                bytes.BlockCopy <byte>(o, 1);
            }
            else if (type == typeof(char))
            {
                bytes.BlockCopy <char>(o, 1);
            }
            else if (type == typeof(bool))
            {
                bytes.Append(BitConverter.GetBytes((bool)o));
            }
            else if (type == typeof(short))
            {
                bytes.Append(BitConverter.GetBytes((short)o));
            }
            else if (type == typeof(ushort))
            {
                bytes.Append(BitConverter.GetBytes((ushort)o));
            }
            else if (type == typeof(int))
            {
                bytes.Append(BitConverter.GetBytes((int)o));
            }
            else if (type == typeof(uint))
            {
                bytes.Append(BitConverter.GetBytes((uint)o));
            }
            else if (type == typeof(long))
            {
                bytes.Append(BitConverter.GetBytes((long)o));
            }
            else if (type == typeof(ulong))
            {
                bytes.Append(BitConverter.GetBytes((ulong)o));
            }
            else if (type == typeof(float))
            {
                bytes.Append(BitConverter.GetBytes((float)o));
            }
            else if (type == typeof(double))
            {
                bytes.Append(BitConverter.GetBytes((double)o));
            }
            else if (type.IsArray)
            {
                int  rank       = type.GetArrayRank();
                Type targetType = type.GetElementType();

                if (targetType != typeof(byte))
                {
                    throw new Exception("Currently only byte arrays can be sent as arrays");
                }

                if (rank > 4)
                {
                    throw new Exception("Currently the system only supports up to 4 dimensions in an array");
                }

                int i, j, k, l;

                // Write each dimension length first
                int[] lengths = new int[rank];
                for (i = 0; i < rank; i++)
                {
                    lengths[i] = ((Array)o).GetLength(i);
                    bytes.Append(BitConverter.GetBytes(lengths[i]));
                }

                switch (rank)
                {
                case 1:
                    for (i = 0; i < lengths[0]; i++)
                    {
                        GetBytes(((Array)o).GetValue(i), targetType, ref bytes);
                    }
                    break;

                case 2:
                    for (i = 0; i < lengths[0]; i++)
                    {
                        for (j = 0; j < lengths[1]; j++)
                        {
                            GetBytes(((Array)o).GetValue(i, j), targetType, ref bytes);
                        }
                    }
                    break;

                case 3:
                    for (i = 0; i < lengths[0]; i++)
                    {
                        for (j = 0; j < lengths[1]; j++)
                        {
                            for (k = 0; k < lengths[2]; k++)
                            {
                                GetBytes(((Array)o).GetValue(i, j, k), targetType, ref bytes);
                            }
                        }
                    }
                    break;

                case 4:
                    for (i = 0; i < lengths[0]; i++)
                    {
                        for (j = 0; j < lengths[1]; j++)
                        {
                            for (k = 0; k < lengths[2]; k++)
                            {
                                for (l = 0; l < lengths[3]; l++)
                                {
                                    GetBytes(((Array)o).GetValue(i, j, k, l), targetType, ref bytes);
                                }
                            }
                        }
                    }
                    break;
                }
            }
            else if (type == typeof(BMSByte))
            {
                bytes.Append(BitConverter.GetBytes(((BMSByte)o).Size));
                bytes.BlockCopy(((BMSByte)o).byteArr, ((BMSByte)o).StartIndex(), ((BMSByte)o).Size);
            }
            else if (type.IsEnum)
            {
                GetBytes(o, Enum.GetUnderlyingType(type), ref bytes);
            }
            else
            {
                // TODO:  Make this a more appropriate exception
                throw new BaseNetworkException("The type " + type.ToString() + " is not allowed to be sent over the Network (yet)");
            }
        }
Example #4
0
        /// <summary>
        /// Creates the frame data using the passed in payload
        /// </summary>
        private void CreateFrame(bool useMask, ulong timestep, byte[] payload, Receivers receivers, int groupId, byte routerId, bool isStream)
        {
            // If we are to use a mask then generate a random mask
            if (useMask)
            {
                mask = new byte[4];
                new Random().NextBytes(mask);
            }

            StreamData = new BMSByte();

            TimeStep  = timestep;
            GroupId   = groupId;
            RouterId  = routerId;
            Receivers = receivers;
            UniqueId  = UniqueMessageIdCounter++;

            // Generate the frame identity
            byte[] frame = new byte[10];

            // The first byte of the data is always the control byte, which dictates the message type
            frame[0] = ControlByte;

            int length = payload.Length;

            if (isStream)
            {
                length += 21;                  // Group id (4), receivers (1), time step (8), unique id (8)
            }
            else
            {
                length += 16; // time step (8), unique id (8)
            }
            if (frame[0] == Binary.CONTROL_BYTE)
            {
                length += 1;
            }

            // Determine the length of the payload
            int dataStartIndex = 0;

            if (length <= 125)
            {
                frame[1]       = (byte)(useMask ? length | 128 : length);
                dataStartIndex = 2;
            }
            else if (length >= 126 && length <= 65535)
            {
                dataStartIndex = 4;
                frame[1]       = (byte)(useMask ? 254 : 126);
            }
            else
            {
                dataStartIndex = 10;
                frame[1]       = (byte)(useMask ? 255 : 127);
            }

            // If the payload is greater than a byte (255) then set the order of the bytes for the length
            if (dataStartIndex > 2)
            {
                int i = 0, j = 2, largestBitIndex = (dataStartIndex - 3) * 8;

                // Little endian / Big endian reversal based on mask
                //if (mask.Length == 0)
                //{
                for (i = largestBitIndex; i >= 0; i -= 8)
                {
                    frame[j++] = (byte)((((long)length) >> i) & 255);
                }
                //} else
                //{
                //    for (i = 0; i <= largestBitIndex; i += 8)
                //        frame[j++] = (byte)((payload.Length >> i) & 255);
                //}
            }

            // Prepare the stream data with the size so that it doesn't have to keep resizing
            StreamData.SetSize(dataStartIndex + mask.Length + length);
            StreamData.Clear();

            // Add the frame bytes
            StreamData.BlockCopy(frame, 0, dataStartIndex);

            // Add the mask bytes
            StreamData.BlockCopy(mask, 0, mask.Length);

            // Setup the int that tracks where the payload begins
            payloadStart = dataStartIndex + mask.Length;

            // If we are on a stream then use groupId
            if (isStream)
            {
                StreamData.BlockCopy(BitConverter.GetBytes(groupId), 0, sizeof(int));
                payloadStart += sizeof(int);
            }

            // Copy the routerId if this is a binary frame
            if (frame[0] == Binary.CONTROL_BYTE)
            {
                StreamData.BlockCopy(new byte[1] {
                    routerId
                }, 0, sizeof(byte));
                payloadStart += 1;
            }

            // Add the initial payload bytes
            StreamData.BlockCopy(payload, 0, payload.Length);

            if (isStream)
            {
                StreamData.BlockCopy(new byte[1] {
                    (byte)Receivers
                }, 0, sizeof(byte));
            }

            // Add the time step to the end of the frame
            StreamData.BlockCopy <ulong>(TimeStep, sizeof(ulong));

            // Add the unique message id for this frame just before the timestep frame
            StreamData.BlockCopy <ulong>(UniqueId, sizeof(ulong));

            if (mask.Length > 0)
            {
                for (int i = dataStartIndex + mask.Length, j = 0; i < StreamData.Size; i++, j++)
                {
                    StreamData.byteArr[i] = (byte)(StreamData.byteArr[i] ^ mask[j % 4]);
                }
            }
        }