Skip to content

Commit f3cbe28

Browse files
committed
Add get_p2p_session_state and error handling
1 parent 6af2123 commit f3cbe28

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

src/networking.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,79 @@ pub enum SendType {
3131
ReliableWithBuffering,
3232
}
3333

34+
/// P2P session error codes
35+
#[repr(u8)]
36+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
37+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
38+
pub enum P2PSessionError {
39+
/// No error
40+
None = 0,
41+
#[deprecated(
42+
note = "For privacy reasons, there is no error if the remote user is playing another game."
43+
)]
44+
NotRunningApp = 1,
45+
/// Local user doesn't own the app that is running
46+
NoRightsToApp = 2,
47+
#[deprecated(note = "For privacy reasons, there is no error if the remote user is offline")]
48+
NotLoggedIn = 3,
49+
/// Target isn't responding, perhaps not calling AcceptP2PSessionWithUser()
50+
/// This may also occur behind corporate firewalls (P2P sessions require UDP ports 3478, 4379, and 4380 to be open for outgoing traffic)
51+
Timeout = 4,
52+
53+
/// Unknown error code
54+
Unknown(u8),
55+
}
56+
57+
impl From<u8> for P2PSessionError {
58+
fn from(value: u8) -> Self {
59+
#[allow(deprecated)]
60+
match value {
61+
0 => P2PSessionError::None,
62+
1 => P2PSessionError::NotRunningApp,
63+
2 => P2PSessionError::NoRightsToApp,
64+
3 => P2PSessionError::NotLoggedIn,
65+
4 => P2PSessionError::Timeout,
66+
other => P2PSessionError::Unknown(other),
67+
}
68+
}
69+
}
70+
71+
impl From<P2PSessionError> for u8 {
72+
fn from(error: P2PSessionError) -> Self {
73+
#[allow(deprecated)]
74+
match error {
75+
P2PSessionError::None => 0,
76+
P2PSessionError::NotRunningApp => 1,
77+
P2PSessionError::NoRightsToApp => 2,
78+
P2PSessionError::NotLoggedIn => 3,
79+
P2PSessionError::Timeout => 4,
80+
P2PSessionError::Unknown(code) => code,
81+
}
82+
}
83+
}
84+
85+
/// Information about a P2P session with a remote user
86+
#[derive(Clone, Debug)]
87+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
88+
pub struct P2PSessionState {
89+
/// Whether we've got an active open connection
90+
pub connection_active: bool,
91+
/// Whether we're currently trying to establish a connection
92+
pub connecting: bool,
93+
/// Last error recorded
94+
pub error: P2PSessionError,
95+
/// Whether it's going through a Steam relay server
96+
pub using_relay: bool,
97+
/// Number of bytes queued for sending
98+
pub bytes_queued_for_send: i32,
99+
/// Number of packets queued for sending
100+
pub packets_queued_for_send: i32,
101+
/// Potential IP address of remote host (could be Steam relay server)
102+
pub remote_ip: u32,
103+
/// Remote port number
104+
pub remote_port: u16,
105+
}
106+
34107
impl Networking {
35108
/// Accepts incoming packets from the given user
36109
///
@@ -44,6 +117,30 @@ impl Networking {
44117
unsafe { sys::SteamAPI_ISteamNetworking_CloseP2PSessionWithUser(self.net, user.0) }
45118
}
46119

120+
/// Gets the connection state to the specified user
121+
///
122+
/// Returns the P2P session state if a connection exists with the user,
123+
/// or None if no connection exists.
124+
pub fn get_p2p_session_state(&self, user: SteamId) -> Option<P2PSessionState> {
125+
unsafe {
126+
let mut state: sys::P2PSessionState_t = std::mem::zeroed();
127+
if sys::SteamAPI_ISteamNetworking_GetP2PSessionState(self.net, user.0, &mut state) {
128+
Some(P2PSessionState {
129+
connection_active: state.m_bConnectionActive != 0,
130+
connecting: state.m_bConnecting != 0,
131+
error: P2PSessionError::from(state.m_eP2PSessionError),
132+
using_relay: state.m_bUsingRelay != 0,
133+
bytes_queued_for_send: state.m_nBytesQueuedForSend,
134+
packets_queued_for_send: state.m_nPacketsQueuedForSend,
135+
remote_ip: state.m_nRemoteIP,
136+
remote_port: state.m_nRemotePort,
137+
})
138+
} else {
139+
None
140+
}
141+
}
142+
}
143+
47144
/// Sends a packet to the user, starting the
48145
/// connection if it isn't started already
49146
pub fn send_p2p_packet(&self, remote: SteamId, send_type: SendType, data: &[u8]) -> bool {

0 commit comments

Comments
 (0)