Ejemplo n.º 1
0
        public void ToStream(ref ByteOutputStream writer)
        {
            QueryHeader.ToStream(ref writer);

            var start = (ushort)writer.GetBytePosition();

            writer.WriteUInt32_NBO(0); // ChunkLen

            var chunkStart = (uint)writer.GetBytePosition();

            ServerInfoData.ToStream(ref writer);
            ChunkLen           = (uint)writer.GetBytePosition() - chunkStart;
            QueryHeader.Length = (ushort)(writer.GetBytePosition() - start);

            const int LengthSize     = 2;
            const int LengthOffset   = 9;
            const int ChunkLenSize   = 4;
            const int ChunkLenOffset = 11;

            var length   = (ushort)System.Net.IPAddress.HostToNetworkOrder((short)QueryHeader.Length);
            var chunkLen = (uint)System.Net.IPAddress.HostToNetworkOrder((int)ChunkLen);

            writer.WriteBytesOffset(new byte[] { (byte)length, (byte)(length >> 8) }, 0, LengthOffset, LengthSize);
            writer.WriteBytesOffset(new byte[] { (byte)chunkLen, (byte)(chunkLen >> 8), (byte)(chunkLen >> 16), (byte)(chunkLen >> 24) }, 0, ChunkLenOffset, ChunkLenSize);
        }
Ejemplo n.º 2
0
        public void StartInfoQuery()
        {
            Debug.Assert(m_State == SQPClientState.Idle);
            StartTime = NetworkUtils.stopwatch.ElapsedMilliseconds;

            var writer = new ByteOutputStream(m_Buffer);
            var req    = new ChallangeRequest();

            req.ToStream(ref writer);

            m_Socket.SendTo(m_Buffer, writer.GetBytePosition(), SocketFlags.None, m_Server);
            m_State = SQPClientState.WaitingForChallange;
        }
Ejemplo n.º 3
0
        void SendServerInfoQuery(SQPQuery q)
        {
            q.StartTime = NetworkUtils.stopwatch.ElapsedMilliseconds;
            var req = new QueryRequest();

            req.Header.ChallangeId = q.ChallangeId;
            req.RequestedChunks    = (byte)SQPChunkType.ServerInfo;

            var writer = new ByteOutputStream(m_Buffer);

            req.ToStream(ref writer);

            q.m_State = SQPClientState.WaitingForResponse;
            m_Socket.SendTo(m_Buffer, writer.GetBytePosition(), SocketFlags.None, q.m_Server);
        }
Ejemplo n.º 4
0
        public void Update()
        {
            if (m_Socket.Poll(0, SelectMode.SelectRead))
            {
                int read = m_Socket.ReceiveFrom(m_Buffer, m_Buffer.Length, SocketFlags.None, ref endpoint);
                if (read > 0)
                {
                    var reader = new ByteInputStream(m_Buffer);
                    var header = new SQPHeader();
                    header.FromStream(ref reader);

                    SQPMessageType type = (SQPMessageType)header.Type;

                    switch (type)
                    {
                    case SQPMessageType.ChallangeRequest:
                    {
                        if (!m_OutstandingTokens.ContainsKey(endpoint))
                        {
                            uint token = GetNextToken();
                            //Debug.Log("token generated: " + token);

                            var writer = new ByteOutputStream(m_Buffer);
                            var rsp    = new ChallangeResponse();
                            rsp.Header.ChallangeId = token;
                            rsp.ToStream(ref writer);

                            m_Socket.SendTo(m_Buffer, writer.GetBytePosition(), SocketFlags.None, endpoint);

                            m_OutstandingTokens.Add(endpoint, token);
                        }
                    }
                    break;

                    case SQPMessageType.QueryRequest:
                    {
                        uint token;
                        if (!m_OutstandingTokens.TryGetValue(endpoint, out token))
                        {
                            //Debug.Log("Failed to find token!");
                            return;
                        }
                        m_OutstandingTokens.Remove(endpoint);

                        reader.Reset();
                        var req = new QueryRequest();
                        req.FromStream(ref reader);

                        if ((SQPChunkType)req.RequestedChunks == SQPChunkType.ServerInfo)
                        {
                            var rsp    = m_ServerInfo;
                            var writer = new ByteOutputStream(m_Buffer);
                            rsp.QueryHeader.Header.ChallangeId = token;

                            rsp.ToStream(ref writer);
                            m_Socket.SendTo(m_Buffer, writer.GetBytePosition(), SocketFlags.None, endpoint);
                        }
                    }
                    break;

                    default:
                        break;
                    }
                }
            }
        }
Ejemplo n.º 5
0
    public static int Read <TInputStream>(ref TInputStream input, NetworkSchema schema, byte[] outputData, byte[] baselineData, byte[] fieldsChangedPrediction, byte fieldMask, ref uint hash) where TInputStream : NetworkCompression.IInputStream
    {
        GameDebug.Assert(baselineData != null);
        var outputStream   = new ByteOutputStream(outputData);
        var baselineStream = new ByteInputStream(baselineData);

        int numFields = schema.fields.Count;

        int skipContext = schema.id * NetworkConfig.maxContextsPerSchema + NetworkConfig.firstSchemaContext;

        for (int i = 0; i * 8 < numFields; i++)
        {
            uint value = input.ReadPackedNibble(skipContext + 2 * i + 0);
            value |= input.ReadPackedNibble(skipContext + 2 * i + 1) << 4;
            fieldsNotPredicted[i] = (byte)(value ^ fieldsChangedPrediction[i]);
        }

        for (int i = 0; i < numFields; ++i)
        {
            GameDebug.Assert(schema.fields[i].byteOffset == baselineStream.GetBytePosition());
            int fieldStartContext = schema.fields[i].startContext;

            var field = schema.fields[i];

            byte fieldByteOffset = (byte)((uint)i >> 3);
            byte fieldBitOffset  = (byte)((uint)i & 0x7);

            bool skip   = (fieldsNotPredicted[fieldByteOffset] & (1 << fieldBitOffset)) == 0;
            bool masked = ((field.fieldMask & fieldMask) != 0);

            skip = skip || masked;

            switch (field.fieldType)
            {
            case NetworkSchema.FieldType.Bool:
            {
                uint value = baselineStream.ReadUInt8();
                if (!skip)
                {
                    value = input.ReadRawBits(1);
                }

                if (!masked)
                {
                    hash = NetworkUtils.SimpleHashStreaming(hash, value);
                }

                outputStream.WriteUInt8((byte)value);
                break;
            }

            case NetworkSchema.FieldType.UInt:
            case NetworkSchema.FieldType.Int:
            case NetworkSchema.FieldType.Float:
            {
                uint baseline = (uint)baselineStream.ReadBits(field.bits);

                uint value = baseline;
                if (!skip)
                {
                    if (field.delta)
                    {
                        value = input.ReadPackedUIntDelta(baseline, fieldStartContext);
                    }
                    else
                    {
                        value = input.ReadRawBits(field.bits);
                    }
                }

                if (!masked)
                {
                    hash = NetworkUtils.SimpleHashStreaming(hash, value);
                }

                outputStream.WriteBits(value, field.bits);          //RUTODO: fix this
                break;
            }

            case NetworkSchema.FieldType.Vector2:
            {
                uint bx = baselineStream.ReadUInt32();
                uint by = baselineStream.ReadUInt32();

                uint vx = bx;
                uint vy = by;
                if (!skip)
                {
                    if (field.delta)
                    {
                        vx = input.ReadPackedUIntDelta(bx, fieldStartContext + 0);
                        vy = input.ReadPackedUIntDelta(by, fieldStartContext + 1);
                    }
                    else
                    {
                        vx = input.ReadRawBits(field.bits);
                        vy = input.ReadRawBits(field.bits);
                    }
                }

                if (!masked)
                {
                    hash = NetworkUtils.SimpleHashStreaming(hash, vx);
                    hash = NetworkUtils.SimpleHashStreaming(hash, vy);
                }

                outputStream.WriteUInt32(vx);
                outputStream.WriteUInt32(vy);

                break;
            }

            case NetworkSchema.FieldType.Vector3:
            {
                uint bx = baselineStream.ReadUInt32();
                uint by = baselineStream.ReadUInt32();
                uint bz = baselineStream.ReadUInt32();

                uint vx = bx;
                uint vy = by;
                uint vz = bz;

                if (!skip)
                {
                    if (field.delta)
                    {
                        vx = input.ReadPackedUIntDelta(bx, fieldStartContext + 0);
                        vy = input.ReadPackedUIntDelta(by, fieldStartContext + 1);
                        vz = input.ReadPackedUIntDelta(bz, fieldStartContext + 2);
                    }
                    else
                    {
                        vx = input.ReadRawBits(field.bits);
                        vy = input.ReadRawBits(field.bits);
                        vz = input.ReadRawBits(field.bits);
                    }
                }

                if (!masked)
                {
                    hash = NetworkUtils.SimpleHashStreaming(hash, vx);
                    hash = NetworkUtils.SimpleHashStreaming(hash, vy);
                    hash = NetworkUtils.SimpleHashStreaming(hash, vz);
                }

                outputStream.WriteUInt32(vx);
                outputStream.WriteUInt32(vy);
                outputStream.WriteUInt32(vz);
                break;
            }

            case NetworkSchema.FieldType.Quaternion:
            {
                uint bx = baselineStream.ReadUInt32();
                uint by = baselineStream.ReadUInt32();
                uint bz = baselineStream.ReadUInt32();
                uint bw = baselineStream.ReadUInt32();

                uint vx = bx;
                uint vy = by;
                uint vz = bz;
                uint vw = bw;

                if (!skip)
                {
                    if (field.delta)
                    {
                        vx = input.ReadPackedUIntDelta(bx, fieldStartContext + 0);
                        vy = input.ReadPackedUIntDelta(by, fieldStartContext + 1);
                        vz = input.ReadPackedUIntDelta(bz, fieldStartContext + 2);
                        vw = input.ReadPackedUIntDelta(bw, fieldStartContext + 3);
                        //RUTODO: normalize
                    }
                    else
                    {
                        vx = input.ReadRawBits(field.bits);
                        vy = input.ReadRawBits(field.bits);
                        vz = input.ReadRawBits(field.bits);
                        vw = input.ReadRawBits(field.bits);
                    }
                }

                if (!masked)
                {
                    hash = NetworkUtils.SimpleHashStreaming(hash, vx);
                    hash = NetworkUtils.SimpleHashStreaming(hash, vy);
                    hash = NetworkUtils.SimpleHashStreaming(hash, vz);
                    hash = NetworkUtils.SimpleHashStreaming(hash, vw);
                }

                outputStream.WriteUInt32(vx);
                outputStream.WriteUInt32(vy);
                outputStream.WriteUInt32(vz);
                outputStream.WriteUInt32(vw);
                break;
            }

            case NetworkSchema.FieldType.String:
            case NetworkSchema.FieldType.ByteArray:
            {
                // TODO : Do a better job with deltaing strings and buffers
                if (!skip)
                {
                    baselineStream.SkipByteArray(field.arraySize);
                    outputStream.CopyByteArray <TInputStream>(ref input, field.arraySize, fieldStartContext);
                }
                else
                {
                    outputStream.CopyByteArray(ref baselineStream, field.arraySize);
                }

                if (!masked)
                {
                    hash += 0;         // TODO (hash strings and bytearrays as well)
                }
            }
            break;
            }
        }
        outputStream.Flush();
        return(outputStream.GetBytePosition());
    }