From 30c9fcc9117190ee79cab900f3881e2e1fac7039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=A4rtens?= Date: Fri, 11 Oct 2019 14:19:55 +0200 Subject: [PATCH] Fix bug that metrics took a random port always introduced in !584 also removed the duplicate port from the server creation process, using the server settings struct now --- Cargo.lock | 1 - server/src/lib.rs | 18 +++++++----------- server/src/metrics.rs | 9 ++------- server/src/settings.rs | 17 ++++++++++++++--- voxygen/Cargo.toml | 3 +-- voxygen/src/menu/main/start_singleplayer.rs | 16 ++++++++++------ voxygen/src/singleplayer.rs | 15 ++++----------- 7 files changed, 38 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91d29cfbf6..c29c84b296 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3635,7 +3635,6 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "msgbox 0.2.0 (git+https://github.com/bekker/msgbox-rs.git)", "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "portpicker 0.1.0 (git+https://github.com/wusyong/portpicker-rs?branch=fix_ipv6)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rodio 0.9.0 (git+https://github.com/RustAudio/rodio?rev=e5474a2)", "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/server/src/lib.rs b/server/src/lib.rs index 566881b8d6..811454ea8d 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -30,13 +30,12 @@ use common::{ }; use crossbeam::channel; use hashbrown::{hash_map::Entry, HashMap}; -use log::debug; +use log::{debug, trace}; use metrics::ServerMetrics; use rand::Rng; use specs::{join::Join, world::EntityBuilder as EcsEntityBuilder, Builder, Entity as EcsEntity}; use std::{ i32, - net::SocketAddr, sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -92,13 +91,8 @@ pub struct Server { } impl Server { - /// Create a new `Server` bound to the default socket. + /// Create a new `Server` pub fn new(settings: ServerSettings) -> Result { - Self::bind(settings.address, settings) - } - - /// Create a new server bound to the given socket. - pub fn bind>(addrs: A, settings: ServerSettings) -> Result { let (chunk_tx, chunk_rx) = channel::unbounded(); let mut state = State::default(); @@ -116,7 +110,7 @@ impl Server { state, world: Arc::new(World::generate(settings.world_seed)), - postoffice: PostOffice::bind(addrs.into())?, + postoffice: PostOffice::bind(settings.gameserver_address)?, clients: Clients::empty(), thread_pool: ThreadPoolBuilder::new() @@ -131,10 +125,12 @@ impl Server { description: settings.server_description.clone(), git_hash: common::util::GIT_HASH.to_string(), }, - metrics: ServerMetrics::new(), + metrics: ServerMetrics::new(settings.metrics_address), accounts: AuthProvider::new(), - server_settings: settings, + server_settings: settings.clone(), }; + debug!("created veloren server"); + trace!("server configuration: {:?}", &settings); Ok(this) } diff --git a/server/src/metrics.rs b/server/src/metrics.rs index ec0ea388b1..4e9ee9666e 100644 --- a/server/src/metrics.rs +++ b/server/src/metrics.rs @@ -1,10 +1,9 @@ use log::info; -use portpicker::pick_unused_port; use prometheus::{Encoder, Gauge, IntGauge, IntGaugeVec, Opts, Registry, TextEncoder}; use rouille::{router, Server}; use std::{ convert::TryInto, - net::{IpAddr, Ipv4Addr, SocketAddr}, + net::SocketAddr, sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -29,7 +28,7 @@ pub struct ServerMetrics { } impl ServerMetrics { - pub fn new() -> Self { + pub fn new(addr: SocketAddr) -> Self { let opts = Opts::new( "player_online", "shows the number of clients connected to the server", @@ -95,10 +94,6 @@ impl ServerMetrics { //TODO: make this a job let handle = Some(thread::spawn(move || { - let addr = SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), - pick_unused_port().expect("Failed to find unused port!"), - ); let server = Server::new(addr, move |request| { router!(request, (GET) (/metrics) => { diff --git a/server/src/settings.rs b/server/src/settings.rs index f96ecd876f..4b2dadecd2 100644 --- a/server/src/settings.rs +++ b/server/src/settings.rs @@ -1,10 +1,12 @@ +use portpicker::pick_unused_port; use serde_derive::{Deserialize, Serialize}; use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf}; #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(default)] pub struct ServerSettings { - pub address: SocketAddr, + pub gameserver_address: SocketAddr, + pub metrics_address: SocketAddr, pub max_players: usize, pub world_seed: u32, //pub pvp_enabled: bool, @@ -18,7 +20,8 @@ pub struct ServerSettings { impl Default for ServerSettings { fn default() -> Self { Self { - address: SocketAddr::from(([0; 4], 14004)), + gameserver_address: SocketAddr::from(([0; 4], 14004)), + metrics_address: SocketAddr::from(([0; 4], 14005)), world_seed: 1337, server_name: "Veloren Alpha".to_owned(), server_description: "This is the best Veloren server.".to_owned(), @@ -63,7 +66,15 @@ impl ServerSettings { pub fn singleplayer() -> Self { Self { - address: SocketAddr::from(([0; 4], 14004)), + //BUG: theoretically another process can grab the port between here and server creation, however the timewindow is quite small + gameserver_address: SocketAddr::from(( + [127, 0, 0, 1], + pick_unused_port().expect("Failed to find unused port!"), + )), + metrics_address: SocketAddr::from(( + [127, 0, 0, 1], + pick_unused_port().expect("Failed to find unused port!"), + )), world_seed: 1337, server_name: "Singleplayer".to_owned(), server_description: "Who needs friends anyway?".to_owned(), diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index 8cc8bacc97..8264426b50 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -8,7 +8,7 @@ default-run = "veloren-voxygen" [features] gl = ["gfx_device_gl"] discord = ["discord-rpc-sdk", "lazy_static"] -singleplayer = ["server", "portpicker"] +singleplayer = ["server"] default = ["gl", "singleplayer", "msgbox", "heaptrack"] @@ -38,7 +38,6 @@ lazy_static = { version = "1.4.0", optional = true } # Singleplayer server = { package = "veloren-server", path = "../server", optional = true } -portpicker = { git = "https://github.com/wusyong/portpicker-rs", branch = "fix_ipv6", optional = true } # Utility glsl-include = "0.3.1" diff --git a/voxygen/src/menu/main/start_singleplayer.rs b/voxygen/src/menu/main/start_singleplayer.rs index 1f97cde4e2..c94b9a4514 100644 --- a/voxygen/src/menu/main/start_singleplayer.rs +++ b/voxygen/src/menu/main/start_singleplayer.rs @@ -5,22 +5,22 @@ use crate::{ }; use common::comp; use log::warn; -use std::net::SocketAddr; +use server::settings::ServerSettings; pub struct StartSingleplayerState { // Necessary to keep singleplayer working _singleplayer: Singleplayer, - sock: SocketAddr, + server_settings: ServerSettings, } impl StartSingleplayerState { /// Create a new `MainMenuState`. pub fn new() -> Self { - let (_singleplayer, sock) = Singleplayer::new(None); // TODO: Make client and server use the same thread pool + let (_singleplayer, server_settings) = Singleplayer::new(None); // TODO: Make client and server use the same thread pool Self { _singleplayer, - sock, + server_settings, } } } @@ -30,10 +30,14 @@ impl PlayState for StartSingleplayerState { match direction { Direction::Forwards => { let username = "singleplayer".to_owned(); - let server_address = self.sock.ip().to_string(); let client_init = ClientInit::new( - (server_address.clone(), self.sock.port(), true), + //TODO: check why we are converting out IP:Port to String instead of parsing it directly as SockAddr + ( + self.server_settings.gameserver_address.ip().to_string(), + self.server_settings.gameserver_address.port(), + true, + ), comp::Player::new( username.clone(), Some(global_state.settings.graphics.view_distance), diff --git a/voxygen/src/singleplayer.rs b/voxygen/src/singleplayer.rs index 2252924f44..620ab34b54 100644 --- a/voxygen/src/singleplayer.rs +++ b/voxygen/src/singleplayer.rs @@ -2,10 +2,8 @@ use client::Client; use common::clock::Clock; use crossbeam::channel::{unbounded, Receiver, Sender, TryRecvError}; use log::info; -use portpicker::pick_unused_port; use server::{Event, Input, Server, ServerSettings}; use std::{ - net::SocketAddr, thread::{self, JoinHandle}, time::Duration, }; @@ -27,17 +25,12 @@ pub struct Singleplayer { } impl Singleplayer { - pub fn new(client: Option<&Client>) -> (Self, SocketAddr) { + pub fn new(client: Option<&Client>) -> (Self, ServerSettings) { let (sender, receiver) = unbounded(); - let sock = SocketAddr::from(( - [127, 0, 0, 1], - pick_unused_port().expect("Failed to find unused port!"), - )); - // Create server - let server = Server::bind(sock.clone(), ServerSettings::singleplayer()) - .expect("Failed to create server instance!"); + let settings = ServerSettings::singleplayer(); + let server = Server::new(settings.clone()).expect("Failed to create server instance!"); let server = match client { Some(client) => server.with_thread_pool(client.thread_pool().clone()), @@ -53,7 +46,7 @@ impl Singleplayer { _server_thread: thread, sender, }, - sock, + settings, ) } }