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| {