bones_framework/networking/
online_lobby.rs

1#![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::{GameID, LobbyId, LobbyInfo, MatchmakerRequest, MatchmakerResponse};
13use std::sync::Arc;
14use tracing::info;
15
16pub(crate) async fn resolve_list_lobbies(
17    user_channel: &BiChannelServer<OnlineMatchmakerRequest, OnlineMatchmakerResponse>,
18    matchmaker_connection_state: &mut MatchmakerConnectionState,
19    game_id: GameID,
20) -> anyhow::Result<()> {
21    let conn = matchmaker_connection_state.acquire_connection().await?;
22    let (mut send, mut recv) = conn.open_bi().await?;
23
24    let message = MatchmakerRequest::ListLobbies(game_id);
25    let message = postcard::to_allocvec(&message)?;
26    send.write_all(&message).await?;
27    send.finish()?;
28    send.stopped().await?;
29
30    let response = recv.read_to_end(5 * 1024).await?;
31    let message: MatchmakerResponse = postcard::from_bytes(&response)?;
32
33    match message {
34        MatchmakerResponse::LobbiesList(lobbies) => {
35            user_channel.try_send(OnlineMatchmakerResponse::LobbiesList(lobbies))?;
36        }
37        other => anyhow::bail!("Unexpected message from matchmaker: {other:?}"),
38    }
39
40    Ok(())
41}
42
43pub(crate) async fn resolve_create_lobby(
44    user_channel: &BiChannelServer<OnlineMatchmakerRequest, OnlineMatchmakerResponse>,
45    matchmaker_connection_state: &mut MatchmakerConnectionState,
46    lobby_info: LobbyInfo,
47) -> anyhow::Result<()> {
48    let conn = matchmaker_connection_state.acquire_connection().await?;
49    let (mut send, mut recv) = conn.open_bi().await?;
50
51    let message = MatchmakerRequest::CreateLobby(lobby_info);
52    let message = postcard::to_allocvec(&message)?;
53    send.write_all(&message).await?;
54    send.finish()?;
55    send.stopped().await?;
56
57    let response = recv.read_to_end(READ_TO_END_BYTE_COUNT).await?;
58    let message: MatchmakerResponse = postcard::from_bytes(&response)?;
59
60    match message {
61        MatchmakerResponse::LobbyCreated(lobby_id) => {
62            user_channel.try_send(OnlineMatchmakerResponse::LobbyCreated(lobby_id))?;
63        }
64        MatchmakerResponse::Error(err) => {
65            user_channel.try_send(OnlineMatchmakerResponse::Error(err))?;
66        }
67        other => anyhow::bail!("Unexpected message from matchmaker: {other:?}"),
68    }
69
70    Ok(())
71}
72
73pub(crate) async fn resolve_join_lobby(
74    user_channel: &BiChannelServer<OnlineMatchmakerRequest, OnlineMatchmakerResponse>,
75    matchmaker_connection_state: &mut MatchmakerConnectionState,
76    game_id: GameID,
77    lobby_id: LobbyId,
78    password: Option<String>,
79) -> anyhow::Result<()> {
80    let conn = matchmaker_connection_state.acquire_connection().await?;
81    let (mut send, mut recv) = conn.open_bi().await?;
82
83    let message = MatchmakerRequest::JoinLobby(game_id, lobby_id.clone(), password);
84    let message = postcard::to_allocvec(&message)?;
85    send.write_all(&message).await?;
86    send.finish()?;
87    send.stopped().await?;
88
89    let response = recv.read_to_end(READ_TO_END_BYTE_COUNT).await?;
90    let message: MatchmakerResponse = postcard::from_bytes(&response)?;
91
92    match message {
93        MatchmakerResponse::LobbyJoined(joined_lobby_id) => {
94            user_channel.try_send(OnlineMatchmakerResponse::LobbyJoined {
95                lobby_id: joined_lobby_id,
96                player_count: 0, // We don't have this information yet
97            })?;
98
99            // Wait for further messages (updates or game start)
100            while let Ok(recv) = conn.accept_uni().await {
101                let mut recv = recv;
102                let message = recv.read_to_end(5 * 1024).await?;
103                let message: MatchmakerResponse = postcard::from_bytes(&message)?;
104
105                match message {
106                    MatchmakerResponse::LobbyUpdate { player_count } => {
107                        info!("Online lobby updated player count: {player_count}");
108                        user_channel
109                            .try_send(OnlineMatchmakerResponse::LobbyUpdate { player_count })?;
110                    }
111                    MatchmakerResponse::Success {
112                        random_seed,
113                        player_idx,
114                        player_count,
115                        player_ids,
116                    } => {
117                        let peer_connections =
118                            establish_peer_connections(player_idx, player_count, player_ids, None)
119                                .await?;
120
121                        let socket = super::socket::Socket::new(player_idx, peer_connections);
122
123                        user_channel.try_send(OnlineMatchmakerResponse::GameStarting {
124                            socket: NetworkMatchSocket(Arc::new(socket)),
125                            player_idx: player_idx as _,
126                            player_count: player_count as _,
127                            random_seed,
128                        })?;
129                        break;
130                    }
131                    MatchmakerResponse::Error(err) => {
132                        user_channel.try_send(OnlineMatchmakerResponse::Error(err))?;
133                        break;
134                    }
135                    other => anyhow::bail!("Unexpected message from matchmaker: {other:?}"),
136                }
137            }
138        }
139        MatchmakerResponse::Error(err) => {
140            user_channel.try_send(OnlineMatchmakerResponse::Error(err))?;
141        }
142        other => anyhow::bail!("Unexpected message from matchmaker: {other:?}"),
143    }
144
145    Ok(())
146}