summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--src/components/equipment.rs20
-rw-r--r--src/config.rs19
-rw-r--r--src/main.rs45
-rw-r--r--src/parameter.rs8
-rw-r--r--src/server/address.rs42
-rw-r--r--src/server/mod.rs1
-rw-r--r--src/util.rs5
-rw-r--r--todo.md1
9 files changed, 88 insertions, 54 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 7c9776e..bbd5c8e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,3 +16,4 @@ rand = "0.7"
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
ctrlc = { version = "3.1", features = ["termination"] }
+structopt = "0.3"
diff --git a/src/components/equipment.rs b/src/components/equipment.rs
index c19563f..8f7b9ab 100644
--- a/src/components/equipment.rs
+++ b/src/components/equipment.rs
@@ -1,6 +1,6 @@
use std::collections::HashMap;
-use serde_json::{json, Value};
+use serde_json::Value;
use specs::{
Component,
HashMapStorage
@@ -21,12 +21,6 @@ impl Slot {
_ => None
}
}
- pub fn to_string(&self) -> String {
- match self {
- Self::Hand => "hand",
- Self::Body => "body"
- }.to_string()
- }
}
@@ -44,12 +38,6 @@ impl Stat {
_ => None
}
}
- pub fn to_string(&self) -> String {
- match self {
- Self::Strength => "strength",
- Self::Defence => "defence"
- }.to_string()
- }
}
@@ -73,12 +61,6 @@ impl Equippable {
.collect::<Option<HashMap<Stat, i64>>>()?
})
}
- pub fn to_json(&self) -> Value {
- json!({
- "slot": self.slot.to_string(),
- "stats": self.stats.iter().map(|(k, v)| (k.to_string(), *v)).collect::<HashMap<String, i64>>()
- })
- }
}
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..9d2c480
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,19 @@
+
+use structopt::StructOpt;
+use std::path::PathBuf;
+use crate::Address;
+
+#[derive(Debug, StructOpt)]
+#[structopt(name = "Rustifarm", about = "Asciifarm server in Rust")]
+pub struct Config {
+
+ #[structopt(short, long, help="A server type and address. Allowed server types: 'inet', 'unix', 'abstract'. Example: \"inet:127.0.0.1:1234\" or \"abstract:rustifarm\"")]
+ pub address: Option<Vec<Address>>,
+
+ #[structopt(short, long, env="ASCIIFARM_CONTENT_DIR", help="The directory in which the content specifying the world is (maps/encyclopaedia)")]
+ pub content_dir: Option<PathBuf>,
+
+ #[structopt(short, long, env="ASCIIFARM_SAVE_DIR", help="The directory in which the savegames are")]
+ pub save_dir: Option<PathBuf>,
+
+}
diff --git a/src/main.rs b/src/main.rs
index 68e0f50..b55c6a4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,10 +1,11 @@
use std::thread::sleep;
use std::time::Duration;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::fs;
use serde_json;
+use structopt::StructOpt;
mod server;
mod gameserver;
@@ -33,6 +34,7 @@ mod world;
mod sprite;
mod timestamp;
mod purgatory;
+mod config;
use self::{
pos::Pos,
@@ -42,14 +44,11 @@ use self::{
sprite::Sprite,
template::Template,
encyclopedia::Encyclopedia,
- timestamp::Timestamp
-};
-
-use self::{
+ timestamp::Timestamp,
+
gameserver::GameServer,
- server::unixserver::UnixServer,
- server::tcpserver::TcpServer,
server::Server,
+ server::address::Address,
persistence::FileStorage,
controls::Action,
worldloader::WorldLoader,
@@ -61,22 +60,32 @@ use self::{
fn main() -> Result<()>{
- let mut servers: Vec<Box<dyn Server>> = Vec::new();
-
- let addr = Path::new("\0rustifarm");
- let unixserver = UnixServer::new(&addr)?;
- servers.push(Box::new(unixserver));
+ let config = config::Config::from_args();
- let addr = "127.0.0.1:1234".parse()?;
- let inetserver = TcpServer::new(&addr)?;
- servers.push(Box::new(inetserver));
+ let adresses = config.address
+ .unwrap_or(vec!["abstract:rustifarm".parse()?, "inet:127.0.0.1:1234".parse()?]);
+ println!("adresses: {:?}", adresses);
+ let servers: Vec<Box<dyn Server>> =
+ adresses
+ .iter()
+ .map(|a| a.to_server().unwrap())
+ .collect();
let mut gameserver = GameServer::new(servers);
- let content_dir = PathBuf::new().join(std::env::var("CARGO_MANIFEST_DIR").unwrap_or(".".to_string())).join("content/");
+ let content_dir = config.content_dir.unwrap_or(
+ PathBuf::new()
+ .join(std::env::var("CARGO_MANIFEST_DIR").unwrap_or(".".to_string()))
+ .join("content/")
+ );
+ println!("content directory: {:?}", content_dir);
let loader = WorldLoader::new(content_dir.join("maps"));
- let storage = FileStorage::new(FileStorage::savedir().expect("couldn't find any save directory"));
+ let save_dir = config.save_dir.unwrap_or(
+ FileStorage::savedir().expect("couldn't find any save directory")
+ );
+ println!("save directory: {:?}", content_dir);
+ let storage = FileStorage::new(save_dir);
let encyclopedia = Encyclopedia::from_json(
serde_json::from_str(
@@ -146,3 +155,5 @@ fn main() -> Result<()>{
}
+
+
diff --git a/src/parameter.rs b/src/parameter.rs
index 5466ce6..ed445b3 100644
--- a/src/parameter.rs
+++ b/src/parameter.rs
@@ -69,12 +69,12 @@ parameters!(
Pos (Pos) pos, v (Pos::from_json(v)?) (json!(v));
Float (f64) float, v (v.as_f64()?) (json!(v));
Template (Template) template, v (Template::from_json(v).ok()?) (v.to_json());
- Action (ItemAction) action, v (ItemAction::from_json(v)?) (panic!("item actions can't be serialized"));
- Interaction (Interactable) interaction, v (Interactable::from_json(v)?) (panic!("interactions can't be serialized"));
+ Action (ItemAction) action, _v (ItemAction::from_json(_v)?) (panic!("item actions can't be serialized"));
+ Interaction (Interactable) interaction, _v (Interactable::from_json(_v)?) (panic!("interactions can't be serialized"));
Bool (bool) bool, v (v.as_bool()?) (json!(v));
- List (Vec<Parameter>) list, v
+ List (Vec<Parameter>) list, _v
({
- v
+ _v
.as_array()?
.iter()
.map(|item| Parameter::guess_from_json(item))
diff --git a/src/server/address.rs b/src/server/address.rs
index 3d8e59f..9fb7bea 100644
--- a/src/server/address.rs
+++ b/src/server/address.rs
@@ -1,19 +1,45 @@
+use std::path::PathBuf;
use std::net::SocketAddr;
-use std::path::Path;
+use std::str::FromStr;
use crate::{
Result,
- aerr
+ aerr,
+ util::AnyError
};
use super::tcpserver::TcpServer;
use super::unixserver::UnixServer;
use super::Server;
-pub fn server_from_address(typename: &str, text: &str) -> Result<Box<dyn Server>> {
- match typename {
- "inet" => Ok(Box::new(TcpServer::new(&text.parse()?)?)),
- "unix" => Ok(Box::new(UnixServer::new(Path::new(text))?)),
- "abstract" => Ok(Box::new(UnixServer::new(Path::new(&format!("\0{}", text)))?)),
- _ => Err(aerr!("Invalid address type"))
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum Address {
+ Inet(SocketAddr),
+ Unix(PathBuf)
+}
+
+impl Address {
+ pub fn to_server(&self) -> Result<Box<dyn Server>> {
+ match self {
+ Address::Inet(addr) => Ok(Box::new(TcpServer::new(addr)?)),
+ Address::Unix(path) => Ok(Box::new(UnixServer::new(path)?)),
+ }
+ }
+}
+
+impl FromStr for Address {
+ type Err = AnyError;
+ fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+ let parts: Vec<&str> = s.splitn(2, ':').collect();
+ if parts.len() != 2 {
+ return Err(aerr!("Address string has the wrong length!"));
+ }
+ let typename = parts[0];
+ let text = parts[1];
+ match typename {
+ "inet" => Ok(Address::Inet(text.parse()?)),
+ "unix" => Ok(Address::Unix(PathBuf::new().join(text))),
+ "abstract" => Ok(Address::Unix(PathBuf::new().join(&format!("\0{}", text)))),
+ _ => Err(aerr!(&format!("'{}' is not a valid address type", typename)))
+ }
}
}
diff --git a/src/server/mod.rs b/src/server/mod.rs
index 131eb19..71b1f96 100644
--- a/src/server/mod.rs
+++ b/src/server/mod.rs
@@ -2,6 +2,7 @@ use std::io;
pub mod tcpserver;
pub mod unixserver;
+pub mod address;
mod streamconnection;
diff --git a/src/util.rs b/src/util.rs
index db572c6..9b46d42 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -41,11 +41,6 @@ macro_rules! aerr {
($description:expr) => {Box::new(crate::util::AError::new($description))}
}
-#[macro_export]
-macro_rules! err {
- ($description:expr) => {Err(crate::aerr!($description))}
-}
-
#[macro_export]
macro_rules! hashmap {
diff --git a/todo.md b/todo.md
index 7af61f5..6a0b1f6 100644
--- a/todo.md
+++ b/todo.md
@@ -3,7 +3,6 @@
- make readme
- more tests
-- command line options
- private rooms
- timer resource?
- log world events to player