Add support for custom netplay server url (#511)

* Add support for custom netplay server url

* more

* more

* more

* more

* more

* more

* more

* more

* more

* more
This commit is contained in:
Logan McNaughton 2025-07-16 15:42:54 +02:00 committed by GitHub
parent e4dd5c2dee
commit 022190384a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 102 additions and 7 deletions

View File

@ -14,6 +14,7 @@ export { VruDialog } from "vru_dialog.slint";
export { NetplayCreate } from "netplay_create.slint";
export { NetplayJoin } from "netplay_join.slint";
export { NetplayWait } from "netplay_wait.slint";
export { CustomNetplayServer } from "netplay_page.slint";
export component AppWindow inherits Window {
callback wiki_button_clicked;

View File

@ -5,6 +5,7 @@ export component NetplayCreate inherits Window {
title: @tr("Netplay: Create Session");
in-out property server_names <=> NetplayData.server_names;
in-out property server_urls <=> NetplayData.server_urls;
in-out property custom_server_url <=> NetplayData.custom_server_url;
in-out property ping <=> NetplayData.ping;
in-out property game_name <=> NetplayData.game_name;
in-out property game_hash <=> NetplayData.game_hash;
@ -14,6 +15,7 @@ export component NetplayCreate inherits Window {
in-out property peer_addr <=> NetplayData.peer_addr;
in-out property rom_dir <=> NetplayData.rom_dir;
callback get_ping(string);
callback get_custom_url();
callback select_rom(string);
callback create_session(string, string, string, string, string, string, string);
@ -69,7 +71,11 @@ export component NetplayCreate inherits Window {
model: NetplayData.server_names;
selected => {
if (self.current-index >= 0) {
get_ping(NetplayData.server_urls[self.current-index]);
if (self.current-value == "Custom") {
get_custom_url();
} else {
get_ping(NetplayData.server_urls[self.current-index]);
}
}
}
}
@ -102,12 +108,18 @@ export component NetplayCreate inherits Window {
Rectangle { }
Button {
property <string> server_url;
text: @tr("Create Session");
enabled: NetplayData.session_name != "" && NetplayData.player_name != "" && NetplayData.game_name != "" && !NetplayData.pending_session;
clicked => {
NetplayData.pending_session = true;
if (server.current-value == "Custom") {
server_url = "ws://" + NetplayData.custom_server_url;
} else {
server_url = NetplayData.server_urls[server.current-index];
}
create_session(
NetplayData.server_urls[server.current-index],
server_url,
NetplayData.session_name,
NetplayData.player_name,
NetplayData.game_name,

View File

@ -5,6 +5,7 @@ export component NetplayJoin inherits Window {
title: @tr("Netplay: Join Session");
in-out property server_names <=> NetplayData.server_names;
in-out property server_urls <=> NetplayData.server_urls;
in-out property custom_server_url <=> NetplayData.custom_server_url;
in-out property ping <=> NetplayData.ping;
in-out property sessions <=> NetplayData.sessions;
in-out property current_session <=> NetplayData.current_session;
@ -17,6 +18,7 @@ export component NetplayJoin inherits Window {
in-out property rom_path <=> NetplayData.rom_path;
in-out property rom_dir <=> NetplayData.rom_dir;
callback get_ping(string);
callback get_custom_url();
callback refresh_session(string);
callback select_rom(string);
callback join_session(string, string, string, int);
@ -46,7 +48,11 @@ export component NetplayJoin inherits Window {
model: NetplayData.server_names;
selected => {
if (self.current-index >= 0) {
get_ping(NetplayData.server_urls[self.current-index]);
if (self.current-value == "Custom") {
get_custom_url();
} else {
get_ping(NetplayData.server_urls[self.current-index]);
}
}
}
}
@ -89,7 +95,11 @@ export component NetplayJoin inherits Window {
Button {
text: @tr("Refresh Session List");
clicked => {
refresh_session(NetplayData.server_urls[server.current-index]);
if (server.current-value == "Custom") {
refresh_session("ws://" + NetplayData.custom_server_url);
} else {
refresh_session(NetplayData.server_urls[server.current-index]);
}
}
}
}

View File

@ -1,7 +1,7 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { VerticalBox, HorizontalBox, Button } from "std-widgets.slint";
import { StandardButton, VerticalBox, HorizontalBox, Button, LineEdit } from "std-widgets.slint";
import { Page } from "page.slint";
export global NetplayData {
@ -21,6 +21,7 @@ export global NetplayData {
in-out property <[int]> ports;
in-out property <int> current_session: -1;
in-out property <string> rom_dir;
in-out property <string> custom_server_url;
}
export component Netplay inherits Page {
@ -74,3 +75,22 @@ export component Netplay inherits Page {
}
}
}
export component CustomNetplayServer inherits Dialog {
in-out property custom_server_url <=> NetplayData.custom_server_url;
title: @tr("Custom Netplay Server");
preferred-width: 400px;
callback ok_clicked(string);
server_url := LineEdit {
text: NetplayData.custom_server_url;
placeholder-text: "example.com:45000";
}
StandardButton {
kind: ok;
clicked => {
NetplayData.custom_server_url = server_url.text;
ok_clicked(NetplayData.custom_server_url);
}
}
}

View File

@ -1,8 +1,8 @@
use crate::device;
use crate::ui;
use crate::ui::gui::{
AppWindow, ErrorDialog, GameSettings, GbPaths, NetplayCreate, NetplayDevice, NetplayJoin,
NetplayWait, VruChannel, run_rom, save_settings,
AppWindow, CustomNetplayServer, ErrorDialog, GameSettings, GbPaths, NetplayCreate,
NetplayDevice, NetplayJoin, NetplayWait, VruChannel, run_rom, save_settings,
};
use futures::{SinkExt, StreamExt};
use sha2::{Digest, Sha256};
@ -56,6 +56,8 @@ trait NetplayPages {
fn refresh_sessions(&self, _server: slint::SharedString) {
// Default implementation does nothing
}
fn invoke_get_ping(&self, server_url: slint::SharedString);
fn set_custom_server_url(&self, server_url: slint::SharedString);
}
impl NetplayPages for NetplayCreate {
@ -83,6 +85,12 @@ impl NetplayPages for NetplayCreate {
fn set_peer_addr(&self, peer_addr: slint::SharedString) {
self.set_peer_addr(peer_addr);
}
fn invoke_get_ping(&self, server_url: slint::SharedString) {
self.invoke_get_ping(server_url);
}
fn set_custom_server_url(&self, server_url: slint::SharedString) {
self.set_custom_server_url(server_url);
}
}
impl NetplayPages for NetplayJoin {
@ -113,6 +121,12 @@ impl NetplayPages for NetplayJoin {
fn set_peer_addr(&self, peer_addr: slint::SharedString) {
self.set_peer_addr(peer_addr);
}
fn invoke_get_ping(&self, server_url: slint::SharedString) {
self.invoke_get_ping(server_url);
}
fn set_custom_server_url(&self, server_url: slint::SharedString) {
self.set_custom_server_url(server_url);
}
}
fn populate_server_names<T: ComponentHandle + NetplayPages + 'static>(weak: slint::Weak<T>) {
@ -159,6 +173,7 @@ fn populate_server_names<T: ComponentHandle + NetplayPages + 'static>(weak: slin
server_names.push(server.0.into());
server_urls.push(server.1.into());
}
server_names.push("Custom".into());
update_ping(weak2, server_urls.row_data(0).unwrap().into());
handle.refresh_sessions(server_urls.row_data(0).unwrap());
let server_names_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
@ -260,6 +275,25 @@ fn update_ping<T: ComponentHandle + NetplayPages + 'static>(
});
}
fn show_custom_url_dialog<T: ComponentHandle + NetplayPages + 'static>(
weak: slint::Weak<T>,
server_url: slint::SharedString,
) {
let url_dialog = CustomNetplayServer::new().unwrap();
url_dialog.set_custom_server_url(server_url);
let weak_dialog = url_dialog.as_weak();
url_dialog.on_ok_clicked(move |server_url| {
weak.upgrade_in_event_loop(move |handle| {
handle.set_custom_server_url(server_url.clone());
let prefix: slint::SharedString = "ws://".into();
handle.invoke_get_ping(prefix + &server_url);
})
.unwrap();
weak_dialog.unwrap().window().hide().unwrap();
});
url_dialog.show().unwrap();
}
pub fn setup_create_window(
create_window: &NetplayCreate,
game_settings: GameSettings,
@ -283,6 +317,15 @@ pub fn setup_create_window(
update_ping(weak.clone(), server_url.to_string());
});
let weak = create_window.as_weak();
create_window.on_get_custom_url(move || {
let weak2 = weak.clone();
weak.upgrade_in_event_loop(move |handle| {
handle.set_ping("Ping: Unknown".into());
show_custom_url_dialog(weak2, handle.get_custom_server_url());
})
.unwrap();
});
let weak = create_window.as_weak();
create_window.on_select_rom(move |rom_dir| {
select_rom(weak.clone(), rom_dir);
});
@ -974,6 +1017,15 @@ pub fn setup_join_window(
.unwrap();
});
let weak = join_window.as_weak();
join_window.on_get_custom_url(move || {
let weak2 = weak.clone();
weak.upgrade_in_event_loop(move |handle| {
handle.set_ping("Ping: Unknown".into());
show_custom_url_dialog(weak2, handle.get_custom_server_url());
})
.unwrap();
});
let weak = join_window.as_weak();
join_window.on_select_rom(move |rom_dir| {
select_rom(weak.clone(), rom_dir);
});