steamworks/
networking_sockets_callback.rs1use crate::networking_sockets::NetConnection;
2use crate::networking_types::{
3 AppNetConnectionEnd, NetConnectionEnd, NetConnectionStatusChanged, NetworkingConnectionState,
4};
5use crate::{register_callback, CallbackHandle, Inner};
6use std::sync::{Arc, Weak};
7use steamworks_sys as sys;
8use sys::ISteamNetworkingSockets;
9
10pub(crate) fn get_or_create_connection_callback(
14 inner: Arc<Inner>,
15 sockets: *mut ISteamNetworkingSockets,
16) -> Arc<CallbackHandle> {
17 let mut network_socket_data = inner.networking_sockets_data.lock().unwrap();
18 if let Some(callback) = network_socket_data.connection_callback.upgrade() {
19 callback
20 } else {
21 let handler = ConnectionCallbackHandler {
22 inner: Arc::downgrade(&inner),
23 sockets,
24 };
25 let callback = unsafe {
26 register_callback(&inner, move |event: NetConnectionStatusChanged| {
27 handler.callback(event);
28 })
29 };
30
31 let callback = Arc::new(callback);
32 network_socket_data.connection_callback = Arc::downgrade(&callback);
33 callback
34 }
35}
36
37pub(crate) struct ConnectionCallbackHandler {
38 inner: Weak<Inner>,
39 sockets: *mut ISteamNetworkingSockets,
40}
41
42unsafe impl Send for ConnectionCallbackHandler {}
43unsafe impl Sync for ConnectionCallbackHandler {}
44
45impl ConnectionCallbackHandler {
46 pub(crate) fn callback(&self, event: NetConnectionStatusChanged) {
47 if let Some(socket) = event.connection_info.listen_socket() {
48 self.listen_socket_callback(socket, event);
49 } else {
50 self.independent_connection_callback(event);
51 }
52 }
53
54 fn listen_socket_callback(
55 &self,
56 socket_handle: sys::HSteamListenSocket,
57 event: NetConnectionStatusChanged,
58 ) {
59 if let Some(inner) = self.inner.upgrade() {
60 let data = inner.networking_sockets_data.lock().unwrap();
61 if let Some((socket, sender)) = data
62 .sockets
63 .get(&socket_handle)
64 .and_then(|(socket, sender)| socket.upgrade().map(|socket| (socket, sender)))
65 {
66 let connection_handle = event.connection;
67 let state = event.connection_info.state().expect("invalid state");
68 if let Ok(event) = event.into_listen_socket_event(socket) {
69 if let Err(_err) = sender.send(event) {
70 if let NetworkingConnectionState::Connecting = state {
73 self.reject_connection(connection_handle);
74 }
75 }
76 } else {
77 }
79 }
80 }
81 }
82
83 fn reject_connection(&self, connection_handle: sys::HSteamNetConnection) {
84 if let Some(inner) = self.inner.upgrade() {
85 NetConnection::new_internal(connection_handle, self.sockets, inner.clone()).close(
86 NetConnectionEnd::App(AppNetConnectionEnd::generic_normal()).into(),
87 Some("no new connections will be accepted"),
88 false,
89 );
90 }
91 }
92
93 fn independent_connection_callback(&self, _event: NetConnectionStatusChanged) {
94 }
96}