From 3679cb75bcaff6bd4906c4c4f7cd0d9405fe1f13 Mon Sep 17 00:00:00 2001 From: Joshua Yanovski Date: Mon, 17 May 2021 08:32:12 -0700 Subject: [PATCH] Revert "Merge branch 'xMAC94x/quic_enablement' into 'master'" This reverts commit 04d8ddf25ed6b1ae8dd97846c5c4b9af4ab399b8, reversing changes made to 9dcf7a9d26f7d60020c5707fea3ed8ac5596d3dc. --- Cargo.lock | 2 - client/Cargo.toml | 3 +- client/src/addr.rs | 195 +++++++++--------- client/src/error.rs | 2 +- client/src/lib.rs | 43 ++-- common/frontend/src/lib.rs | 1 - server/Cargo.toml | 3 +- server/src/lib.rs | 32 --- server/src/settings.rs | 9 - voxygen/src/menu/char_selection/mod.rs | 4 - voxygen/src/menu/main/client_init.rs | 30 ++- voxygen/src/menu/main/mod.rs | 273 ++++++++++++++----------- voxygen/src/settings/networking.rs | 2 - 13 files changed, 299 insertions(+), 300 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65bd77291a..fd55c47fdb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5483,7 +5483,6 @@ dependencies = [ "hashbrown", "image", "num 0.4.0", - "quinn", "rayon", "ron", "rustyline", @@ -5753,7 +5752,6 @@ dependencies = [ "portpicker", "prometheus", "prometheus-hyper", - "quinn", "rand 0.8.3", "rand_distr", "rayon", diff --git a/client/Cargo.toml b/client/Cargo.toml index 02861fba46..e0113e12f2 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -18,12 +18,11 @@ common-base = { package = "veloren-common-base", path = "../common/base" } common-state = { package = "veloren-common-state", path = "../common/state", default-features = false } common-systems = { package = "veloren-common-systems", path = "../common/systems", default-features = false } common-net = { package = "veloren-common-net", path = "../common/net" } -network = { package = "veloren-network", path = "../network", features = ["compression","quic"], default-features = false } +network = { package = "veloren-network", path = "../network", features = ["compression"], default-features = false } byteorder = "1.3.2" futures-util = "0.3.7" tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] } -quinn = "0.7.2" image = { version = "0.23.12", default-features = false, features = ["png"] } num = "0.4" tracing = { version = "0.1", default-features = false } diff --git a/client/src/addr.rs b/client/src/addr.rs index 539c294006..fa8c871aea 100644 --- a/client/src/addr.rs +++ b/client/src/addr.rs @@ -4,80 +4,47 @@ use tracing::trace; #[derive(Clone, Debug)] pub enum ConnectionArgs { - ///hostname: (hostname|ip):[] - Quic { - hostname: String, - prefer_ipv6: bool, - }, - ///hostname: (hostname|ip):[] - Tcp { - hostname: String, - prefer_ipv6: bool, - }, + IpAndPort(Vec), Mpsc(u64), } impl ConnectionArgs { const DEFAULT_PORT: u16 = 14004; -} -/// Parse ip address or resolves hostname. -/// Note: If you use an ipv6 address, the number after the last -/// colon will be used as the port unless you use [] around the address. -pub(crate) async fn resolve( - address: &str, - prefer_ipv6: bool, -) -> Result, std::io::Error> { - // `lookup_host` will internally try to parse it as a SocketAddr - // 1. Assume it's a hostname + port - match lookup_host(address).await { - Ok(s) => { - trace!("Host lookup succeeded"); - Ok(sort_ipv6(s, prefer_ipv6)) - }, - Err(e) => { - // 2. Assume its a hostname without port - match lookup_host((address, ConnectionArgs::DEFAULT_PORT)).await { - Ok(s) => { - trace!("Host lookup without ports succeeded"); - Ok(sort_ipv6(s, prefer_ipv6)) - }, - Err(_) => Err(e), // Todo: evaluate returning both errors - } - }, - } -} - -pub(crate) async fn try_connect( - network: &network::Network, - address: &str, - prefer_ipv6: bool, - f: F, -) -> Result -where - F: Fn(std::net::SocketAddr) -> network::ConnectAddr, -{ - use crate::error::Error; - let mut participant = None; - for addr in resolve(&address, prefer_ipv6) - .await - .map_err(Error::HostnameLookupFailed)? - { - match network.connect(f(addr)).await { - Ok(p) => { - participant = Some(Ok(p)); - break; + /// Parse ip address or resolves hostname. + /// Note: If you use an ipv6 address, the number after the last + /// colon will be used as the port unless you use [] around the address. + pub async fn resolve( + /* :[] */ server_address: &str, + prefer_ipv6: bool, + ) -> Result { + // `lookup_host` will internally try to parse it as a SocketAddr + // 1. Assume it's a hostname + port + match lookup_host(server_address).await { + Ok(s) => { + trace!("Host lookup succeeded"); + Ok(Self::sort_ipv6(s, prefer_ipv6)) + }, + Err(e) => { + // 2. Assume its a hostname without port + match lookup_host((server_address, Self::DEFAULT_PORT)).await { + Ok(s) => { + trace!("Host lookup without ports succeeded"); + Ok(Self::sort_ipv6(s, prefer_ipv6)) + }, + Err(_) => Err(e), // Todo: evaluate returning both errors + } }, - Err(e) => participant = Some(Err(Error::NetworkErr(e))), } } - participant.unwrap_or_else(|| Err(Error::Other("No Ip Addr provided".to_string()))) -} -fn sort_ipv6(s: impl Iterator, prefer_ipv6: bool) -> Vec { - let (mut first_addrs, mut second_addrs) = - s.partition::, _>(|a| a.is_ipv6() == prefer_ipv6); - std::iter::Iterator::chain(first_addrs.drain(..), second_addrs.drain(..)).collect::>() + fn sort_ipv6(s: impl Iterator, prefer_ipv6: bool) -> Self { + let (mut first_addrs, mut second_addrs) = + s.partition::, _>(|a| a.is_ipv6() == prefer_ipv6); + let addr = std::iter::Iterator::chain(first_addrs.drain(..), second_addrs.drain(..)) + .collect::>(); + ConnectionArgs::IpAndPort(addr) + } } #[cfg(test)] @@ -87,47 +54,85 @@ mod tests { #[tokio::test] async fn resolve_localhost() { - let args = resolve("localhost", false).await.expect("resolve failed"); - assert!(args.len() == 1 || args.len() == 2); - assert_eq!(args[0].ip(), IpAddr::V4(Ipv4Addr::LOCALHOST)); - assert_eq!(args[0].port(), 14004); - - let args = resolve("localhost:666", false) + let args = ConnectionArgs::resolve("localhost", false) .await .expect("resolve failed"); - assert!(args.len() == 1 || args.len() == 2); - assert_eq!(args[0].port(), 666); + if let ConnectionArgs::IpAndPort(args) = args { + assert!(args.len() == 1 || args.len() == 2); + assert_eq!(args[0].ip(), IpAddr::V4(Ipv4Addr::LOCALHOST)); + assert_eq!(args[0].port(), 14004); + } else { + panic!("wrong resolution"); + } + + let args = ConnectionArgs::resolve("localhost:666", false) + .await + .expect("resolve failed"); + if let ConnectionArgs::IpAndPort(args) = args { + assert!(args.len() == 1 || args.len() == 2); + assert_eq!(args[0].port(), 666); + } else { + panic!("wrong resolution"); + } } #[tokio::test] async fn resolve_ipv6() { - let args = resolve("localhost", true).await.expect("resolve failed"); - assert!(args.len() == 1 || args.len() == 2); - assert_eq!(args[0].ip(), Ipv6Addr::LOCALHOST); - assert_eq!(args[0].port(), 14004); + let args = ConnectionArgs::resolve("localhost", true) + .await + .expect("resolve failed"); + if let ConnectionArgs::IpAndPort(args) = args { + assert!(args.len() == 1 || args.len() == 2); + assert_eq!(args[0].ip(), Ipv6Addr::LOCALHOST); + assert_eq!(args[0].port(), 14004); + } else { + panic!("wrong resolution"); + } } #[tokio::test] - async fn tresolve() { - let args = resolve("google.com", false).await.expect("resolve failed"); - assert!(args.len() == 1 || args.len() == 2); - assert_eq!(args[0].port(), 14004); - - let args = resolve("127.0.0.1", false).await.expect("resolve failed"); - assert_eq!(args.len(), 1); - assert_eq!(args[0].port(), 14004); - assert_eq!(args[0].ip(), IpAddr::V4(Ipv4Addr::LOCALHOST)); - - let args = resolve("55.66.77.88", false).await.expect("resolve failed"); - assert_eq!(args.len(), 1); - assert_eq!(args[0].port(), 14004); - assert_eq!(args[0].ip(), IpAddr::V4(Ipv4Addr::new(55, 66, 77, 88))); - - let args = resolve("127.0.0.1:776", false) + async fn resolve() { + let args = ConnectionArgs::resolve("google.com", false) .await .expect("resolve failed"); - assert_eq!(args.len(), 1); - assert_eq!(args[0].port(), 776); - assert_eq!(args[0].ip(), IpAddr::V4(Ipv4Addr::LOCALHOST)); + if let ConnectionArgs::IpAndPort(args) = args { + assert!(args.len() == 1 || args.len() == 2); + assert_eq!(args[0].port(), 14004); + } else { + panic!("wrong resolution"); + } + + let args = ConnectionArgs::resolve("127.0.0.1", false) + .await + .expect("resolve failed"); + if let ConnectionArgs::IpAndPort(args) = args { + assert_eq!(args.len(), 1); + assert_eq!(args[0].port(), 14004); + assert_eq!(args[0].ip(), IpAddr::V4(Ipv4Addr::LOCALHOST)); + } else { + panic!("wrong resolution"); + } + + let args = ConnectionArgs::resolve("55.66.77.88", false) + .await + .expect("resolve failed"); + if let ConnectionArgs::IpAndPort(args) = args { + assert_eq!(args.len(), 1); + assert_eq!(args[0].port(), 14004); + assert_eq!(args[0].ip(), IpAddr::V4(Ipv4Addr::new(55, 66, 77, 88))); + } else { + panic!("wrong resolution"); + } + + let args = ConnectionArgs::resolve("127.0.0.1:776", false) + .await + .expect("resolve failed"); + if let ConnectionArgs::IpAndPort(args) = args { + assert_eq!(args.len(), 1); + assert_eq!(args[0].port(), 776); + assert_eq!(args[0].ip(), IpAddr::V4(Ipv4Addr::LOCALHOST)); + } else { + panic!("wrong resolution"); + } } } diff --git a/client/src/error.rs b/client/src/error.rs index adceaddf04..a9079d77d6 100644 --- a/client/src/error.rs +++ b/client/src/error.rs @@ -9,6 +9,7 @@ pub enum Error { NetworkErr(NetworkError), ParticipantErr(ParticipantError), StreamErr(StreamError), + ServerWentMad, ServerTimeout, ServerShutdown, TooManyPlayers, @@ -17,7 +18,6 @@ pub enum Error { AuthClientError(AuthClientError), AuthServerUrlInvalid(String), AuthServerNotTrusted, - HostnameLookupFailed(std::io::Error), Banned(String), /// Persisted character data is invalid or missing InvalidCharacter, diff --git a/client/src/lib.rs b/client/src/lib.rs index 064d0b3a1d..df73a2a780 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -203,8 +203,10 @@ pub struct CharacterList { } impl Client { + /// Create a new `Client`. pub async fn new( addr: ConnectionArgs, + view_distance: Option, runtime: Arc, // TODO: refactor to avoid needing to use this out parameter mismatched_server_info: &mut Option, @@ -212,21 +214,20 @@ impl Client { let network = Network::new(Pid::new(), &runtime); let participant = match addr { - ConnectionArgs::Tcp { - hostname, - prefer_ipv6, - } => addr::try_connect(&network, &hostname, prefer_ipv6, ConnectAddr::Tcp).await?, - ConnectionArgs::Quic { - hostname, - prefer_ipv6, - } => { - let mut config = quinn::ClientConfigBuilder::default(); - config.protocols(&[b"VELOREN"]); - let config = config.build(); - addr::try_connect(&network, &hostname, prefer_ipv6, |a| { - ConnectAddr::Quic(a, config.clone(), hostname.clone()) - }) - .await? + ConnectionArgs::IpAndPort(addrs) => { + // Try to connect to all IP's and return the first that works + let mut participant = None; + for addr in addrs { + match network.connect(ConnectAddr::Tcp(addr)).await { + Ok(p) => { + participant = Some(Ok(p)); + break; + }, + Err(e) => participant = Some(Err(Error::NetworkErr(e))), + } + } + participant + .unwrap_or_else(|| Err(Error::Other("No Ip Addr provided".to_string())))? }, ConnectionArgs::Mpsc(id) => network.connect(ConnectAddr::Mpsc(id)).await?, }; @@ -693,7 +694,7 @@ impl Client { tick: 0, state, - view_distance: None, + view_distance, loaded_distance: 0.0, pending_chunks: HashMap::new(), @@ -2446,6 +2447,7 @@ impl Drop for Client { #[cfg(test)] mod tests { use super::*; + use std::net::SocketAddr; #[test] /// THIS TEST VERIFIES THE CONSTANT API. @@ -2455,16 +2457,17 @@ mod tests { /// CONTACT @Core Developer BEFORE MERGING CHANGES TO THIS TEST fn constant_api_test() { use common::clock::Clock; + use std::net::{IpAddr, Ipv4Addr}; const SPT: f64 = 1.0 / 60.0; + let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9000); + let view_distance: Option = None; let runtime = Arc::new(Runtime::new().unwrap()); let runtime2 = Arc::clone(&runtime); let veloren_client: Result = runtime.block_on(Client::new( - ConnectionArgs::Tcp { - hostname: "127.0.0.1:9000".to_owned(), - prefer_ipv6: false, - }, + ConnectionArgs::IpAndPort(vec![socket]), + view_distance, runtime2, &mut None, )); diff --git a/common/frontend/src/lib.rs b/common/frontend/src/lib.rs index 40278de603..522c34a118 100644 --- a/common/frontend/src/lib.rs +++ b/common/frontend/src/lib.rs @@ -59,7 +59,6 @@ where .add_directive("tokio_util=info".parse().unwrap()) .add_directive("rustls=info".parse().unwrap()) .add_directive("veloren_network_protocol=info".parse().unwrap()) - .add_directive("quinn_proto::connection=info".parse().unwrap()) .add_directive( "veloren_server::persistence::character=info" .parse() diff --git a/server/Cargo.toml b/server/Cargo.toml index 4f24502bd5..e6c61d8516 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -20,7 +20,7 @@ common-state = { package = "veloren-common-state", path = "../common/state" } common-systems = { package = "veloren-common-systems", path = "../common/systems" } common-net = { package = "veloren-common-net", path = "../common/net" } world = { package = "veloren-world", path = "../world" } -network = { package = "veloren-network", path = "../network", features = ["metrics", "compression", "quic"], default-features = false } +network = { package = "veloren-network", path = "../network", features = ["metrics", "compression"], default-features = false } # inline_tweak = "1.0.8" @@ -33,7 +33,6 @@ vek = { version = "0.14.1", features = ["serde"] } futures-util = "0.3.7" tokio = { version = "1", default-features = false, features = ["rt"] } prometheus-hyper = "0.1.2" -quinn = "0.7.2" atomicwrites = "0.3.0" chrono = { version = "0.4.9", features = ["serde"] } humantime = "2.1.0" diff --git a/server/src/lib.rs b/server/src/lib.rs index 84883e4d74..705f5178b5 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -398,38 +398,6 @@ impl Server { }); runtime.block_on(network.listen(ListenAddr::Tcp(settings.gameserver_address)))?; runtime.block_on(network.listen(ListenAddr::Mpsc(14004)))?; - if let Some(quic) = &settings.quic_files { - use std::fs; - match || -> Result<_, Box> { - let mut server_config = - quinn::ServerConfigBuilder::new(quinn::ServerConfig::default()); - server_config.protocols(&[b"VELOREN"]); - let key = fs::read(&quic.key)?; - let key = if quic.key.extension().map_or(false, |x| x == "der") { - quinn::PrivateKey::from_der(&key)? - } else { - quinn::PrivateKey::from_pem(&key)? - }; - let cert_chain = fs::read(&quic.cert)?; - let cert_chain = if quic.cert.extension().map_or(false, |x| x == "der") { - quinn::CertificateChain::from_certs(Some( - quinn::Certificate::from_der(&cert_chain).unwrap(), - )) - } else { - quinn::CertificateChain::from_pem(&cert_chain)? - }; - server_config.certificate(cert_chain, key)?; - Ok(server_config.build()) - }() { - Ok(server_config) => { - runtime.block_on( - network - .listen(ListenAddr::Quic(settings.gameserver_address, server_config)), - )?; - }, - Err(e) => error!(?e, "Failed to load Quic Certificate, run without Quic"), - } - } let connection_handler = ConnectionHandler::new(network, &runtime); // Initiate real-time world simulation diff --git a/server/src/settings.rs b/server/src/settings.rs index 5c819381d1..1424af9fe5 100644 --- a/server/src/settings.rs +++ b/server/src/settings.rs @@ -33,19 +33,12 @@ const BANLIST_FILENAME: &str = "banlist.ron"; const SERVER_DESCRIPTION_FILENAME: &str = "description.ron"; const ADMINS_FILENAME: &str = "admins.ron"; -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct X509FilePair { - pub cert: PathBuf, - pub key: PathBuf, -} - #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(default)] pub struct Settings { pub gameserver_address: SocketAddr, pub metrics_address: SocketAddr, pub auth_server_address: Option, - pub quic_files: Option, pub max_players: usize, pub world_seed: u32, //pub pvp_enabled: bool, @@ -69,7 +62,6 @@ impl Default for Settings { gameserver_address: SocketAddr::from(([0; 4], 14004)), metrics_address: SocketAddr::from(([0; 4], 14005)), auth_server_address: Some("https://auth.veloren.net".into()), - quic_files: None, world_seed: DEFAULT_WORLD_SEED, server_name: "Veloren Alpha".into(), max_players: 100, @@ -148,7 +140,6 @@ impl Settings { pick_unused_port().expect("Failed to find unused port!"), )), auth_server_address: None, - quic_files: None, // If loading the default map file, make sure the seed is also default. world_seed: if load.map_file.is_some() { load.world_seed diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index 007914cb4d..a7825976a7 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -116,10 +116,6 @@ impl PlayState for CharSelectionState { }, ui::Event::Play(character_id) => { self.client.borrow_mut().request_character(character_id); - //Send our ViewDistance - self.client - .borrow_mut() - .set_view_distance(global_state.settings.graphics.view_distance); return PlayStateResult::Switch(Box::new(SessionState::new( global_state, diff --git a/voxygen/src/menu/main/client_init.rs b/voxygen/src/menu/main/client_init.rs index 622633660c..de69abc5a5 100644 --- a/voxygen/src/menu/main/client_init.rs +++ b/voxygen/src/menu/main/client_init.rs @@ -17,6 +17,7 @@ use tracing::{trace, warn}; #[derive(Debug)] pub enum Error { + NoAddress, ClientError { error: ClientError, mismatched_server_info: Option, @@ -30,6 +31,12 @@ pub enum Msg { Done(Result), } +pub enum ClientConnArgs { + Host(String), + #[allow(dead_code)] //singleplayer + Resolved(ConnectionArgs), +} + pub struct AuthTrust(String, bool); // Used to asynchronously parse the server address, resolve host names, @@ -44,8 +51,9 @@ impl ClientInit { #[allow(clippy::op_ref)] // TODO: Pending review in #587 #[allow(clippy::or_fun_call)] // TODO: Pending review in #587 pub fn new( - connection_args: ConnectionArgs, + connection_args: ClientConnArgs, username: String, + view_distance: Option, password: String, runtime: Option>, ) -> Self { @@ -81,6 +89,18 @@ impl ClientInit { .unwrap_or(false) }; + let connection_args = match connection_args { + ClientConnArgs::Host(host) => match ConnectionArgs::resolve(&host, false).await { + Ok(r) => r, + Err(_) => { + let _ = tx.send(Msg::Done(Err(Error::NoAddress))); + tokio::task::block_in_place(move || drop(runtime2)); + return; + }, + }, + ClientConnArgs::Resolved(r) => r, + }; + let mut last_err = None; const FOUR_MINUTES_RETRIES: u64 = 48; @@ -91,6 +111,7 @@ impl ClientInit { let mut mismatched_server_info = None; match Client::new( connection_args.clone(), + view_distance, Arc::clone(&runtime2), &mut mismatched_server_info, ) @@ -125,11 +146,8 @@ impl ClientInit { tokio::time::sleep(Duration::from_secs(5)).await; } - // Only possibility for no last_err is aborting - let _ = tx.send(Msg::Done(Err(last_err.unwrap_or(Error::ClientError { - error: ClientError::Other("Connection attempt aborted by user".to_owned()), - mismatched_server_info: None, - })))); + // Parsing/host name resolution successful but no connection succeeded. + let _ = tx.send(Msg::Done(Err(last_err.unwrap_or(Error::NoAddress)))); // Safe drop runtime tokio::task::block_in_place(move || drop(runtime2)); diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index d03c45167b..dac729c725 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -5,18 +5,22 @@ use super::char_selection::CharSelectionState; #[cfg(feature = "singleplayer")] use crate::singleplayer::Singleplayer; use crate::{ - i18n::LocalizationHandle, render::Renderer, settings::Settings, window::Event, Direction, - GlobalState, PlayState, PlayStateResult, + i18n::{Localization, LocalizationHandle}, + render::Renderer, + settings::Settings, + window::Event, + Direction, GlobalState, PlayState, PlayStateResult, }; +#[cfg(feature = "singleplayer")] +use client::addr::ConnectionArgs; use client::{ - addr::ConnectionArgs, error::{InitProtocolError, NetworkConnectError, NetworkError}, ServerInfo, }; -use client_init::{ClientInit, Error as InitError, Msg as InitMsg}; +use client_init::{ClientConnArgs, ClientInit, Error as InitError, Msg as InitMsg}; use common::comp; use common_base::span; -use std::sync::Arc; +use std::{fmt::Debug, sync::Arc}; use tokio::runtime; use tracing::error; use ui::{Event as MainMenuEvent, MainMenuUi}; @@ -70,10 +74,11 @@ impl PlayState for MainMenuState { Ok(Ok(runtime)) => { // Attempt login after the server is finished initializing attempt_login( + &mut global_state.settings, &mut global_state.info_message, "singleplayer".to_owned(), "".to_owned(), - ConnectionArgs::Mpsc(14004), + ClientConnArgs::Resolved(ConnectionArgs::Mpsc(14004)), &mut self.client_init, Some(runtime), ); @@ -115,14 +120,117 @@ impl PlayState for MainMenuState { std::rc::Rc::new(std::cell::RefCell::new(client)), ))); }, - Some(InitMsg::Done(Err(e))) => { + Some(InitMsg::Done(Err(err))) => { + let localized_strings = global_state.i18n.read(); self.client_init = None; - tracing::trace!(?e, "raw Client Init error"); - let e = get_client_msg_error(e, &global_state.i18n); - // Log error for possible additional use later or incase that the error - // displayed is cut of. - error!(?e, "Client Init failed"); - global_state.info_message = Some(e); + global_state.info_message = Some({ + let err = match err { + InitError::NoAddress => { + localized_strings.get("main.login.server_not_found").into() + }, + InitError::ClientError { + error, + mismatched_server_info, + } => match error { + client::Error::SpecsErr(e) => format!( + "{}: {}", + localized_strings.get("main.login.internal_error"), + e + ), + client::Error::AuthErr(e) => format!( + "{}: {}", + localized_strings.get("main.login.authentication_error"), + e + ), + client::Error::Kicked(e) => e, + client::Error::TooManyPlayers => { + localized_strings.get("main.login.server_full").into() + }, + client::Error::AuthServerNotTrusted => localized_strings + .get("main.login.untrusted_auth_server") + .into(), + client::Error::ServerWentMad => localized_strings + .get("main.login.outdated_client_or_server") + .into(), + client::Error::ServerTimeout => { + localized_strings.get("main.login.timeout").into() + }, + client::Error::ServerShutdown => { + localized_strings.get("main.login.server_shut_down").into() + }, + client::Error::NotOnWhitelist => { + localized_strings.get("main.login.not_on_whitelist").into() + }, + client::Error::Banned(reason) => format!( + "{}: {}", + localized_strings.get("main.login.banned"), + reason + ), + client::Error::InvalidCharacter => { + localized_strings.get("main.login.invalid_character").into() + }, + client::Error::NetworkErr(NetworkError::ConnectFailed( + NetworkConnectError::Handshake(InitProtocolError::WrongVersion(_)), + )) => get_network_error_text( + &localized_strings, + localized_strings.get("main.login.network_wrong_version"), + mismatched_server_info, + ), + client::Error::NetworkErr(e) => get_network_error_text( + &localized_strings, + e, + mismatched_server_info, + ), + client::Error::ParticipantErr(e) => get_network_error_text( + &localized_strings, + e, + mismatched_server_info, + ), + client::Error::StreamErr(e) => get_network_error_text( + &localized_strings, + e, + mismatched_server_info, + ), + client::Error::Other(e) => { + format!("{}: {}", localized_strings.get("common.error"), e) + }, + client::Error::AuthClientError(e) => match e { + // TODO: remove parentheses + client::AuthClientError::RequestError(e) => format!( + "{}: {}", + localized_strings.get("main.login.failed_sending_request"), + e + ), + client::AuthClientError::JsonError(e) => format!( + "{}: {}", + localized_strings.get("main.login.failed_sending_request"), + e + ), + client::AuthClientError::InsecureSchema => localized_strings + .get("main.login.insecure_auth_scheme") + .into(), + client::AuthClientError::ServerError(_, e) => { + String::from_utf8_lossy(&e).to_string() + }, + }, + client::Error::AuthServerUrlInvalid(e) => { + format!( + "{}: https://{}", + localized_strings + .get("main.login.failed_auth_server_url_invalid"), + e + ) + }, + }, + InitError::ClientCrashed => { + localized_strings.get("main.login.client_crashed").into() + }, + }; + // Log error for possible additional use later or incase that the error + // displayed is cut of. + error!("{}", err); + err + }); }, Some(InitMsg::IsAuthTrusted(auth_server)) => { if global_state @@ -156,7 +264,6 @@ impl PlayState for MainMenuState { server_address, } => { let mut net_settings = &mut global_state.settings.networking; - let use_quic = net_settings.use_quic; net_settings.username = username.clone(); net_settings.default_server = server_address.clone(); if !net_settings.servers.contains(&server_address) { @@ -164,22 +271,12 @@ impl PlayState for MainMenuState { } global_state.settings.save_to_file_warn(); - let connection_args = if use_quic { - ConnectionArgs::Quic { - hostname: server_address, - prefer_ipv6: false, - } - } else { - ConnectionArgs::Tcp { - hostname: server_address, - prefer_ipv6: false, - } - }; attempt_login( + &mut global_state.settings, &mut global_state.info_message, username, password, - connection_args, + ClientConnArgs::Host(server_address), &mut self.client_init, None, ); @@ -250,110 +347,37 @@ impl PlayState for MainMenuState { } } -fn get_client_msg_error(e: client_init::Error, localized_strings: &LocalizationHandle) -> String { - let localization = localized_strings.read(); - - // When a network error is received and there is a mismatch between the client - // and server version it is almost definitely due to this mismatch rather than - // a true networking error. - let net_e = |error: String, mismatched_server_info: Option| -> String { - if let Some(server_info) = mismatched_server_info { - format!( - "{} {}: {} {}: {}", - localization.get("main.login.network_wrong_version"), - localization.get("main.login.client_version"), - common::util::GIT_HASH.to_string(), - localization.get("main.login.server_version"), - server_info.git_hash - ) - } else { - format!( - "{}: {}", - localization.get("main.login.network_error"), - error - ) - } - }; - - use client::Error; - match e { - InitError::ClientError { - error, - mismatched_server_info, - } => match error { - Error::SpecsErr(e) => { - format!("{}: {}", localization.get("main.login.internal_error"), e) - }, - Error::AuthErr(e) => format!( - "{}: {}", - localization.get("main.login.authentication_error"), - e - ), - Error::Kicked(e) => e, - Error::TooManyPlayers => localization.get("main.login.server_full").into(), - Error::AuthServerNotTrusted => { - localization.get("main.login.untrusted_auth_server").into() - }, - Error::ServerTimeout => localization.get("main.login.timeout").into(), - Error::ServerShutdown => localization.get("main.login.server_shut_down").into(), - Error::NotOnWhitelist => localization.get("main.login.not_on_whitelist").into(), - Error::Banned(reason) => { - format!("{}: {}", localization.get("main.login.banned"), reason) - }, - Error::InvalidCharacter => localization.get("main.login.invalid_character").into(), - Error::NetworkErr(NetworkError::ConnectFailed(NetworkConnectError::Handshake( - InitProtocolError::WrongVersion(_), - ))) => net_e( - localization - .get("main.login.network_wrong_version") - .to_owned(), - mismatched_server_info, - ), - Error::NetworkErr(e) => net_e(e.to_string(), mismatched_server_info), - Error::ParticipantErr(e) => net_e(e.to_string(), mismatched_server_info), - Error::StreamErr(e) => net_e(e.to_string(), mismatched_server_info), - Error::HostnameLookupFailed(e) => { - format!("{}: {}", localization.get("main.login.server_not_found"), e) - }, - Error::Other(e) => { - format!("{}: {}", localization.get("common.error"), e) - }, - Error::AuthClientError(e) => match e { - // TODO: remove parentheses - client::AuthClientError::RequestError(e) => format!( - "{}: {}", - localization.get("main.login.failed_sending_request"), - e - ), - client::AuthClientError::JsonError(e) => format!( - "{}: {}", - localization.get("main.login.failed_sending_request"), - e - ), - client::AuthClientError::InsecureSchema => { - localization.get("main.login.insecure_auth_scheme").into() - }, - client::AuthClientError::ServerError(_, e) => { - String::from_utf8_lossy(&e).to_string() - }, - }, - Error::AuthServerUrlInvalid(e) => { - format!( - "{}: https://{}", - localization.get("main.login.failed_auth_server_url_invalid"), - e - ) - }, - }, - InitError::ClientCrashed => localization.get("main.login.client_crashed").into(), +/// When a network error is received and there is a mismatch between the client +/// and server version it is almost definitely due to this mismatch rather than +/// a true networking error. +fn get_network_error_text( + localization: &Localization, + error: impl Debug, + mismatched_server_info: Option, +) -> String { + if let Some(server_info) = mismatched_server_info { + format!( + "{} {}: {} {}: {}", + localization.get("main.login.network_wrong_version"), + localization.get("main.login.client_version"), + common::util::GIT_HASH.to_string(), + localization.get("main.login.server_version"), + server_info.git_hash + ) + } else { + format!( + "{}: {:?}", + localization.get("main.login.network_error"), + error + ) } } - fn attempt_login( + settings: &mut Settings, info_message: &mut Option, username: String, password: String, - connection_args: ConnectionArgs, + connection_args: ClientConnArgs, client_init: &mut Option, runtime: Option>, ) { @@ -367,6 +391,7 @@ fn attempt_login( *client_init = Some(ClientInit::new( connection_args, username, + Some(settings.graphics.view_distance), password, runtime, )); diff --git a/voxygen/src/settings/networking.rs b/voxygen/src/settings/networking.rs index 402fb5f4e4..4732b5dc7e 100644 --- a/voxygen/src/settings/networking.rs +++ b/voxygen/src/settings/networking.rs @@ -9,7 +9,6 @@ pub struct NetworkingSettings { pub servers: Vec, pub default_server: String, pub trusted_auth_servers: HashSet, - pub use_quic: bool, } impl Default for NetworkingSettings { @@ -22,7 +21,6 @@ impl Default for NetworkingSettings { .iter() .map(|s| s.to_string()) .collect(), - use_quic: false, } } }