private void OnP2PData(ulong steamId, byte[] data, int dataLength) { if (!isActive) { return; } if (steamId != hostSteamId) { return; } timeout = Screen.Selected == GameMain.GameScreen ? NetworkConnection.TimeoutThresholdInGame : NetworkConnection.TimeoutThreshold; byte incByte = data[0]; bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0; bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0; bool isDisconnectMessage = (incByte & (byte)PacketHeader.IsDisconnectMessage) != 0; bool isServerMessage = (incByte & (byte)PacketHeader.IsServerMessage) != 0; bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0; if (!isServerMessage) { return; } if (isConnectionInitializationStep) { ulong low = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8); ulong high = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8 + 32); ulong lobbyId = low + (high << 32); Steam.SteamManager.JoinLobby(lobbyId, false); IReadMessage inc = new ReadOnlyMessage(data, false, 1 + 8, dataLength - 9, ServerConnection); if (initializationStep != ConnectionInitialization.Success) { incomingInitializationMessages.Add(inc); } } else if (isHeartbeatMessage) { return; //TODO: implement heartbeats } else if (isDisconnectMessage) { IReadMessage inc = new ReadOnlyMessage(data, false, 1, dataLength - 1, ServerConnection); string msg = inc.ReadString(); Close(msg); OnDisconnectMessageReceived?.Invoke(msg); } else { UInt16 length = data[1]; length |= (UInt16)(((UInt32)data[2]) << 8); IReadMessage inc = new ReadOnlyMessage(data, isCompressed, 3, length, ServerConnection); incomingDataMessages.Add(inc); } }
private void OnConnectionFailed(Steamworks.SteamId steamId, Steamworks.P2PSessionError error) { if (!isActive) { return; } if (steamId != hostSteamId) { return; } Close($"SteamP2P connection failed: {error}"); OnDisconnectMessageReceived?.Invoke($"SteamP2P connection failed: {error}"); }
private void HandleStatusChanged(NetIncomingMessage inc) { if (!isActive) { return; } NetConnectionStatus status = (NetConnectionStatus)inc.ReadByte(); switch (status) { case NetConnectionStatus.Disconnected: string disconnectMsg = inc.ReadString(); Close(disconnectMsg); OnDisconnectMessageReceived?.Invoke(disconnectMsg); break; } }
public override void Update(float deltaTime) { if (!isActive) { return; } timeout -= deltaTime; heartbeatTimer -= deltaTime; if (initializationStep != ConnectionInitialization.Password && initializationStep != ConnectionInitialization.ContentPackageOrder && initializationStep != ConnectionInitialization.Success) { connectionStatusTimer -= deltaTime; if (connectionStatusTimer <= 0.0) { var state = Steamworks.SteamNetworking.GetP2PSessionState(hostSteamId); if (state == null) { Close("SteamP2P connection could not be established"); OnDisconnectMessageReceived?.Invoke("SteamP2P connection could not be established"); } else { if (state?.P2PSessionError != Steamworks.P2PSessionError.None) { Close($"SteamP2P error code: {state?.P2PSessionError}"); OnDisconnectMessageReceived?.Invoke($"SteamP2P error code: {state?.P2PSessionError}"); } } connectionStatusTimer = 1.0f; } } for (int i = 0; i < 100; i++) { if (!Steamworks.SteamNetworking.IsP2PPacketAvailable()) { break; } var packet = Steamworks.SteamNetworking.ReadP2PPacket(); if (packet.HasValue) { OnP2PData(packet?.SteamId ?? 0, packet?.Data, packet?.Data.Length ?? 0); receivedBytes += packet?.Data.Length ?? 0; } } GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.ReceivedBytes, receivedBytes); GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.SentBytes, sentBytes); if (heartbeatTimer < 0.0) { IWriteMessage outMsg = new WriteOnlyMessage(); outMsg.Write((byte)DeliveryMethod.Unreliable); outMsg.Write((byte)PacketHeader.IsHeartbeatMessage); Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Unreliable); sentBytes += outMsg.LengthBytes; heartbeatTimer = 5.0; } if (timeout < 0.0) { Close("Timed out"); OnDisconnectMessageReceived?.Invoke(""); return; } if (initializationStep != ConnectionInitialization.Success) { if (incomingDataMessages.Count > 0) { OnInitializationComplete?.Invoke(); initializationStep = ConnectionInitialization.Success; } else { foreach (IReadMessage inc in incomingInitializationMessages) { ReadConnectionInitializationStep(inc); } } } if (initializationStep == ConnectionInitialization.Success) { foreach (IReadMessage inc in incomingDataMessages) { OnMessageReceived?.Invoke(inc); } } incomingInitializationMessages.Clear(); incomingDataMessages.Clear(); }
public override void Update(float deltaTime) { if (!isActive) { return; } timeout -= deltaTime; heartbeatTimer -= deltaTime; for (int i = 0; i < 100; i++) { if (!Steamworks.SteamNetworking.IsP2PPacketAvailable()) { break; } var packet = Steamworks.SteamNetworking.ReadP2PPacket(); if (packet.HasValue) { OnP2PData(packet?.SteamId ?? 0, packet?.Data, packet?.Data.Length ?? 0, 0); } } if (heartbeatTimer < 0.0) { IWriteMessage outMsg = new WriteOnlyMessage(); outMsg.Write((byte)DeliveryMethod.Unreliable); outMsg.Write((byte)PacketHeader.IsHeartbeatMessage); Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Unreliable); heartbeatTimer = 5.0; } if (timeout < 0.0) { Close("Timed out"); OnDisconnectMessageReceived?.Invoke(""); return; } if (initializationStep != ConnectionInitialization.Success) { if (incomingDataMessages.Count > 0) { OnInitializationComplete?.Invoke(); initializationStep = ConnectionInitialization.Success; } else { foreach (IReadMessage inc in incomingInitializationMessages) { ReadConnectionInitializationStep(inc); } } } if (initializationStep == ConnectionInitialization.Success) { foreach (IReadMessage inc in incomingDataMessages) { OnMessageReceived?.Invoke(inc); } } incomingInitializationMessages.Clear(); incomingDataMessages.Clear(); }