diff --git a/Cargo.lock b/Cargo.lock index c0cee2a..8a54318 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,55 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + [[package]] name = "autocfg" version = "1.4.0" @@ -160,6 +209,46 @@ dependencies = [ "inout", ] +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + [[package]] name = "color-eyre" version = "0.6.3" @@ -193,6 +282,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "cpufeatures" version = "0.2.14" @@ -212,6 +307,7 @@ dependencies = [ "byteorder", "bytes", "cfb8", + "clap", "color-eyre", "fastanvil", "fastnbt 2.5.0 (git+https://github.com/owengage/fastnbt.git)", @@ -413,6 +509,12 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -458,6 +560,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itoa" version = "1.0.11" @@ -925,6 +1033,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "1.0.109" @@ -1129,6 +1243,12 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.11.0" diff --git a/Cargo.toml b/Cargo.toml index c4214dd..3ffacc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ bitfield-struct = "0.9.2" byteorder = "1.5.0" bytes = "1.8.0" cfb8 = { version = "0.8.1", optional = true } +clap = { version = "4.5.20", features = ["derive"] } color-eyre = "0.6.3" fastanvil = "0.31.0" fastnbt = { git = "https://github.com/owengage/fastnbt.git" } diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..59ac7ab --- /dev/null +++ b/src/args.rs @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Andrew Brower. + * This file is part of Crawlspace. + * + * Crawlspace is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * Crawlspace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with Crawlspace. If not, see + * . + */ + +use clap::Parser; + +#[derive(Debug, Parser)] +pub struct Args { + /// The directory to load the map from. Should be DIM1, or the equivalent renamed folder. + pub map_dir: String, + /// The address to serve crawlspace on. Defaults to [::] (all interfaces) if not set. + #[arg(short, long)] + addr: Option, + /// The port to serve crawlspace on. Defaults to 25565 if not set. + #[arg(short, long)] + port: Option, +} + +impl Args { + #[inline(always)] + pub fn addr(&self) -> String { + self.addr.clone().unwrap_or("[::]".into()) + } + + #[inline(always)] + pub fn port(&self) -> u16 { + self.port.unwrap_or(25565) + } +} diff --git a/src/main.rs b/src/main.rs index 9871eb9..b4c7351 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,8 @@ use std::{fs::OpenOptions, sync::Arc}; +use args::Args; +use clap::Parser; use color_eyre::eyre::Result; use net::cache::WorldCache; use server::Server; @@ -28,6 +30,7 @@ use world::{blocks::ALL_BLOCKS, read_world}; #[macro_use] extern crate tracing; +mod args; mod net; mod protocol; mod server; @@ -67,8 +70,10 @@ async fn main() -> Result<()> { .init(), } + let args = Args::parse(); + info!("Loading world"); - let world = read_world("./tmp/DIM1/region")?; + let world = read_world(&args.map_dir)?; info!("Done."); info!("Loading blocks"); @@ -79,17 +84,13 @@ async fn main() -> Result<()> { let world_cache = WorldCache::from(world); info!("Done."); - let port = std::env::var("PORT") - .ok() - .and_then(|p| p.parse::().ok()) - .unwrap_or(25565); - let state = Arc::new(state::State::new( VERSION, VERSION_NUM, DESCRIPTION, MAX_PLAYERS, - port, + args.addr(), + args.port(), )); #[cfg(feature = "lan")] diff --git a/src/net/mod.rs b/src/net/mod.rs index 5ffdc21..2386c0c 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -51,8 +51,9 @@ pub async fn spawn_lan_broadcast(state: CrawlState) -> Result<()> { } pub async fn spawn_net_handler(state: CrawlState) -> Result<()> { + let addr = state.addr.clone(); let port = state.port; - let listener = TcpListener::bind(format!("[::]:{port}")).await?; + let listener = TcpListener::bind(format!("{addr}:{port}")).await?; warn!("Listening on port {port}."); tokio::spawn(net_handler(state, listener)); Ok(()) diff --git a/src/state.rs b/src/state.rs index 7795a1b..624d802 100644 --- a/src/state.rs +++ b/src/state.rs @@ -34,6 +34,7 @@ pub struct State { pub description: String, pub version_name: String, pub version_number: i32, + pub addr: String, pub port: u16, pub registry_cache: RegistryCache, @@ -53,6 +54,7 @@ impl State { version_number: i32, description: &str, max_players: usize, + addr: String, port: u16, ) -> Self { let max = max_players.min(Semaphore::MAX_PERMITS); @@ -70,6 +72,7 @@ impl State { description: description.to_owned(), version_name: version_name.to_owned(), version_number: version_number.to_owned(), + addr, port, registry_cache: RegistryCache::from(&*ALL_REGISTRIES), diff --git a/src/world/mod.rs b/src/world/mod.rs index f2ce1f5..70c3108 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -17,7 +17,11 @@ * . */ -use std::{collections::HashMap, fs::File}; +use std::{ + collections::HashMap, + fs::File, + path::Path, +}; use color_eyre::eyre::Result; use fastanvil::Region; @@ -110,7 +114,8 @@ pub struct Biomes { } pub fn read_world(path: &str) -> Result { - let folder = std::fs::read_dir(path).unwrap(); + let folder = Path::new(path).join("region"); + let folder = std::fs::read_dir(folder).unwrap(); let chunks = std::sync::Mutex::new(HashMap::new()); folder.into_iter().par_bridge().for_each(|path| {