void ReadClientInfo <TInputStream>(ref TInputStream input) where TInputStream : NetworkCompression.IInputStream { var newClientId = (int)input.ReadRawBits(8); serverTickRate = (int)input.ReadRawBits(8); // TODO (petera) remove this from here. This should only be handshake code. tickrate updated by other means like configvar uint serverProtocol = input.ReadRawBits(8); int modelSize = (int)input.ReadRawBits(16); if (modelSize > modelData.Length) { modelData = new byte[modelSize]; } for (int i = 0; i < modelSize; i++) { modelData[i] = (byte)input.ReadRawBits(8); } if (connectionState == ConnectionState.Connected) { GameDebug.Log("Ignoring ClientInfo as we are already connected"); return; } uint ourProtocol = NetworkConfig.protocolVersion; GameDebug.Log("Client protocol id: " + ourProtocol); GameDebug.Log("Server protocol id: " + serverProtocol); if (ourProtocol != serverProtocol) { if (clientVerifyProtocol.IntValue > 0) { GameDebug.LogError("Protocol mismatch. Server is: " + serverProtocol + " and we are: " + ourProtocol); connectionState = ConnectionState.Disconnected; return; } GameDebug.Log("Ignoring protocol difference client.verifyprotocol is 0"); } GameDebug.Assert(clientId == -1 || newClientId == clientId, "Repeated client info didn't match existing client id"); compressionModel = new NetworkCompressionModel(modelData); clientId = newClientId; connectionState = ConnectionState.Connected; if (clientDebug.IntValue > 0) { GameDebug.Log(string.Format("ReadClientInfo: clientId {0} serverTickRate {1}", newClientId, serverTickRate)); } }
public void ReadPackage <TInputStream>(byte[] packageData, int packageSize, NetworkCompressionModel compressionModel, INetworkClientCallbacks networkClientConsumer, ISnapshotConsumer snapshotConsumer) where TInputStream : struct, NetworkCompression.IInputStream { counters.bytesIn += packageSize; NetworkMessage content; byte[] assembledData; int assembledSize; int headerSize; var packageSequence = ProcessPackageHeader(packageData, packageSize, out content, out assembledData, out assembledSize, out headerSize); // Reset stats counters.ClearSectionStats(); counters.AddSectionStats("header", headerSize * 8, Color.white); // The package was dropped (duplicate or too old) or if it was a fragment not yet assembled, bail out here if (packageSequence == 0) { return; } var input = default(TInputStream); // new TInputStream(); due to bug new generates garbage here input.Initialize(compressionModel, assembledData, headerSize); if ((content & NetworkMessage.ClientInfo) != 0) { ReadClientInfo(ref input); } counters.AddSectionStats("clientInfo", input.GetBitPosition2(), Color.green); if ((content & NetworkMessage.MapInfo) != 0) { ReadMapInfo(ref input); } counters.AddSectionStats("mapInfo", input.GetBitPosition2(), new Color(0.65f, 0.16f, 0.16f)); // The package was received out of order but older than the last map reset, // so we ignore the remaining data if (mapInfo.ackSequence == 0 || packageSequence < mapInfo.ackSequence) { return; } if ((content & NetworkMessage.Snapshot) != 0) { ReadSnapshot(packageSequence, ref input, snapshotConsumer); // Make sure the callback actually picked up the snapshot data. It is important that // every snapshot gets processed by the game so that the spawns, despawns and updates lists // does not end up containing stuff from different snapshots GameDebug.Assert(spawns.Count == 0 && despawns.Count == 0 && updates.Count == 0, "Game did not consume snapshots"); } // We have to skip this if we dropped snapshot as we will then be in the middle of the input stream if ((content & NetworkMessage.Events) != 0 && !m_DropSnapshots) { ReadEvents(ref input, networkClientConsumer); } counters.AddSectionStats("events", input.GetBitPosition2(), new Color(1.0f, 0.84f, 0.0f)); counters.AddSectionStats("unknown", assembledSize * 8, Color.black); counters.packageContentStatsPackageSequence = packageSequence; }