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); }
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; }
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); }
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; } } } }
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()); }