protected override void SendMsgInternal(NetworkConnection conn, DeliveryMethod deliveryMethod, IWriteMessage msg) { LidgrenConnection lidgrenConn = conn as LidgrenConnection; NetDeliveryMethod lidgrenDeliveryMethod = NetDeliveryMethod.Unreliable; switch (deliveryMethod) { case DeliveryMethod.Unreliable: lidgrenDeliveryMethod = NetDeliveryMethod.Unreliable; break; case DeliveryMethod.Reliable: lidgrenDeliveryMethod = NetDeliveryMethod.ReliableUnordered; break; case DeliveryMethod.ReliableOrdered: lidgrenDeliveryMethod = NetDeliveryMethod.ReliableOrdered; break; } NetOutgoingMessage lidgrenMsg = netServer.CreateMessage(); lidgrenMsg.Write(msg.Buffer, 0, msg.LengthBytes); NetSendResult result = netServer.SendMessage(lidgrenMsg, lidgrenConn.NetConnection, lidgrenDeliveryMethod); if (result != NetSendResult.Sent && result != NetSendResult.Queued) { DebugConsole.NewMessage("Failed to send message to " + conn.Name + ": " + result.ToString(), Microsoft.Xna.Framework.Color.Yellow); } }
public override void Start(object endPoint, int ownerKey) { if (isActive) { return; } netPeerConfiguration = new NetPeerConfiguration("barotrauma"); netPeerConfiguration.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt | NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error); netClient = new NetClient(netPeerConfiguration); incomingLidgrenMessages = new List <NetIncomingMessage>(); initializationStep = ConnectionInitialization.SteamTicketAndVersion; IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Loopback, Steam.SteamManager.STEAMP2P_OWNER_PORT); netClient.Start(); ServerConnection = new LidgrenConnection("Server", netClient.Connect(ipEndPoint), 0); ServerConnection.Status = NetworkConnectionStatus.Connected; remotePeers = new List <RemotePeer>(); Steam.SteamManager.Instance.Networking.OnIncomingConnection = OnIncomingConnection; Steam.SteamManager.Instance.Networking.OnP2PData = OnP2PData; Steam.SteamManager.Instance.Networking.SetListenChannel(0, true); Steam.SteamManager.Instance.Auth.OnAuthChange = OnAuthChange; isActive = true; }
public override void Start(object endPoint, int ownerKey) { if (isActive) { return; } this.ownerKey = ownerKey; contentPackageOrderReceived = false; netPeerConfiguration = new NetPeerConfiguration("barotrauma") { UseDualModeSockets = GameMain.Config.UseDualModeSockets }; netPeerConfiguration.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt | NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error); netClient = new NetClient(netPeerConfiguration); if (SteamManager.IsInitialized) { steamAuthTicket = SteamManager.GetAuthSessionTicket(); //TODO: wait for GetAuthSessionTicketResponse_t if (steamAuthTicket == null) { throw new Exception("GetAuthSessionTicket returned null"); } } incomingLidgrenMessages = new List <NetIncomingMessage>(); initializationStep = ConnectionInitialization.SteamTicketAndVersion; if (!(endPoint is IPEndPoint ipEndPoint)) { throw new InvalidCastException("endPoint is not IPEndPoint"); } if (ServerConnection != null) { throw new InvalidOperationException("ServerConnection is not null"); } netClient.Start(); ServerConnection = new LidgrenConnection("Server", netClient.Connect(ipEndPoint), 0) { Status = NetworkConnectionStatus.Connected }; isActive = true; }
protected override void CheckOwnership(PendingClient pendingClient) { LidgrenConnection l = pendingClient.Connection as LidgrenConnection; if (OwnerConnection == null && IPAddress.IsLoopback(l.NetConnection.RemoteEndPoint.Address.MapToIPv4NoThrow()) && ownerKey != null && pendingClient.OwnerKey != 0 && pendingClient.OwnerKey == ownerKey) { ownerKey = null; OwnerConnection = pendingClient.Connection; } }
private void HandleDataMessage(NetIncomingMessage inc) { if (netServer == null) { return; } PendingClient pendingClient = pendingClients.Find(c => c.Connection == inc.SenderConnection); byte incByte = inc.ReadByte(); bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0; bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0; if (isConnectionInitializationStep && pendingClient != null) { ReadConnectionInitializationStep(pendingClient, inc); } else if (!isConnectionInitializationStep) { LidgrenConnection conn = connectedClients.Find(c => c.NetConnection == inc.SenderConnection); if (conn == null) { if (pendingClient != null) { RemovePendingClient(pendingClient, DisconnectReason.AuthenticationRequired, "Received data message from unauthenticated client"); } else if (inc.SenderConnection.Status != NetConnectionStatus.Disconnected && inc.SenderConnection.Status != NetConnectionStatus.Disconnecting) { inc.SenderConnection.Disconnect(DisconnectReason.AuthenticationRequired.ToString() + "/ Received data message from unauthenticated client"); } return; } if (pendingClient != null) { pendingClients.Remove(pendingClient); } if (serverSettings.BanList.IsBanned(conn.IPEndPoint.Address, conn.SteamID, out string banReason)) { Disconnect(conn, DisconnectReason.Banned.ToString() + "/ " + banReason); return; } UInt16 length = inc.ReadUInt16(); //DebugConsole.NewMessage(isCompressed + " " + isConnectionInitializationStep + " " + (int)incByte + " " + length); IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, conn); OnMessageReceived?.Invoke(conn, msg); } }
private void OnAuthChange(Steamworks.SteamId steamID, Steamworks.SteamId ownerID, Steamworks.AuthResponse status) { if (netServer == null) { return; } PendingClient pendingClient = pendingClients.Find(c => c.SteamID == steamID); DebugConsole.Log(steamID + " validation: " + status + ", " + (pendingClient != null)); if (pendingClient == null) { if (status != Steamworks.AuthResponse.OK) { LidgrenConnection connection = connectedClients.Find(c => c.SteamID == steamID) as LidgrenConnection; if (connection != null) { Disconnect(connection, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam authentication status changed: " + status.ToString()); } } return; } LidgrenConnection pendingConnection = pendingClient.Connection as LidgrenConnection; string banReason; if (serverSettings.BanList.IsBanned(pendingConnection.NetConnection.RemoteEndPoint.Address, steamID, ownerID, out banReason)) { RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason); return; } if (status == Steamworks.AuthResponse.OK) { pendingClient.OwnerSteamID = ownerID; pendingClient.InitializationStep = serverSettings.HasPassword ? ConnectionInitialization.Password : ConnectionInitialization.ContentPackageOrder; pendingClient.UpdateTime = Timing.TotalTime; } else { RemovePendingClient(pendingClient, DisconnectReason.SteamAuthenticationFailed, "Steam authentication failed: " + status.ToString()); return; } }
private void OnAuthChange(ulong steamID, ulong ownerID, ServerAuth.Status status) { if (netServer == null) { return; } PendingClient pendingClient = pendingClients.Find(c => c.SteamID == steamID); DebugConsole.Log(steamID + " validation: " + status + ", " + (pendingClient != null)); if (pendingClient == null) { if (status != ServerAuth.Status.OK) { LidgrenConnection connection = connectedClients.Find(c => c.SteamID == steamID); if (connection != null) { Disconnect(connection, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam authentication status changed: " + status.ToString()); } } return; } if (serverSettings.BanList.IsBanned(pendingClient.Connection.RemoteEndPoint.Address, steamID)) { RemovePendingClient(pendingClient, DisconnectReason.Banned, "SteamID banned"); return; } if (status == ServerAuth.Status.OK) { pendingClient.InitializationStep = serverSettings.HasPassword ? ConnectionInitialization.Password : ConnectionInitialization.Success; pendingClient.UpdateTime = Timing.TotalTime; } else { RemovePendingClient(pendingClient, DisconnectReason.SteamAuthenticationFailed, "Steam authentication failed: " + status.ToString()); return; } }
private void HandleStatusChanged(NetIncomingMessage inc) { if (netServer == null) { return; } switch (inc.SenderConnection.Status) { case NetConnectionStatus.Disconnected: string disconnectMsg; LidgrenConnection conn = connectedClients.Find(c => c.NetConnection == inc.SenderConnection); if (conn != null) { if (conn == OwnerConnection) { DebugConsole.NewMessage("Owner disconnected: closing the server..."); GameServer.Log("Owner disconnected: closing the server...", ServerLog.MessageType.ServerMessage); Close(DisconnectReason.ServerShutdown.ToString() + "/ Owner disconnected"); } else { disconnectMsg = $"ServerMessage.HasDisconnected~[client]={conn.Name}"; Disconnect(conn, disconnectMsg); } } else { PendingClient pendingClient = pendingClients.Find(c => c.Connection == inc.SenderConnection); if (pendingClient != null) { disconnectMsg = $"ServerMessage.HasDisconnected~[client]={pendingClient.Name}"; RemovePendingClient(pendingClient, disconnectMsg); } } break; } }
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); }
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); }