/// <summary> /// Sets up Socket ready to send data to endpoint as a client /// </summary> /// <param name="endPoint"></param> public void Connect(IEndPoint endPoint) { switch (_steamOptions.SteamMode) { case SteamModes.P2P: var steamEndPoint = (SteamEndpoint)endPoint; var steamIdentity = new SteamNetworkingIdentity(); steamIdentity.SetSteamID(steamEndPoint.Address); _steamSocketManager.HoHSteamNetConnection = SteamNetworkingSockets.ConnectP2P(ref steamIdentity, 0, 0, Array.Empty <SteamNetworkingConfigValue_t>()); _steamSocketManager.SteamConnections.Add(steamEndPoint, _steamSocketManager.HoHSteamNetConnection); break; case SteamModes.UDP: _endPoint = (SteamSocketFactory.SteamEndPointWrapper)endPoint; var address = new SteamNetworkingIPAddr(); address.SetIPv6(((IPEndPoint)_endPoint.inner).Address.GetAddressBytes(), (ushort)((IPEndPoint)_endPoint.inner).Port); _steamSocketManager.HoHSteamNetConnection = SteamNetworkingSockets.ConnectByIPAddress(ref address, 0, Array.Empty <SteamNetworkingConfigValue_t>()); _steamSocketManager.SteamConnections.Add(_endPoint, _steamSocketManager.HoHSteamNetConnection); break; default: Debug.LogWarning("Unknown steam mode. Please check if mode has been supported."); break; } }
private async void Connect(string host) { cancelToken = new CancellationTokenSource(); c_onConnectionChange = Callback <SteamNetConnectionStatusChangedCallback_t> .Create(OnConnectionStatusChanged); try { hostSteamID = new CSteamID(UInt64.Parse(host)); connectedComplete = new TaskCompletionSource <Task>(); OnConnected += SetConnectedComplete; SteamNetworkingIdentity smi = new SteamNetworkingIdentity(); smi.SetSteamID(hostSteamID); SteamNetworkingConfigValue_t[] options = new SteamNetworkingConfigValue_t[] { }; HostConnection = SteamNetworkingSockets.ConnectP2P(ref smi, 0, options.Length, options); Task connectedCompleteTask = connectedComplete.Task; Task timeOutTask = Task.Delay(ConnectionTimeout, cancelToken.Token); if (await Task.WhenAny(connectedCompleteTask, timeOutTask) != connectedCompleteTask) { if (cancelToken.IsCancellationRequested) { Debug.LogError($"The connection attempt was cancelled."); } else if (timeOutTask.IsCompleted) { Debug.LogError($"Connection to {host} timed out."); } OnConnected -= SetConnectedComplete; OnConnectionFailed(); } OnConnected -= SetConnectedComplete; } catch (FormatException) { Debug.LogError($"Connection string was not in the right format. Did you enter a SteamId?"); Error = true; OnConnectionFailed(); } catch (Exception ex) { Debug.LogError(ex.Message); Error = true; OnConnectionFailed(); } finally { if (Error) { Debug.LogError("Connection failed."); OnConnectionFailed(); } } }
/// <summary> /// Begins a p2p conenctiona attempt with the target. /// </summary> /// <param name="target"></param> private void AttemptConnection(CSteamID target) { SteamNetworkingIdentity id = new SteamNetworkingIdentity(); id.SetSteamID(target); Send(OpCode.AttemptP2PConnection, new IdentityPacket() { identity = SteamID.m_SteamID }, id); }
/// <summary> /// Sends a message to the target. /// </summary> /// <param name="msg"></param> /// <param name="qos"></param> public void Send(short opcode, ISerializablePacket packet, SteamNetworkingIdentity target)/* OutgoingMessage msg)*/ { if (!IsConnected) { return; } if (!IsLocal) { return; } using (PooledNetWriter w = NetWriterPool.GetWriter()) { MessageHelper.CreateAndFinalize(w, opcode, packet); var segment = w.ToArray(); //if (NetLogFilter.messageDiagnostics) { NetDiagnostics.OnSend(opcode, segment.Count, 1); } // Initialize unmanaged memory to hold the array. int size = Marshal.SizeOf(segment[0]) * segment.Length; IntPtr pnt = Marshal.AllocHGlobal(size); try { // Copy the array to unmanaged memory. Marshal.Copy(segment, 0, pnt, segment.Length); EResult result = SteamNetworkingMessages.SendMessageToUser(ref target, pnt, (uint)size, Constants.k_nSteamNetworkingSend_ReliableNoNagle, 0); if (NetLogFilter.logInfo) { Debug.Log($"Packet to {SteamFriends.GetFriendPersonaName(target.GetSteamID())} was sent with resilt: {result}. ({Time.time})"); } } finally { // Free the unmanaged memory. Marshal.FreeHGlobal(pnt); } //if (SteamNetworking.SendP2PPacket(target, segment, (uint)segment.Length, EP2PSend.k_EP2PSendReliable)) //{ // if (NetLogFilter.logInfo) { Debug.Log($"Packet to {SteamFriends.GetFriendPersonaName(target)} was successfully sent. ({Time.time})"); } //} //else //{ // if (NetLogFilter.logInfo) { Debug.Log($"Packet to {SteamFriends.GetFriendPersonaName(target)} failed to send. ({Time.time})"); } //} } }
/// This is called to actively communicate rejection or failure /// to the incoming message. If you intend to ignore all incoming requests /// that you do not wish to accept, then it's not strictly necessary to /// implement this. public void SendRejectionSignal(ref SteamNetworkingIdentity identityPeer, IntPtr pMsg, int cbMsg) { NativeMethods.SteamAPI_ISteamNetworkingSignalingRecvContext_SendRejectionSignal(ref this, ref identityPeer, pMsg, cbMsg); }
/// Called when the signal represents a request for a new connection. /// /// If you want to ignore the request, just return NULL. In this case, /// the peer will NOT receive any reply. You should consider ignoring /// requests rather than actively rejecting them, as a security measure. /// If you actively reject requests, then this makes it possible to detect /// if a user is online or not, just by sending them a request. /// /// If you wish to send back a rejection, then use /// ISteamNetworkingSockets::CloseConnection() and then return NULL. /// We will marshal a properly formatted rejection signal and /// call SendRejectionSignal() so you can send it to them. /// /// If you return a signaling object, the connection is NOT immediately /// accepted by default. Instead, it stays in the "connecting" state, /// and the usual callback is posted, and your app can accept the /// connection using ISteamNetworkingSockets::AcceptConnection. This /// may be useful so that these sorts of connections can be more similar /// to your application code as other types of connections accepted on /// a listen socket. If this is not useful and you want to skip this /// callback process and immediately accept the connection, call /// ISteamNetworkingSockets::AcceptConnection before returning the /// signaling object. /// /// After accepting a connection (through either means), the connection /// will transition into the "finding route" state. public IntPtr OnConnectRequest(HSteamNetConnection hConn, ref SteamNetworkingIdentity identityPeer, int nLocalVirtualPort) { return NativeMethods.SteamAPI_ISteamNetworkingSignalingRecvContext_OnConnectRequest(ref this, hConn, ref identityPeer, nLocalVirtualPort); }