private void ReadDataEvent(NetworkConnection connection, DataStreamReader streamReader) { try { int senderActorNumber = connection.InternalId; int command = streamReader.ReadInt(); switch (command) { case Commands.AcknowledgeActorNumber: { if (_acceptAllPlayers) { AcceptPlayer(senderActorNumber); } break; } case Commands.PlayerData: { string playerData = streamReader.ReadManagedString(); PlayerDataReceived?.Invoke(senderActorNumber, playerData); break; } case Commands.Ping: _lastPingTimes[connection] = Time; float sendLocalTime = streamReader.ReadFloat(); DataStreamWriter writer = _serverDriver.BeginSend(_unreliablePipeline, connection); writer.WriteInt(Commands.Ping); writer.WriteFloat(sendLocalTime); writer.WriteFloat(Time); writer.WriteFloat(UnityEngine.Time.deltaTime); _serverDriver.EndSend(writer); break; case Commands.RequestSpawnMessage: { var connections = new NativeList <NetworkConnection>(1, Allocator.Temp) { connection }; SendSpawnMessage(NetObjectManager.Instance.NetObjects, connections); connections.Dispose(); break; } case Commands.UpdateNetObjects: { int objectsInMessage = streamReader.ReadInt(); for (var obj = 0; obj < objectsInMessage; obj++) { int netObjID = streamReader.ReadInt(); int size = streamReader.ReadInt(); NetObject netObject = NetObjectManager.Instance.Exists(netObjID) ? NetObjectManager.Instance.Get(netObjID) : null; // ignore illegal updates and those from local host client if (netObject == null || netObject.OwnerActorNumber != senderActorNumber || // cheater? Client.IsHost && Client.Instance.ActorNumber == senderActorNumber) { streamReader.DiscardBytes(size); } else { int bytesRead = streamReader.GetBytesRead(); try { netObject.Deserialize(ref streamReader, b => b.ClientAuthoritative); } catch (Exception e) { Debug.LogException(e); int remainingBytes = size + bytesRead - streamReader.GetBytesRead(); streamReader.DiscardBytes(remainingBytes); } } } break; } case Commands.GameAction: { int gameActionID = streamReader.ReadInt(); int actorNumber = streamReader.ReadInt(); float triggerTime = streamReader.ReadFloat(); try { GameAction gameAction = GameActionManager.Instance.Get(gameActionID); GameAction.IParameters parameters = gameAction.DeserializeParameters(ref streamReader); gameAction.ReceiveOnServer(parameters, actorNumber, senderActorNumber, triggerTime); break; } catch (Exception e) { Debug.LogException(e); break; } } case Commands.NetAssetRPC: { float sentServerTime = streamReader.ReadFloat(); int netAssetID = streamReader.ReadInt(); NetAsset netAsset = NetAssetManager.Instance.Get(netAssetID); NetAsset.RPC rpc = netAsset.DeserializeRPC(ref streamReader); var messageInfo = new MessageInfo { SentServerTime = sentServerTime, SenderActorNumber = senderActorNumber }; rpc.Invoke(messageInfo); break; } case Commands.NetObjectRPC: { float sentServerTime = streamReader.ReadFloat(); int netObjectID = streamReader.ReadInt(); if (!NetObjectManager.Instance.Exists(netObjectID)) { Debug.LogWarning("Ignoring received RPC, because NetObject was not found."); break; } NetObject netObject = NetObjectManager.Instance.Get(netObjectID); ushort netBehaviourID = streamReader.ReadUShort(); NetBehaviour netBehaviour = netObject.Get(netBehaviourID); NetObjectManager.RPC rpc = NetObjectManager.Instance.DeserializeRPC(ref streamReader, netBehaviour); var messageInfo = new MessageInfo { SentServerTime = sentServerTime, SenderActorNumber = senderActorNumber }; rpc.Invoke(messageInfo); break; } default: Debug.LogException(new NetException($"Unknown command {command}")); break; } } catch (Exception e) { Debug.LogException(new NetException("Failed to handle data event", e)); } }