public async void ConnectToId(SteamId hostId) { // Refuse to attempt another connection if one is active or in progress if (Active || Status == PeerStatus.CONNECTING) { Output.LogWarning($"{Name}: Attempted to connect while a previous connection is active or in progress"); return; } // Set timeout start time, set client active, and set client status to Connecting DateTime timeoutStart = DateTime.Now; // Set status appropriately _active = true; _status = PeerStatus.CONNECTING; try { // Send a request to connect byte[] sendData = new byte[] { (byte)PacketType.CONNECT }; SendPacket(hostId, sendData, sendData.Length); while (Status == PeerStatus.CONNECTING) { // Wait for a packet to arrive while (!IsPacketAvailable()) { TimeSpan timeoutChk = DateTime.Now - timeoutStart; if (timeoutChk.TotalMilliseconds >= MP_TIMEOUT) { throw new Exception("Timed out attempting to connect"); } await Task.Delay(TimeSpan.FromMilliseconds(TickRate)); } GetNextPacket(out P2Packet? packet); if (packet == null) { throw new Exception("Null packet received"); } // If the packet is not null, get data and sender SteamId byte[] data = packet.Value.Data; SteamId sender = packet.Value.SteamId; if (data.Length < 1 || data == null) { throw new Exception("Null or zero-length data array received"); } // Ignore packets sent by someone who isn't expected if (sender != hostId) { continue; } if (data[0] != (byte)PacketType.CONNECTION_ACCEPTED) { throw new Exception($"Unexpected response ({data[0]})"); } // Now connected to a new server, set status and refresh receive queue _status = PeerStatus.CONNECTED; _receiveQueue.Clear(); // Raise OnConnected event OnConnected?.Invoke(); } _host = hostId; } catch (Exception e) { Output.LogError($"{Name}: Error connecting to host ({e.Message})"); // If we catch an exception, reset active and status ResetStatus(); } }