bones_framework/networking/
online_matchmaking.rs1#![allow(missing_docs)]
2
3use super::online::{
4 MatchmakerConnectionState, OnlineMatchmakerRequest, OnlineMatchmakerResponse,
5 READ_TO_END_BYTE_COUNT,
6};
7use crate::{
8 networking::{socket::establish_peer_connections, NetworkMatchSocket},
9 prelude::*,
10 utils::BiChannelServer,
11};
12use bones_matchmaker_proto::{MatchInfo, MatchmakerRequest, MatchmakerResponse};
13use std::sync::Arc;
14use tracing::{info, warn};
15
16pub(crate) async fn resolve_search_for_match(
18 matchmaker_channel: &BiChannelServer<OnlineMatchmakerRequest, OnlineMatchmakerResponse>,
19 matchmaker_connection_state: &mut MatchmakerConnectionState,
20 match_info: MatchInfo,
21) -> anyhow::Result<()> {
22 let conn = matchmaker_connection_state.acquire_connection().await?;
23 let (mut send, mut recv) = conn.open_bi().await?;
24
25 let message = MatchmakerRequest::RequestMatchmaking(match_info.clone());
27 info!(request=?message, "Resolve: Sending match request");
28 let message = postcard::to_allocvec(&message)?;
29 send.write_all(&message).await?;
30 send.finish()?;
31 send.stopped().await?;
32
33 let res = recv.read_to_end(READ_TO_END_BYTE_COUNT).await?;
34 let _response: MatchmakerResponse = postcard::from_bytes(&res)?;
35
36 loop {
37 tokio::select! {
38 message = matchmaker_channel.recv() => {
39 match message {
40 Ok(OnlineMatchmakerRequest::StopSearch { .. }) => {
41 if let Err(err) = resolve_stop_search_for_match(
42 matchmaker_channel,
43 matchmaker_connection_state,
44 match_info.clone(),
45 ).await {
46 warn!("Error stopping matchmaking: {:?}", err);
47 }
48 return Ok(());
49 }
50 Ok(other) => {
51 warn!("Unexpected request during matchmaking: {:?}", other);
52 }
53 Err(err) => {
54 anyhow::bail!("Failed to recv from match maker channel: {err:?}");
55 }
56 }
57 }
58 recv = conn.accept_uni() => {
59 let mut recv = recv?;
60 let message = recv.read_to_end(5 * 1024).await?;
61 let message: MatchmakerResponse = postcard::from_bytes(&message)?;
62
63 match message {
64 MatchmakerResponse::MatchmakingUpdate{ player_count } => {
65 info!("Online matchmaking updated player count: {player_count}");
66 matchmaker_channel.try_send(OnlineMatchmakerResponse::MatchmakingUpdate{ player_count })?;
67 }
68 MatchmakerResponse::Success {
69 random_seed,
70 player_idx,
71 player_count,
72 player_ids,
73 } => {
74 info!(%random_seed, %player_idx, player_count=%player_count, "Online match starting");
75
76 let peer_connections = establish_peer_connections(
77 player_idx,
78 player_count,
79 player_ids,
80 None,
81 )
82 .await?;
83
84 let socket = super::socket::Socket::new(player_idx, peer_connections);
85
86 matchmaker_channel.try_send(OnlineMatchmakerResponse::GameStarting {
87 socket: NetworkMatchSocket(Arc::new(socket)),
88 player_idx: player_idx as _,
89 player_count: player_count as _,
90 random_seed
91 })?;
92
93 matchmaker_connection_state.close_connection();
94 return Ok(());
95 }
96 other => anyhow::bail!("Unexpected message from matchmaker: {other:?}"),
97 }
98 }
99 }
100 }
101}
102
103pub(crate) async fn resolve_stop_search_for_match(
105 matchmaker_channel: &BiChannelServer<OnlineMatchmakerRequest, OnlineMatchmakerResponse>,
106 matchmaker_connection_state: &mut MatchmakerConnectionState,
107 match_info: MatchInfo,
108) -> anyhow::Result<()> {
109 let conn = matchmaker_connection_state.acquire_connection().await?;
110 let (mut send, mut recv) = conn.open_bi().await?;
112
113 let message = MatchmakerRequest::StopMatchmaking(match_info);
114 info!(request=?message, "Sending stop matchmaking request");
115
116 let message = postcard::to_allocvec(&message)?;
117 send.write_all(&message).await?;
118 send.finish()?;
119 send.stopped().await?;
120
121 let res = recv.read_to_end(READ_TO_END_BYTE_COUNT).await?;
122 let response: MatchmakerResponse = postcard::from_bytes(&res)?;
123
124 match response {
125 MatchmakerResponse::Accepted => {
126 matchmaker_channel
127 .send(OnlineMatchmakerResponse::Error(
128 "Matchmaking stopped by user".to_string(),
129 ))
130 .await?;
131 }
132 MatchmakerResponse::Error(error) => {
133 anyhow::bail!("Failed to stop matchmaking: {}", error);
134 }
135 _ => {
136 anyhow::bail!("Unexpected response from matchmaker: {:?}", response);
137 }
138 }
139
140 Ok(())
141}