private void HandleDataMessage(NetIncomingMessage inc) { if (!isActive) { return; } byte incByte = inc.ReadByte(); bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0; bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0; //DebugConsole.NewMessage(isCompressed + " " + isConnectionInitializationStep + " " + (int)incByte); if (isConnectionInitializationStep && initializationStep != ConnectionInitialization.Success) { ReadConnectionInitializationStep(inc); } else { if (initializationStep != ConnectionInitialization.Success) { OnInitializationComplete?.Invoke(); initializationStep = ConnectionInitialization.Success; } UInt16 length = inc.ReadUInt16(); IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, ServerConnection); OnMessageReceived?.Invoke(msg); } }
public override void Update(float deltaTime) { if (!isActive) { return; } timeout -= deltaTime; heartbeatTimer -= deltaTime; if (heartbeatTimer < 0.0) { IWriteMessage outMsg = new WriteOnlyMessage(); outMsg.Write((byte)DeliveryMethod.Unreliable); outMsg.Write((byte)PacketHeader.IsHeartbeatMessage); SteamManager.Instance.Networking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, Facepunch.Steamworks.Networking.SendType.Unreliable); heartbeatTimer = 5.0; } if (timeout < 0.0) { Close("Timed out"); 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; 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(); }
private void UpdatePendingClient(PendingClient pendingClient) { if (netServer == null) { return; } if (serverSettings.BanList.IsBanned(pendingClient.SteamID)) { RemovePendingClient(pendingClient, DisconnectReason.Banned, "Initialization interrupted by ban"); return; } //DebugConsole.NewMessage("pending client status: " + pendingClient.InitializationStep); if (connectedClients.Count >= serverSettings.MaxPlayers - 1) { RemovePendingClient(pendingClient, DisconnectReason.ServerFull, ""); } if (pendingClient.InitializationStep == ConnectionInitialization.Success) { SteamP2PConnection newConnection = new SteamP2PConnection(pendingClient.Name, pendingClient.SteamID) { Status = NetworkConnectionStatus.Connected }; connectedClients.Add(newConnection); pendingClients.Remove(pendingClient); OnInitializationComplete?.Invoke(newConnection); } pendingClient.TimeOut -= Timing.Step; if (pendingClient.TimeOut < 0.0) { RemovePendingClient(pendingClient, DisconnectReason.Unknown, Lidgren.Network.NetConnection.NoResponseMessage); } if (Timing.TotalTime < pendingClient.UpdateTime) { return; } pendingClient.UpdateTime = Timing.TotalTime + 1.0; NetOutgoingMessage outMsg = netServer.CreateMessage(); outMsg.Write(pendingClient.SteamID); outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep | PacketHeader.IsServerMessage)); outMsg.Write((byte)pendingClient.InitializationStep); switch (pendingClient.InitializationStep) { case ConnectionInitialization.Password: outMsg.Write(pendingClient.PasswordSalt == null); outMsg.WritePadBits(); if (pendingClient.PasswordSalt == null) { pendingClient.PasswordSalt = CryptoRandom.Instance.Next(); outMsg.Write(pendingClient.PasswordSalt.Value); } else { outMsg.Write(pendingClient.Retries); } break; } if (netConnection != null) { NetSendResult result = netServer.SendMessage(outMsg, netConnection, NetDeliveryMethod.ReliableUnordered); if (result != NetSendResult.Sent && result != NetSendResult.Queued) { DebugConsole.NewMessage("Failed to send initialization step " + pendingClient.InitializationStep.ToString() + " to pending client: " + result.ToString(), Microsoft.Xna.Framework.Color.Yellow); } } }
private void HandleDataMessage(NetIncomingMessage inc) { if (netServer == null) { return; } if (inc.SenderConnection != netConnection) { return; } UInt64 senderSteamId = inc.ReadUInt64(); byte incByte = inc.ReadByte(); 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) { DebugConsole.ThrowError("Got server message from" + senderSteamId.ToString()); return; } if (senderSteamId != OwnerSteamID) //sender is remote, handle disconnects and heartbeats { PendingClient pendingClient = pendingClients.Find(c => c.SteamID == senderSteamId); SteamP2PConnection connectedClient = connectedClients.Find(c => c.SteamID == senderSteamId); pendingClient?.Heartbeat(); connectedClient?.Heartbeat(); if (serverSettings.BanList.IsBanned(senderSteamId)) { if (pendingClient != null) { RemovePendingClient(pendingClient, DisconnectReason.Banned, "Banned"); } else if (connectedClient != null) { Disconnect(connectedClient, DisconnectReason.Banned.ToString() + "/ Banned"); } return; } else if (isDisconnectMessage) { if (pendingClient != null) { string disconnectMsg = $"ServerMessage.HasDisconnected~[client]={pendingClient.Name}"; RemovePendingClient(pendingClient, DisconnectReason.Unknown, disconnectMsg); } else if (connectedClient != null) { string disconnectMsg = $"ServerMessage.HasDisconnected~[client]={connectedClient.Name}"; Disconnect(connectedClient, disconnectMsg, false); } return; } else if (isHeartbeatMessage) { //message exists solely as a heartbeat, ignore its contents return; } else if (isConnectionInitializationStep) { if (pendingClient != null) { ReadConnectionInitializationStep(pendingClient, new ReadOnlyMessage(inc.Data, false, inc.PositionInBytes, inc.LengthBytes - inc.PositionInBytes, null)); } else { ConnectionInitialization initializationStep = (ConnectionInitialization)inc.ReadByte(); if (initializationStep == ConnectionInitialization.ConnectionStarted) { pendingClients.Add(new PendingClient(senderSteamId)); } } } else if (connectedClient != null) { UInt16 length = inc.ReadUInt16(); IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, connectedClient); OnMessageReceived?.Invoke(connectedClient, msg); } } else //sender is owner { if (OwnerConnection != null) { (OwnerConnection as SteamP2PConnection).Heartbeat(); } if (isDisconnectMessage) { DebugConsole.ThrowError("Received disconnect message from owner"); return; } if (isServerMessage) { DebugConsole.ThrowError("Received server message from owner"); return; } if (isConnectionInitializationStep) { if (OwnerConnection == null) { string ownerName = inc.ReadString(); OwnerConnection = new SteamP2PConnection(ownerName, OwnerSteamID) { Status = NetworkConnectionStatus.Connected }; OnInitializationComplete?.Invoke(OwnerConnection); } return; } if (isHeartbeatMessage) { return; } else { UInt16 length = inc.ReadUInt16(); IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, OwnerConnection); OnMessageReceived?.Invoke(OwnerConnection, msg); } } }
private void UpdatePendingClient(PendingClient pendingClient) { if (!started) { return; } if (serverSettings.BanList.IsBanned(pendingClient.SteamID, out string banReason)) { RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason); return; } //DebugConsole.NewMessage("pending client status: " + pendingClient.InitializationStep); if (connectedClients.Count >= serverSettings.MaxPlayers - 1) { RemovePendingClient(pendingClient, DisconnectReason.ServerFull, ""); } if (pendingClient.InitializationStep == ConnectionInitialization.Success) { SteamP2PConnection newConnection = new SteamP2PConnection(pendingClient.Name, pendingClient.SteamID) { Status = NetworkConnectionStatus.Connected }; connectedClients.Add(newConnection); pendingClients.Remove(pendingClient); OnInitializationComplete?.Invoke(newConnection); } pendingClient.TimeOut -= Timing.Step; if (pendingClient.TimeOut < 0.0) { RemovePendingClient(pendingClient, DisconnectReason.Unknown, Lidgren.Network.NetConnection.NoResponseMessage); } if (Timing.TotalTime < pendingClient.UpdateTime) { return; } pendingClient.UpdateTime = Timing.TotalTime + 1.0; IWriteMessage outMsg = new WriteOnlyMessage(); outMsg.Write(pendingClient.SteamID); outMsg.Write((byte)DeliveryMethod.Reliable); outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep | PacketHeader.IsServerMessage)); outMsg.Write((byte)pendingClient.InitializationStep); switch (pendingClient.InitializationStep) { case ConnectionInitialization.ContentPackageOrder: var mpContentPackages = GameMain.SelectedPackages.Where(cp => cp.HasMultiplayerIncompatibleContent).ToList(); outMsg.WriteVariableUInt32((UInt32)mpContentPackages.Count); for (int i = 0; i < mpContentPackages.Count; i++) { outMsg.Write(mpContentPackages[i].MD5hash.Hash); } break; case ConnectionInitialization.Password: outMsg.Write(pendingClient.PasswordSalt == null); outMsg.WritePadBits(); if (pendingClient.PasswordSalt == null) { pendingClient.PasswordSalt = Lidgren.Network.CryptoRandom.Instance.Next(); outMsg.Write(pendingClient.PasswordSalt.Value); } else { outMsg.Write(pendingClient.Retries); } break; } byte[] msgToSend = (byte[])outMsg.Buffer.Clone(); Array.Resize(ref msgToSend, outMsg.LengthBytes); ChildServerRelay.Write(msgToSend); }
private void HandleDataMessage(IReadMessage inc) { if (!isActive) { return; } UInt64 recipientSteamId = inc.ReadUInt64(); DeliveryMethod deliveryMethod = (DeliveryMethod)inc.ReadByte(); int p2pDataStart = inc.BytePosition; byte incByte = inc.ReadByte(); 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 (recipientSteamId != selfSteamID) { if (!isServerMessage) { DebugConsole.ThrowError("Received non-server message meant for remote peer"); return; } RemotePeer peer = remotePeers.Find(p => p.SteamID == recipientSteamId); if (peer == null) { return; } if (isDisconnectMessage) { DisconnectPeer(peer, inc.ReadString()); return; } Steamworks.P2PSend sendType; switch (deliveryMethod) { case DeliveryMethod.Reliable: case DeliveryMethod.ReliableOrdered: //the documentation seems to suggest that the Reliable send type //enforces packet order (TODO: verify) sendType = Steamworks.P2PSend.Reliable; break; default: sendType = Steamworks.P2PSend.Unreliable; break; } byte[] p2pData; if (isConnectionInitializationStep) { p2pData = new byte[inc.LengthBytes - p2pDataStart + 8]; p2pData[0] = inc.Buffer[p2pDataStart]; Lidgren.Network.NetBitWriter.WriteUInt64(SteamManager.CurrentLobbyID, 64, p2pData, 8); Array.Copy(inc.Buffer, p2pDataStart + 1, p2pData, 9, inc.LengthBytes - p2pDataStart - 1); } else { p2pData = new byte[inc.LengthBytes - p2pDataStart]; Array.Copy(inc.Buffer, p2pDataStart, p2pData, 0, p2pData.Length); } if (p2pData.Length + 4 >= MsgConstants.MTU) { DebugConsole.Log("WARNING: message length comes close to exceeding MTU, forcing reliable send (" + p2pData.Length.ToString() + " bytes)"); sendType = Steamworks.P2PSend.Reliable; } bool successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, 0, sendType); sentBytes += p2pData.Length; if (!successSend) { if (sendType != Steamworks.P2PSend.Reliable) { DebugConsole.Log("WARNING: message couldn't be sent unreliably, forcing reliable send (" + p2pData.Length.ToString() + " bytes)"); sendType = Steamworks.P2PSend.Reliable; successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, 0, sendType); sentBytes += p2pData.Length; } if (!successSend) { DebugConsole.ThrowError("Failed to send message to remote peer! (" + p2pData.Length.ToString() + " bytes)"); } } } else { if (isDisconnectMessage) { DebugConsole.ThrowError("Received disconnect message from owned server"); return; } if (!isServerMessage) { DebugConsole.ThrowError("Received non-server message from owned server"); return; } if (isHeartbeatMessage) { return; //timeout is handled by Lidgren, ignore this message } if (isConnectionInitializationStep) { IWriteMessage outMsg = new WriteOnlyMessage(); outMsg.Write(selfSteamID); outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep)); outMsg.Write(Name); byte[] msgToSend = (byte[])outMsg.Buffer.Clone(); Array.Resize(ref msgToSend, outMsg.LengthBytes); ChildServerRelay.Write(msgToSend); return; } else { if (initializationStep != ConnectionInitialization.Success) { OnInitializationComplete?.Invoke(); initializationStep = ConnectionInitialization.Success; } UInt16 length = inc.ReadUInt16(); IReadMessage msg = new ReadOnlyMessage(inc.Buffer, isCompressed, inc.BytePosition, length, ServerConnection); OnMessageReceived?.Invoke(msg); return; } } }
private void UpdatePendingClient(PendingClient pendingClient, float deltaTime) { if (netServer == null) { return; } if (serverSettings.BanList.IsBanned(pendingClient.Connection.RemoteEndPoint.Address, pendingClient.SteamID ?? 0, out string banReason)) { RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason); return; } //DebugConsole.NewMessage("pending client status: " + pendingClient.InitializationStep); if (connectedClients.Count >= serverSettings.MaxPlayers) { RemovePendingClient(pendingClient, DisconnectReason.ServerFull, ""); } if (pendingClient.InitializationStep == ConnectionInitialization.Success) { LidgrenConnection newConnection = new LidgrenConnection(pendingClient.Name, pendingClient.Connection, pendingClient.SteamID ?? 0) { Status = NetworkConnectionStatus.Connected }; connectedClients.Add(newConnection); pendingClients.Remove(pendingClient); if (OwnerConnection == null && IPAddress.IsLoopback(pendingClient.Connection.RemoteEndPoint.Address.MapToIPv4NoThrow()) && ownerKey != null && pendingClient.OwnerKey != 0 && pendingClient.OwnerKey == ownerKey) { ownerKey = null; OwnerConnection = newConnection; } OnInitializationComplete?.Invoke(newConnection); return; } pendingClient.TimeOut -= deltaTime; if (pendingClient.TimeOut < 0.0) { RemovePendingClient(pendingClient, DisconnectReason.Unknown, Lidgren.Network.NetConnection.NoResponseMessage); } if (Timing.TotalTime < pendingClient.UpdateTime) { return; } pendingClient.UpdateTime = Timing.TotalTime + 1.0; NetOutgoingMessage outMsg = netServer.CreateMessage(); outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep); outMsg.Write((byte)pendingClient.InitializationStep); switch (pendingClient.InitializationStep) { case ConnectionInitialization.ContentPackageOrder: var mpContentPackages = GameMain.SelectedPackages.Where(cp => cp.HasMultiplayerIncompatibleContent).ToList(); outMsg.WriteVariableInt32(mpContentPackages.Count); for (int i = 0; i < mpContentPackages.Count; i++) { outMsg.Write(mpContentPackages[i].MD5hash.Hash); } break; case ConnectionInitialization.Password: outMsg.Write(pendingClient.PasswordSalt == null); outMsg.WritePadBits(); if (pendingClient.PasswordSalt == null) { pendingClient.PasswordSalt = CryptoRandom.Instance.Next(); outMsg.Write(pendingClient.PasswordSalt.Value); } else { outMsg.Write(pendingClient.Retries); } break; } #if DEBUG netPeerConfiguration.SimulatedDuplicatesChance = GameMain.Server.SimulatedDuplicatesChance; netPeerConfiguration.SimulatedMinimumLatency = GameMain.Server.SimulatedMinimumLatency; netPeerConfiguration.SimulatedRandomLatency = GameMain.Server.SimulatedRandomLatency; netPeerConfiguration.SimulatedLoss = GameMain.Server.SimulatedLoss; #endif NetSendResult result = netServer.SendMessage(outMsg, pendingClient.Connection, NetDeliveryMethod.ReliableUnordered); if (result != NetSendResult.Sent && result != NetSendResult.Queued) { DebugConsole.NewMessage("Failed to send initialization step " + pendingClient.InitializationStep.ToString() + " to pending client: " + result.ToString(), Microsoft.Xna.Framework.Color.Yellow); } //DebugConsole.NewMessage("sent update to pending client: " + pendingClient.InitializationStep); }
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(); }
private void HandleDataMessage(NetIncomingMessage inc) { if (!isActive) { return; } UInt64 recipientSteamId = inc.ReadUInt64(); int p2pDataStart = inc.PositionInBytes; byte incByte = inc.ReadByte(); 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 (recipientSteamId != selfSteamID) { if (!isServerMessage) { DebugConsole.ThrowError("Received non-server message meant for remote peer"); return; } RemotePeer peer = remotePeers.Find(p => p.SteamID == recipientSteamId); if (peer == null) { return; } if (isDisconnectMessage) { DisconnectPeer(peer, inc.ReadString()); return; } Facepunch.Steamworks.Networking.SendType sendType; switch (inc.DeliveryMethod) { case NetDeliveryMethod.ReliableUnordered: case NetDeliveryMethod.ReliableSequenced: case NetDeliveryMethod.ReliableOrdered: //the documentation seems to suggest that the Reliable send type //enforces packet order (TODO: verify) sendType = Facepunch.Steamworks.Networking.SendType.Reliable; break; default: sendType = Facepunch.Steamworks.Networking.SendType.Unreliable; break; } byte[] p2pData; if (isConnectionInitializationStep) { p2pData = new byte[inc.LengthBytes - p2pDataStart + 8]; p2pData[0] = inc.Data[p2pDataStart]; Lidgren.Network.NetBitWriter.WriteUInt64(Steam.SteamManager.Instance.Lobby.CurrentLobby, 64, p2pData, 8); Array.Copy(inc.Data, p2pDataStart + 1, p2pData, 9, inc.LengthBytes - p2pDataStart - 1); } else { p2pData = new byte[inc.LengthBytes - p2pDataStart]; Array.Copy(inc.Data, p2pDataStart, p2pData, 0, p2pData.Length); } if (p2pData.Length + 4 >= MsgConstants.MTU) { DebugConsole.Log("WARNING: message length comes close to exceeding MTU, forcing reliable send (" + p2pData.Length.ToString() + " bytes)"); sendType = Facepunch.Steamworks.Networking.SendType.Reliable; } bool successSend = Steam.SteamManager.Instance.Networking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, sendType); if (!successSend) { if (sendType != Facepunch.Steamworks.Networking.SendType.Reliable) { DebugConsole.Log("WARNING: message couldn't be sent unreliably, forcing reliable send (" + p2pData.Length.ToString() + " bytes)"); sendType = Facepunch.Steamworks.Networking.SendType.Reliable; successSend = Steam.SteamManager.Instance.Networking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, sendType); } if (!successSend) { DebugConsole.ThrowError("Failed to send message to remote peer! (" + p2pData.Length.ToString() + " bytes)"); } } } else { if (isDisconnectMessage) { DebugConsole.ThrowError("Received disconnect message from owned server"); return; } if (!isServerMessage) { DebugConsole.ThrowError("Received non-server message from owned server"); return; } if (isHeartbeatMessage) { return; //timeout is handled by Lidgren, ignore this message } if (isConnectionInitializationStep) { NetOutgoingMessage outMsg = netClient.CreateMessage(); outMsg.Write(selfSteamID); outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep)); outMsg.Write(Name); NetSendResult result = netClient.SendMessage(outMsg, NetDeliveryMethod.ReliableUnordered); if (result != NetSendResult.Queued && result != NetSendResult.Sent) { DebugConsole.NewMessage("Failed to send initialization message to host: " + result); } return; } else { if (initializationStep != ConnectionInitialization.Success) { OnInitializationComplete?.Invoke(); initializationStep = ConnectionInitialization.Success; } UInt16 length = inc.ReadUInt16(); IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, ServerConnection); OnMessageReceived?.Invoke(msg); return; } } }
private void UpdatePendingClient(PendingClient pendingClient, float deltaTime) { if (netServer == null) { return; } if (serverSettings.BanList.IsBanned(pendingClient.Connection.RemoteEndPoint.Address, pendingClient.SteamID ?? 0)) { RemovePendingClient(pendingClient, DisconnectReason.Banned.ToString()); return; } //DebugConsole.NewMessage("pending client status: " + pendingClient.InitializationStep); if (connectedClients.Count >= serverSettings.MaxPlayers) { RemovePendingClient(pendingClient, DisconnectReason.ServerFull.ToString()); } if (pendingClient.InitializationStep == ConnectionInitialization.Success) { LidgrenConnection newConnection = new LidgrenConnection(pendingClient.Name, pendingClient.Connection, pendingClient.SteamID ?? 0); newConnection.Status = NetworkConnectionStatus.Connected; connectedClients.Add(newConnection); pendingClients.Remove(pendingClient); if (OwnerConnection == null && IPAddress.IsLoopback(pendingClient.Connection.RemoteEndPoint.Address.MapToIPv4()) && ownerKey != null && pendingClient.OwnerKey != 0 && pendingClient.OwnerKey == ownerKey) { ownerKey = null; OwnerConnection = newConnection; } OnInitializationComplete?.Invoke(newConnection); return; } pendingClient.TimeOut -= deltaTime; if (pendingClient.TimeOut < 0.0) { RemovePendingClient(pendingClient, Lidgren.Network.NetConnection.NoResponseMessage); } if (Timing.TotalTime < pendingClient.UpdateTime) { return; } pendingClient.UpdateTime = Timing.TotalTime + 1.0; NetOutgoingMessage outMsg = netServer.CreateMessage(); outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep); outMsg.Write((byte)pendingClient.InitializationStep); switch (pendingClient.InitializationStep) { case ConnectionInitialization.Password: outMsg.Write(pendingClient.PasswordSalt == null); outMsg.WritePadBits(); if (pendingClient.PasswordSalt == null) { pendingClient.PasswordSalt = CryptoRandom.Instance.Next(); outMsg.Write(pendingClient.PasswordSalt.Value); } else { outMsg.Write(pendingClient.Retries); } break; } NetSendResult result = netServer.SendMessage(outMsg, pendingClient.Connection, NetDeliveryMethod.ReliableUnordered); if (result != NetSendResult.Sent && result != NetSendResult.Queued) { DebugConsole.NewMessage("Failed to send initialization step " + pendingClient.InitializationStep.ToString() + " to pending client: " + result.ToString(), Microsoft.Xna.Framework.Color.Yellow); } //DebugConsole.NewMessage("sent update to pending client: "+result); }