use custom ICE server config (#1071)

* use custom ICE server config

* more

* more

* more

* more

* more

* more
This commit is contained in:
Logan McNaughton
2026-06-13 18:28:33 +02:00
committed by GitHub
parent 99c4d6dff8
commit ae7bac65d5
2 changed files with 67 additions and 7 deletions
+24 -3
View File
@@ -3,6 +3,13 @@ use crate::savestates;
use crate::ui;
use sha2::digest::Digest;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct RtcIceServerConfig {
pub urls: Vec<String>,
pub username: Option<String>,
pub credential: Option<String>,
}
pub struct GgrsConfig;
impl ggrs::Config for GgrsConfig {
type Input = ui::input::InputData;
@@ -346,10 +353,24 @@ pub fn init(
input_delay: usize,
pal: bool,
) -> Option<Netplay> {
let (mut socket, loop_fut) = matchbox_socket::WebRtcSocketBuilder::new(server_addr)
let mut builder = matchbox_socket::WebRtcSocketBuilder::new(server_addr)
.add_unreliable_channel()
.add_reliable_channel()
.build();
.add_reliable_channel();
if let ice_config_path = ui::get_dirs().cache_dir.join("ice_config.json")
&& let Ok(ice_config) = std::fs::read(&ice_config_path)
&& let Ok(ice_config) = serde_json::from_slice::<RtcIceServerConfig>(&ice_config)
{
builder = builder.ice_server(matchbox_socket::RtcIceServerConfig {
urls: ice_config.urls,
username: ice_config.username,
credential: ice_config.credential,
});
} else {
eprintln!("Using default ICE config");
}
let (mut socket, loop_fut) = builder.build();
tokio::spawn(async move {
if let Err(e) = loop_fut.await {
eprintln!("WebRTC loop failed: {}", e);
+43 -4
View File
@@ -1,4 +1,5 @@
use crate::device;
use crate::netplay::RtcIceServerConfig;
use crate::ui;
use crate::ui::gui::{AppWindow, open_uri, run_rom, save_settings};
use futures::{SinkExt, StreamExt};
@@ -35,6 +36,7 @@ struct NetplaySession {
players: Vec<String>,
server_address: Option<String>,
input_delay: Option<usize>,
ice_server_config: Option<RtcIceServerConfig>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@@ -274,6 +276,7 @@ fn create_session(
players: vec![player_name],
server_address: None,
input_delay: None,
ice_server_config: None,
};
let create_session = NetplayLobbyMessage {
message_type: MessageType::RequestCreateSession,
@@ -321,6 +324,7 @@ fn create_session(
close_ping_rx,
session.server_address.as_ref().unwrap().clone(),
session_name.into(),
session.ice_server_config.clone(),
session.game_name.as_ref().unwrap().into(),
handle.get_netplay_rom_path(),
ui::GameSettings {
@@ -384,6 +388,7 @@ fn join_session(
players: vec![player_name],
server_address: None,
input_delay: None,
ice_server_config: None,
};
let join_session = NetplayLobbyMessage {
message_type: MessageType::RequestJoinSession,
@@ -396,12 +401,22 @@ fn join_session(
fn update_ping(
server_addr: String,
ice_server_config: Option<RtcIceServerConfig>,
mut close_ping_rx: tokio::sync::broadcast::Receiver<()>,
weak_app: slint::Weak<AppWindow>,
) {
let (mut socket, loop_fut) = matchbox_socket::WebRtcSocketBuilder::new(server_addr)
.add_unreliable_channel()
.build();
let mut builder =
matchbox_socket::WebRtcSocketBuilder::new(server_addr).add_unreliable_channel();
if let Some(ice_server_config) = ice_server_config {
builder = builder.ice_server(matchbox_socket::RtcIceServerConfig {
urls: ice_server_config.urls,
username: ice_server_config.username,
credential: ice_server_config.credential,
});
} else {
eprintln!("Using default ICE config");
}
let (mut socket, loop_fut) = builder.build();
tokio::spawn(async move {
if let Err(e) = loop_fut.await {
@@ -525,6 +540,22 @@ fn update_ping(
});
}
fn update_ice_config(ice_server_config: Option<RtcIceServerConfig>) {
tokio::spawn(async move {
let ice_config_path = ui::get_dirs().cache_dir.join("ice_config.json");
if let Some(ice_server_config) = ice_server_config {
tokio::fs::write(
&ice_config_path,
serde_json::to_vec(&ice_server_config).unwrap(),
)
.await
.unwrap();
} else {
let _ = tokio::fs::remove_file(&ice_config_path).await;
}
});
}
#[allow(clippy::too_many_arguments)]
fn setup_wait_window(
netplay_write_sender: tokio::sync::broadcast::Sender<Option<NetplayLobbyMessage>>,
@@ -532,12 +563,19 @@ fn setup_wait_window(
close_ping_rx: tokio::sync::broadcast::Receiver<()>,
server_addr: String,
session_name: slint::SharedString,
ice_server_config: Option<RtcIceServerConfig>,
game_name: slint::SharedString,
rom_path: slint::SharedString,
game_settings: ui::GameSettings,
app: &AppWindow,
) {
update_ping(server_addr.clone(), close_ping_rx, app.as_weak());
update_ice_config(ice_server_config.clone());
update_ping(
server_addr.clone(),
ice_server_config,
close_ping_rx,
app.as_weak(),
);
app.set_netplay_session_name(session_name);
app.set_netplay_game_name(game_name);
@@ -746,6 +784,7 @@ fn setup_join_window(
close_ping_rx.resubscribe(),
session.server_address.as_ref().unwrap().clone(),
session_name.into(),
session.ice_server_config.clone(),
session.game_name.as_ref().unwrap().into(),
handle.get_netplay_rom_path(),
ui::GameSettings {