Made single-player server start on random unused port

Former-commit-id: 95ec85b9be58d0fd348144c398004a69676eb6cd
This commit is contained in:
Joshua Barretto 2019-05-06 15:26:10 +01:00
parent 3705f9a871
commit 871767ada0
7 changed files with 74 additions and 29 deletions

10
Cargo.lock generated
View File

@ -1614,6 +1614,14 @@ dependencies = [
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "portpicker"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pretty_env_logger"
version = "0.3.0"
@ -2360,6 +2368,7 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msgbox 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"portpicker 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
"simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2750,6 +2759,7 @@ dependencies = [
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum png 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925"
"checksum png 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63daf481fdd0defa2d1d2be15c674fbfa1b0fd71882c303a91f9a79b3252c359"
"checksum portpicker 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b497d05c16fe00939445c00a4fe2fa4f3d3dfc9c0401a3ab5c577afda2debb9"
"checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
"checksum proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)" = "ba92c84f814b3f9a44c5cfca7d2ad77fa10710867d2bbb1b3d175ab5f47daa12"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"

View File

@ -8,10 +8,19 @@ pub mod input;
// Reexports
pub use crate::{error::Error, input::Input};
use crate::{
client::{Client, Clients},
cmd::CHAT_COMMANDS,
use std::{
collections::HashSet,
net::SocketAddr,
sync::mpsc,
time::Duration,
i32,
};
use specs::{
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
Entity as EcsEntity,
};
use threadpool::ThreadPool;
use vek::*;
use common::{
comp,
comp::character::Animation,
@ -20,14 +29,11 @@ use common::{
state::{State, Uid},
terrain::TerrainChunk,
};
use specs::{
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
Entity as EcsEntity,
};
use std::{collections::HashSet, i32, net::SocketAddr, sync::mpsc, time::Duration};
use threadpool::ThreadPool;
use vek::*;
use world::World;
use crate::{
client::{Client, Clients},
cmd::CHAT_COMMANDS,
};
const CLIENT_TIMEOUT: f64 = 20.0; // Seconds
@ -51,9 +57,15 @@ pub struct Server {
}
impl Server {
/// Create a new `Server`.
/// Create a new `Server` bound to the default socket.
#[allow(dead_code)]
pub fn new() -> Result<Self, Error> {
Self::bind(SocketAddr::from(([0; 4], 59003)))
}
/// Create a new server bound to the given socket
#[allow(dead_code)]
pub fn bind<A: Into<SocketAddr>>(addrs: A) -> Result<Self, Error> {
let (chunk_tx, chunk_rx) = mpsc::channel();
let mut state = State::new();
@ -63,7 +75,7 @@ impl Server {
state,
world: World::new(),
postoffice: PostOffice::bind(SocketAddr::from(([0; 4], 59003)))?,
postoffice: PostOffice::bind(addrs.into())?,
clients: Clients::empty(),
thread_pool: threadpool::Builder::new()

View File

@ -46,3 +46,4 @@ fnv = "1.0"
simplelog = "0.5"
msgbox = "0.1"
directories = "1.0"
portpicker = "0.1"

View File

@ -3,6 +3,8 @@ use common::comp;
use std::{
sync::mpsc::{channel, Receiver, TryRecvError},
thread::{self, JoinHandle},
net::ToSocketAddrs,
time::Duration,
};
#[derive(Debug)]
@ -20,14 +22,17 @@ pub struct ClientInit {
rx: Receiver<Result<Client, Error>>,
}
impl ClientInit {
pub fn new(connection_args: (String, u16, bool), client_args: (comp::Player, u64)) -> Self {
pub fn new(connection_args: (String, u16, bool), client_args: (comp::Player, u64), wait: bool) -> Self {
let (server_address, default_port, prefer_ipv6) = connection_args;
let (player, view_distance) = client_args;
let (tx, rx) = channel();
let handle = Some(thread::spawn(move || {
use std::net::ToSocketAddrs;
// Sleep the thread to wait for the single-player server to start up
if wait {
thread::sleep(Duration::from_millis(250));
}
// Parses 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
match server_address

View File

@ -102,6 +102,7 @@ impl PlayState for MainMenuState {
client_init = client_init.or(Some(ClientInit::new(
(server_address, DEFAULT_PORT, false),
(comp::Player::new(username.clone()), 300),
false,
)));
}
MainMenuEvent::StartSingleplayer => {

View File

@ -1,19 +1,24 @@
use super::{client_init::ClientInit, DEFAULT_PORT};
use std::net::SocketAddr;
use common::comp;
use crate::{
menu::char_selection::CharSelectionState, singleplayer::Singleplayer, Direction, GlobalState,
PlayState, PlayStateResult,
};
use common::comp;
use super::{client_init::ClientInit, DEFAULT_PORT};
pub struct StartSingleplayerState {
singleplayer: Singleplayer,
sock: SocketAddr,
}
impl StartSingleplayerState {
/// Create a new `MainMenuState`
pub fn new() -> Self {
let (singleplayer, sock) = Singleplayer::new();
Self {
singleplayer: Singleplayer::new(),
singleplayer,
sock,
}
}
}
@ -23,11 +28,12 @@ impl PlayState for StartSingleplayerState {
match direction {
Direction::Forwards => {
let username = "singleplayer".to_owned();
let server_address = "localhost".to_owned();
let server_address = self.sock.ip().to_string();
let client_init = ClientInit::new(
(server_address.clone(), DEFAULT_PORT, false),
(server_address.clone(), self.sock.port(), false),
(comp::Player::new(username.clone()), 300),
true,
);
// Client creation

View File

@ -1,9 +1,13 @@
use common::clock::Clock;
use std::{
sync::mpsc::{channel, Receiver, Sender, TryRecvError},
time::Duration,
thread::{self, JoinHandle},
net::SocketAddr,
};
use log::info;
use portpicker::pick_unused_port;
use common::clock::Clock;
use server::{Event, Input, Server};
use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError};
use std::time::Duration;
use std::{thread, thread::JoinHandle};
const TPS: u64 = 30;
@ -19,15 +23,21 @@ pub struct Singleplayer {
}
impl Singleplayer {
pub fn new() -> Self {
pub fn new() -> (Self, SocketAddr) {
let (sender, reciever) = channel();
let sock = SocketAddr::from(([0; 4], pick_unused_port()
.expect("Failed to find unused port")));
let sock2 = sock.clone();
let thread = thread::spawn(move || {
run_server(reciever);
run_server(sock2, reciever);
});
Singleplayer {
(Singleplayer {
server_thread: thread,
sender,
}
}, sock)
}
}
@ -37,14 +47,14 @@ impl Drop for Singleplayer {
}
}
fn run_server(rec: Receiver<Msg>) {
fn run_server(sock: SocketAddr, rec: Receiver<Msg>) {
info!("Starting server-cli...");
// Set up an fps clock
let mut clock = Clock::new();
// Create server
let mut server = Server::new().expect("Failed to create server instance");
let mut server = Server::bind(sock).expect("Failed to create server instance");
loop {
let events = server