From 9eb3a9da97e53cee14e585e027badb3783b8e25e Mon Sep 17 00:00:00 2001 From: troido Date: Thu, 24 Sep 2020 22:18:30 +0200 Subject: turned sprite, playerid and roomid into tuple structs --- src/components/interactable.rs | 2 +- src/componentwrapper.rs | 4 ++-- src/fromtoparameter.rs | 8 +++++--- src/gameserver.rs | 19 +++++++++---------- src/playerid.rs | 15 ++++++++------- src/playerstate.rs | 8 ++++---- src/purgatory.rs | 2 +- src/roomid.rs | 24 ++++++++++++------------ src/sprite.rs | 23 ++++++++--------------- src/systems/interact.rs | 14 +++++++------- src/systems/migrate.rs | 2 +- src/world.rs | 4 ++-- src/worldloader.rs | 13 +++++-------- 13 files changed, 65 insertions(+), 73 deletions(-) diff --git a/src/components/interactable.rs b/src/components/interactable.rs index 2f20966..651437c 100644 --- a/src/components/interactable.rs +++ b/src/components/interactable.rs @@ -31,7 +31,7 @@ impl Interactable { pub fn parse_from_parameter(typ: &str, arg: &Parameter) -> Option { Some(match (typ, arg) { ("trigger", Parameter::String(s)) => Trigger(Trigger::from_str(s)?), - ("visit", Parameter::String(s)) => Visit(RoomId::from_str(s)), + ("visit", Parameter::String(s)) => Visit(RoomId(s.clone())), ("mine", Parameter::String(s)) => Mine(Stat::from_str(s)?), ("say", Parameter::String(s)) => Say(s.clone()), ("reply", Parameter::String(s)) => Reply(s.clone()), diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs index b952657..96fcba2 100644 --- a/src/componentwrapper.rs +++ b/src/componentwrapper.rs @@ -152,9 +152,9 @@ components!(all: Inventory () {panic!("inventory from parameters not implemented")}; Health (health: i64, maxhealth: i64); Serialise () {panic!("serialise from parameters not implemented")}; - RoomExit (destination: String, dest_pos: String) { + RoomExit (destination: RoomId, dest_pos: String) { RoomExit { - destination: RoomId::from_str(&destination), + destination, dest_pos: if dest_pos.is_empty() { RoomPos::Unknown } else { diff --git a/src/fromtoparameter.rs b/src/fromtoparameter.rs index 75912ae..8d169d0 100644 --- a/src/fromtoparameter.rs +++ b/src/fromtoparameter.rs @@ -7,7 +7,8 @@ use crate::{ Pos, PlayerId, Sprite, - ItemId + ItemId, + RoomId }; pub trait FromToParameter: Sized { @@ -78,9 +79,10 @@ tofrom!(String: String); tofrom!(Pos: Pos); tofrom!(Template: Template); -tofrom!(PlayerId{name: String}); -tofrom!(Sprite{name: String}); +tofrom!(PlayerId(String)); +tofrom!(Sprite(String)); tofrom!(ItemId(String)); +tofrom!(RoomId(String)); impl FromToParameter for Vec where diff --git a/src/gameserver.rs b/src/gameserver.rs index 7910d99..ccb9e30 100644 --- a/src/gameserver.rs +++ b/src/gameserver.rs @@ -89,7 +89,7 @@ impl GameServer { for id in left { if let Some(player) = self.players.remove(&(serverid, id)){ self.connections.remove(&player); - self.broadcast_message(&format!("{} disconnected", player.name)); + self.broadcast_message(&format!("{} disconnected", player)); actions.push(Action::Leave(player.clone())); } } @@ -149,15 +149,15 @@ impl GameServer { if self.players.contains_key(&id) { return Err(merr!(action, "You can not change your name")); } - let player = PlayerId{name}; + let player = PlayerId(name); self.authenticate(&player, auth.clone(), id)?; if self.connections.contains_key(&player) { return Err(merr!("nametaken", "Another connection to this player exists already")); } - self.broadcast_message(&format!("{} connected", player.name)); + self.broadcast_message(&format!("{} connected", player)); self.players.insert(id, player.clone()); self.connections.insert(player.clone(), id); - if let Err(_) = self.send(&player, json!(["connected", format!("successfully connected as {}", &player.name)])){ + if let Err(_) = self.send(&player, json!(["connected", format!("successfully connected as {}", player)])){ return Err(merr!("server", "unable to send connected message")) } if auth == Authentication::Guest { @@ -174,9 +174,8 @@ impl GameServer { }) } Message::Chat(text) => { - let player = self.players.get(&id).ok_or(merr!(action, "Set a valid name before you send any other messages"))?; - let name = player.name.clone(); - self.broadcast_message(&format!("{}: {}", name, text)); + let player = self.players.get(&id).ok_or(merr!(action, "Set a valid name before you send any other messages"))?.clone(); + self.broadcast_message(&format!("{}: {}", player, text)); Ok(None) } Message::Input(inp) => { @@ -196,7 +195,7 @@ impl GameServer { () } Authentication::Tilde => { - let (firstchar, username) = player.name.split_at(1); + let (firstchar, username) = player.0.split_at(1); if firstchar == "~" { if Some(username.to_string()) != self.servers[serverid].get_name(connectionid) { return Err(merr!(name, "A tilde name must match your username")); @@ -206,7 +205,7 @@ impl GameServer { Authentication::Passtoken(token) => { match self.users.load_user(player) { Ok(user) => { - if player.name != user.name { + if player.0 != user.name { println!("Name mismatch: user entry for {:?} has name {}", player, user.name); return Err(merr!("server", "name mismatch")); } @@ -216,7 +215,7 @@ impl GameServer { () } Err(LoaderError::InvalidResource(err)) => { - println!("failed to load user data for user '{}': {}", player.name, err); + println!("failed to load user data for user '{}': {}", player, err); return Err(merr!("server", "failed to load user data")) } Err(LoaderError::MissingResource(_)) => { diff --git a/src/playerid.rs b/src/playerid.rs index 08e31d2..01de524 100644 --- a/src/playerid.rs +++ b/src/playerid.rs @@ -1,11 +1,12 @@ -#[derive(Debug, Default, PartialEq, Eq, Clone, Hash)] -pub struct PlayerId { - pub name: String -} +use std::fmt; +use serde::{Serialize, Deserialize}; + +#[derive(Debug, Default, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct PlayerId(pub String); -impl PlayerId { - pub fn to_string(&self) -> String { - self.name.clone() +impl fmt::Display for PlayerId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) } } diff --git a/src/playerstate.rs b/src/playerstate.rs index f9f6a4e..f159567 100644 --- a/src/playerstate.rs +++ b/src/playerstate.rs @@ -77,7 +77,7 @@ impl PlayerState { pub fn to_json(&self) -> Value { json!({ - "name": self.id.name, + "name": self.id, "roomname": match &self.room { Some(id) => json!(id.to_string()), None => json!(null) @@ -139,9 +139,9 @@ impl PlayerState { } } Ok(Self { - id: PlayerId{name: val.get("name").ok_or(perr!("player json does not have name"))?.as_str().ok_or(perr!("player name not a string"))?.to_string()}, + id: PlayerId(val.get("name").ok_or(perr!("player json does not have name"))?.as_str().ok_or(perr!("player name not a string"))?.to_string()), room: match val.get("roomname").ok_or(perr!("player json does not have room name"))? { - Value::String(name) => Some(RoomId::from_str(name)), + Value::String(name) => Some(RoomId(name.clone())), _ => None }, pos: RoomPos::Unknown, @@ -160,7 +160,7 @@ impl PlayerState { pub fn construct(&self, encyclopedia: &Encyclopedia) -> Result { Ok(vec![ - ComponentWrapper::Visible(Visible{sprite: Sprite{name: "player".to_string()}, height: 1.75, name: self.id.name.clone()}), + ComponentWrapper::Visible(Visible{sprite: Sprite("player".to_string()), height: 1.75, name: self.id.0.clone()}), ComponentWrapper::Player(Player::new(self.id.clone())), ComponentWrapper::Inventory(Inventory{ items: self.inventory.iter().map( |(itemid, is_equipped)| { diff --git a/src/purgatory.rs b/src/purgatory.rs index f387b83..98bae6e 100644 --- a/src/purgatory.rs +++ b/src/purgatory.rs @@ -20,7 +20,7 @@ use crate::{ }; pub fn purgatory_id() -> RoomId { - RoomId{name: String::from("+")} + RoomId(String::from("+")) } pub fn create_purgatory<'a, 'b>(encyclopedia: &Encyclopedia) -> Room<'a, 'b> { diff --git a/src/roomid.rs b/src/roomid.rs index d3c0b17..22ca88b 100644 --- a/src/roomid.rs +++ b/src/roomid.rs @@ -1,21 +1,21 @@ +use std::fmt; use std::collections::HashMap; +use serde::{Serialize, Deserialize}; -#[derive(Debug, PartialEq, Eq, Clone, Hash)] -pub struct RoomId { - pub name: String -} +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct RoomId(pub String); impl RoomId { - pub fn from_str(name: &str) -> Self { - Self {name: name.to_string()} - } - pub fn to_string(&self) -> String { - self.name.clone() - } pub fn format(&self, dict: HashMap<&str, &str>) -> Self { - let name = dict.into_iter().fold(self.name.clone(), |name, (from, to)| name.replace(from, to)); - Self {name} + let name = dict.into_iter().fold(self.0.clone(), |name, (from, to)| name.replace(from, to)); + Self(name) } } + +impl fmt::Display for RoomId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} diff --git a/src/sprite.rs b/src/sprite.rs index d5f65a0..cb6af92 100644 --- a/src/sprite.rs +++ b/src/sprite.rs @@ -1,20 +1,13 @@ -use serde::{Serialize, Serializer, Deserialize, Deserializer}; +use std::fmt; +use serde::{Serialize, Deserialize}; -#[derive(Debug, Clone, PartialEq, Hash, Eq)] -pub struct Sprite { - pub name: String -} +#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] +pub struct Sprite(pub String); -impl Serialize for Sprite { - fn serialize(&self, serializer: S) -> Result - where S: Serializer { - serializer.serialize_str(self.name.as_str()) - } -} -impl<'de> Deserialize<'de> for Sprite { - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> { - Ok(Self{name: String::deserialize(deserializer)?}) + +impl fmt::Display for Sprite { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) } } diff --git a/src/systems/interact.rs b/src/systems/interact.rs index 0629dc1..81563e8 100644 --- a/src/systems/interact.rs +++ b/src/systems/interact.rs @@ -85,7 +85,7 @@ impl <'a> System<'a> for Interact { if let (Some(player), Some(whitelist)) = (players.get(actor), whitelists.get_mut(ent)){ if let Some(playername) = strip_prefix(&argument, "visit ") { let destination = dest.format(hashmap!("{player}" => playername)); - if let Some(set) = whitelist.allowed.get(&destination.name) { + if let Some(set) = whitelist.allowed.get(&destination.0) { if set.contains(&player.id){ emigration.emigrants.push((player.id.clone(), destination, RoomPos::Unknown)); } else { @@ -95,16 +95,16 @@ impl <'a> System<'a> for Interact { say(ear, format!("unknown destination {}", playername), name); } } else if let Some(playername) = strip_prefix(&argument, "allow ") { - let destination = dest.format(hashmap!("{player}" => player.id.name.as_str())); - whitelist.allowed.entry(destination.name).or_insert_with(HashSet::new).insert(PlayerId{name: playername.to_string()}); + let destination = dest.format(hashmap!("{player}" => player.id.0.as_str())); + whitelist.allowed.entry(destination.0).or_insert_with(HashSet::new).insert(PlayerId( playername.to_string())); say(ear, format!("allowed {} to enter your home", playername), name); } else if let Some(playername) = strip_prefix(&argument, "disallow ") { - let destination = dest.format(hashmap!("{player}" => player.id.name.as_str())); - whitelist.allowed.entry(destination.name).or_insert_with(HashSet::new).remove(&PlayerId{name: playername.to_string()}); + let destination = dest.format(hashmap!("{player}" => player.id.0.as_str())); + whitelist.allowed.entry(destination.0).or_insert_with(HashSet::new).remove(&PlayerId( playername.to_string())); say(ear, format!("disallowed {} to enter your home", playername), name); } else if argument.starts_with("whitelist") { - let destination = dest.format(hashmap!("{player}" => player.id.name.as_str())); - let allowed = whitelist.allowed.entry(destination.name).or_insert_with(HashSet::new).iter().map(|id| id.name.as_str()).collect::>(); + let destination = dest.format(hashmap!("{player}" => player.id.0.as_str())); + let allowed = whitelist.allowed.entry(destination.0).or_insert_with(HashSet::new).iter().map(|id| id.0.as_str()).collect::>(); say(ear, format!("allowed players: {}", allowed.join(", ")), name); } } diff --git a/src/systems/migrate.rs b/src/systems/migrate.rs index f9019d8..2007734 100644 --- a/src/systems/migrate.rs +++ b/src/systems/migrate.rs @@ -28,7 +28,7 @@ impl <'a> System<'a> for Migrate { for (player, position, _moved) in (&players, &positions, &moved).join() { for ent in ground.cells.get(&position.pos).unwrap() { if let Some(exit) = exits.get(*ent) { - let destination = exit.destination.format(hashmap!("{player}" => player.id.name.as_str())); + let destination = exit.destination.format(hashmap!("{player}" => player.id.0.as_str())); emigration.emigrants.push((player.id.clone(), destination, exit.dest_pos.clone())); break; } diff --git a/src/world.rs b/src/world.rs index 6e65f84..b9af6df 100644 --- a/src/world.rs +++ b/src/world.rs @@ -75,7 +75,7 @@ impl <'a, 'b>World<'a, 'b> { fn get_room_mut_(&mut self, id: &RoomId) -> Result<&mut Room<'a, 'b>> { if !self.rooms.contains_key(id){ - println!("loading room '{}'", id.name); + println!("loading room '{}'", id); let mut room: Room = if id == &purgatory::purgatory_id() { purgatory::create_purgatory(&self.encyclopedia) } else { @@ -221,7 +221,7 @@ impl <'a, 'b>World<'a, 'b> { } } for roomid in to_remove { - println!("unloading room '{}'", roomid.name); + println!("unloading room '{}'", roomid); self.rooms.remove(&roomid); } } diff --git a/src/worldloader.rs b/src/worldloader.rs index 8934fc8..414d443 100644 --- a/src/worldloader.rs +++ b/src/worldloader.rs @@ -3,6 +3,7 @@ use std::path::{PathBuf}; use std::fs; use serde_json; use serde_json::Value; +use serde::Deserialize; use crate::{ RoomId, roomtemplate::RoomTemplate, @@ -27,13 +28,9 @@ impl WorldLoader { let path = self.directory.join("world.json"); let text = fs::read_to_string(path)?; let json: Value = serde_json::from_str(&text)?; - let default_room = RoomId::from_str( - json - .get("default_room") - .ok_or(aerr!("world meta does not have default_room"))? - .as_str() - .ok_or(aerr!("world meta default_room is not a string"))? - ); + let default_room = RoomId::deserialize( + json.get("default_room").ok_or(aerr!("world meta does not have default_room"))? + ).map_err(|e| aerr!("invalid roomid for default room: {}", e))?; let encyclopediae = json .get("encyclopediae") @@ -54,7 +51,7 @@ impl WorldLoader { } pub fn load_room(&self, id: RoomId) -> Result { - let fname = id.name.splitn(2, '+').next().unwrap().to_string() + ".json"; + let fname = id.to_string().splitn(2, '+').next().unwrap().to_string() + ".json"; let path = self.directory.join("maps").join(fname); let text = fs::read_to_string(path)?; let template = serde_json::from_str(&text)?; -- cgit