From a4efade392aa7127c373b0247d39274cb0decd10 Mon Sep 17 00:00:00 2001 From: tom barrett Date: Tue, 19 Feb 2019 13:24:25 -0600 Subject: unified all server->client connection and brought logic to modules --- src/bin/client.rs | 2 +- src/bin/server.rs | 21 ++++++-- src/client/construction.rs | 5 +- src/client/engines.rs | 5 +- src/client/mining.rs | 5 +- src/client/navigation.rs | 80 +++++++++++++---------------- src/client/refinery.rs | 5 +- src/client/tractorbeam.rs | 5 +- src/constants.rs | 1 + src/item.rs | 10 ++-- src/lib.rs | 2 +- src/mass.rs | 105 +++++++++++++++++++++++++++++++++++--- src/modules/construction.rs | 94 +++++++++++++++++++++++++--------- src/modules/engines.rs | 17 ++++++- src/modules/mining.rs | 120 +++++++++++++++++++++++++++++++++++--------- src/modules/navigation.rs | 56 +++++++++++++++------ src/modules/refinery.rs | 79 ++++++++++++++++++++--------- src/modules/tractorbeam.rs | 101 +++++++++++++++++++++---------------- src/server/connection.rs | 74 --------------------------- src/server/construction.rs | 69 ------------------------- src/server/dashboard.rs | 17 ------- src/server/engines.rs | 47 ----------------- src/server/mining.rs | 94 ---------------------------------- src/server/mod.rs | 8 --- src/server/navigation.rs | 38 -------------- src/server/refinery.rs | 51 ------------------- src/server/tractorbeam.rs | 52 ------------------- src/server_connection.rs | 62 +++++++++++++++++++++++ src/storage.rs | 14 ++++-- 29 files changed, 575 insertions(+), 664 deletions(-) delete mode 100644 src/server/connection.rs delete mode 100644 src/server/construction.rs delete mode 100644 src/server/dashboard.rs delete mode 100644 src/server/engines.rs delete mode 100644 src/server/mining.rs delete mode 100644 src/server/mod.rs delete mode 100644 src/server/navigation.rs delete mode 100644 src/server/refinery.rs delete mode 100644 src/server/tractorbeam.rs create mode 100644 src/server_connection.rs diff --git a/src/bin/client.rs b/src/bin/client.rs index 517076f..cbc7302 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -108,8 +108,8 @@ fn main() { ModuleType::Mining => client_mining(stream, buff_r), ModuleType::Engines => client_engines(stream, buff_r), ModuleType::Refinery => client_refinery(stream, buff_r), + ModuleType::Navigation => client_navigation(stream, buff_r), ModuleType::Tractorbeam => client_tractorbeam(stream, buff_r), ModuleType::Construction => client_construction(stream, buff_r), - ModuleType::Navigation => client_navigation(name, stream, buff_r), } } diff --git a/src/bin/server.rs b/src/bin/server.rs index 0429224..62da029 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -1,6 +1,7 @@ extern crate space; use std::collections::HashMap; +use std::io::Write; use std::net::TcpListener; use std::thread::sleep; use std::time::Duration; @@ -8,7 +9,7 @@ use std::time::Duration; use space::constants; use space::mass::Mass; use space::math::rand_name; -use space::server::connection::ServerConnection; +use space::server_connection::ServerConnection; fn populate() -> HashMap { let mut masses: HashMap = HashMap::new(); @@ -42,11 +43,23 @@ fn main() { } _ => { for connection in &mut connections { - connection.process(&mut masses); + if connection.open { + let mut ship = masses.remove(&connection.name).unwrap(); + + let send = ship.get_client_data(connection.module_type.clone(), &masses); + connection.open = connection.stream.write(send.as_bytes()).is_ok(); + + let recv = connection.receive(); + ship.give_received_data(connection.module_type.clone(), recv, &masses); + + masses.insert(connection.name.clone(), ship); + } } - for mass in masses.values_mut() { - mass.process(); + for key in masses.clone().keys() { + let mut mass = masses.remove(key).unwrap(); + mass.process(&mut masses); + masses.insert(key.to_string(), mass); } sleep(Duration::from_millis(constants::SLEEP_DURATION)); diff --git a/src/client/construction.rs b/src/client/construction.rs index 8cb812f..8549c09 100644 --- a/src/client/construction.rs +++ b/src/client/construction.rs @@ -8,8 +8,7 @@ use std::io::{BufRead, BufReader}; use std::net::TcpStream; use crate::constants; -use crate::modules::construction::ConstructionStatus; -use crate::server::construction::ConstructionData; +use crate::modules::construction::{ConstructionClientData, ConstructionStatus}; pub fn client_construction(mut stream: TcpStream, mut buff_r: BufReader) { let stdout = stdout(); @@ -19,7 +18,7 @@ pub fn client_construction(mut stream: TcpStream, mut buff_r: BufReader) { let stdout = stdout(); @@ -19,7 +19,8 @@ pub fn client_engines(mut stream: TcpStream, mut buff_r: BufReader) { loop { let mut recv = String::new(); buff_r.read_line(&mut recv).unwrap(); - let engines_data: EnginesData = serde_json::from_str(&recv.replace("\n", "")).unwrap(); + let engines_data: EnginesClientData = + serde_json::from_str(&recv.replace("\n", "")).unwrap(); writeln!( stdout, diff --git a/src/client/mining.rs b/src/client/mining.rs index 5515f3a..84dfcb6 100644 --- a/src/client/mining.rs +++ b/src/client/mining.rs @@ -7,8 +7,7 @@ use std::io::{stdout, Read, Write}; use std::io::{BufRead, BufReader}; use std::net::TcpStream; -use crate::modules::mining::MiningStatus; -use crate::server::mining::MiningData; +use crate::modules::mining::{MiningClientData, MiningStatus}; pub fn client_mining(mut stream: TcpStream, mut buff_r: BufReader) { let stdout = stdout(); @@ -18,7 +17,7 @@ pub fn client_mining(mut stream: TcpStream, mut buff_r: BufReader) { loop { let mut recv = String::new(); buff_r.read_line(&mut recv).unwrap(); - let data: MiningData = serde_json::from_str(&recv.replace("\n", "")).unwrap(); + let data: MiningClientData = serde_json::from_str(&recv.replace("\n", "")).unwrap(); write!(stdout, "{}", termion::clear::All).unwrap(); diff --git a/src/client/navigation.rs b/src/client/navigation.rs index 43daafb..586ac9e 100644 --- a/src/client/navigation.rs +++ b/src/client/navigation.rs @@ -3,15 +3,13 @@ extern crate termion; use self::termion::async_stdin; use self::termion::raw::IntoRawMode; -use std::collections::BTreeMap; use std::io::{stdout, Read, Write}; use std::io::{BufRead, BufReader}; use std::net::TcpStream; -use crate::mass::{Mass, MassType}; -use crate::modules::navigation::Navigation; +use crate::modules::navigation::NavigationClientData; -pub fn client_navigation(name: String, mut stream: TcpStream, mut buff_r: BufReader) { +pub fn client_navigation(mut stream: TcpStream, mut buff_r: BufReader) { let stdout = stdout(); let mut stdout = stdout.lock().into_raw_mode().unwrap(); let mut stdin = async_stdin().bytes(); @@ -19,7 +17,7 @@ pub fn client_navigation(name: String, mut stream: TcpStream, mut buff_r: BufRea loop { let mut recv = String::new(); buff_r.read_line(&mut recv).unwrap(); - let mut within_range: BTreeMap = serde_json::from_str(&recv).unwrap(); + let navigation_data: NavigationClientData = serde_json::from_str(&recv).unwrap(); write!( stdout, @@ -29,52 +27,44 @@ pub fn client_navigation(name: String, mut stream: TcpStream, mut buff_r: BufRea ) .unwrap(); - let ship = within_range.remove(&name).unwrap(); - - if let MassType::Ship { ref navigation, .. } = ship.mass_type { - for (i, (mass_name, mass)) in within_range.iter().enumerate() { - let target_data = get_target_status(&navigation, &mass_name); - write!( - stdout, - "{}{}) {} {} Distance : {:.2} {}", - termion::cursor::Goto(1, 2 + i as u16), - i, - mass_name, - mass.position, - mass.position.distance_from(ship.position.clone()), - target_data - ) - .unwrap(); - } - - if let Some(c) = stdin.next() { - let c = c.unwrap() as char; - if c == 'q' { - break; - } else { - let i = c.to_digit(10).unwrap() as usize; - if i < within_range.len() { - let mut send = String::new(); - send.push_str(within_range.iter().nth(i).unwrap().0); - send.push_str("\n"); - stream.write_all(send.as_bytes()).unwrap(); + for (i, (name, position)) in navigation_data.available_targets.iter().enumerate() { + let target_status = match &navigation_data.target_name { + Some(target_name) => { + if target_name == name { + serde_json::to_string(&navigation_data.status).unwrap() + } else { + String::new() } } - } + None => String::new(), + }; + write!( + stdout, + "{}{}) {} {} Distance : {:.2} {}", + termion::cursor::Goto(1, 2 + i as u16), + i, + name, + position, + position.distance_from(navigation_data.ship_position.clone()), + target_status + ) + .unwrap(); } - stdout.flush().unwrap(); - } -} -fn get_target_status(navigation: &Navigation, mass_name: &str) -> String { - match navigation.target_name.clone() { - Some(name) => { - if name == mass_name { - serde_json::to_string(&navigation.status).unwrap() + if let Some(c) = stdin.next() { + let c = c.unwrap() as char; + if c == 'q' { + break; } else { - String::new() + let i = c.to_digit(10).unwrap() as usize; + if i < navigation_data.available_targets.len() { + let mut send = String::new(); + send.push_str(&navigation_data.available_targets[i].0); + send.push_str("\n"); + stream.write_all(send.as_bytes()).unwrap(); + } } } - None => String::new(), + stdout.flush().unwrap(); } } diff --git a/src/client/refinery.rs b/src/client/refinery.rs index a3ae6f4..a977e04 100644 --- a/src/client/refinery.rs +++ b/src/client/refinery.rs @@ -7,8 +7,7 @@ use std::io::{stdout, Read, Write}; use std::io::{BufRead, BufReader}; use std::net::TcpStream; -use crate::modules::refinery::RefineryStatus; -use crate::server::refinery::RefineryData; +use crate::modules::refinery::{RefineryClientData, RefineryStatus}; pub fn client_refinery(mut stream: TcpStream, mut buff_r: BufReader) { let stdout = stdout(); @@ -18,7 +17,7 @@ pub fn client_refinery(mut stream: TcpStream, mut buff_r: BufReader) loop { let mut recv = String::new(); buff_r.read_line(&mut recv).unwrap(); - let data: RefineryData = serde_json::from_str(&recv.replace("\n", "")).unwrap(); + let data: RefineryClientData = serde_json::from_str(&recv.replace("\n", "")).unwrap(); write!(stdout, "{}", termion::clear::All).unwrap(); diff --git a/src/client/tractorbeam.rs b/src/client/tractorbeam.rs index e9e60b2..16508b5 100644 --- a/src/client/tractorbeam.rs +++ b/src/client/tractorbeam.rs @@ -7,8 +7,7 @@ use std::io::{stdout, Read, Write}; use std::io::{BufRead, BufReader}; use std::net::TcpStream; -use crate::modules::tractorbeam::TractorbeamStatus; -use crate::server::tractorbeam::TractorbeamData; +use crate::modules::tractorbeam::{TractorbeamClientData, TractorbeamStatus}; pub fn client_tractorbeam(mut stream: TcpStream, mut buff_r: BufReader) { let stdout = stdout(); @@ -18,7 +17,7 @@ pub fn client_tractorbeam(mut stream: TcpStream, mut buff_r: BufReader Item { - let size = match itemtype { + pub fn new(item_type: ItemType) -> Item { + let size = match item_type { ItemType::Iron => constants::IRON_SIZE, ItemType::Hydrogen => constants::HYDROGEN_SIZE, ItemType::CrudeMinerals => constants::CRUDE_MINERALS_SIZE, }; Item { - name: serde_json::to_string(&itemtype).unwrap() + &rand_name(), - itemtype, + name: serde_json::to_string(&item_type).unwrap() + &rand_name(), + item_type, size, } } diff --git a/src/lib.rs b/src/lib.rs index 2b76cc6..e398dba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,5 +7,5 @@ pub mod item; pub mod mass; pub mod math; pub mod modules; -pub mod server; +pub mod server_connection; pub mod storage; diff --git a/src/mass.rs b/src/mass.rs index c556e0c..8d9f9fc 100644 --- a/src/mass.rs +++ b/src/mass.rs @@ -2,6 +2,7 @@ extern crate rand; use self::rand::distributions::Uniform; use self::rand::Rng; +use std::collections::HashMap; use crate::constants; use crate::item::{Item, ItemType}; @@ -84,7 +85,10 @@ impl Mass { ); let mut resources = Vec::new(); - for _ in 0..rng.gen_range(0, constants::ASTROID_STARTING_MINERALS_MAX) { + for _ in 0..rng.gen_range( + constants::ASTROID_STARTING_MINERALS_MIN, + constants::ASTROID_STARTING_MINERALS_MAX, + ) { resources.push(Item::new(ItemType::CrudeMinerals)); } @@ -160,25 +164,112 @@ impl Mass { modules } - pub fn process(&mut self) { + pub fn process(&mut self, masses: &mut HashMap) { if let MassType::Ship { ref mut navigation, ref mut engines, ref mut mining, ref mut refinery, ref mut construction, + ref mut storage, + ref mut tractorbeam, .. } = self.mass_type { - mining.process(); - refinery.process(); - navigation.process(); - construction.process(); + if let Some(target_name) = &navigation.target_name { + let mut target = masses.remove(target_name).unwrap(); + mining.process(self.position.clone(), masses, &mut target, storage); + tractorbeam.process(); + let acceleration = + tractorbeam.get_acceleration(self.position.clone(), target.position.clone()); + target.effects.give_acceleration(acceleration); + masses.insert(target_name.to_string(), target); + } + + refinery.process(storage); + navigation.process(self.position.clone(), masses); + construction.process( + self.velocity.clone(), + self.position.clone(), + masses, + storage, + ); engines.process(self.velocity.clone()); - self.effects.give_acceleration(engines.take_acceleration()) + self.effects.give_acceleration(engines.take_acceleration()); } self.velocity += self.effects.take_acceleration(); self.position += self.velocity.clone(); } + + pub fn get_client_data( + &self, + module_type: ModuleType, + masses: &HashMap, + ) -> String { + if let MassType::Ship { + ref navigation, + ref engines, + ref mining, + ref refinery, + ref construction, + ref storage, + ref tractorbeam, + .. + } = self.mass_type + { + let target = match &navigation.target_name { + Some(target_name) => masses.get(target_name), + None => None, + }; + match module_type { + ModuleType::Navigation => navigation.get_client_data(self.position.clone(), masses), + ModuleType::Engines => engines.get_client_data(navigation.status.clone()), + ModuleType::Mining => mining.get_client_data(self.position.clone(), target), + ModuleType::Dashboard => serde_json::to_string(&self).unwrap() + "\n", + ModuleType::Construction => construction.get_client_data(storage), + ModuleType::Refinery => refinery.get_client_data(storage), + ModuleType::Tractorbeam => tractorbeam.get_client_data(target), + } + } else { + String::new() + } + } + + pub fn give_received_data( + &mut self, + module_type: ModuleType, + recv: String, + masses: &HashMap, + ) { + if let MassType::Ship { + ref mut navigation, + ref mut engines, + ref mut mining, + ref mut refinery, + ref mut construction, + ref mut tractorbeam, + .. + } = self.mass_type + { + let target = match &navigation.target_name { + Some(target_name) => masses.get(target_name), + None => None, + }; + match module_type { + ModuleType::Navigation => navigation.give_received_data(recv), + ModuleType::Engines => engines.give_received_data( + recv, + self.position.clone(), + self.velocity.clone(), + target, + ), + ModuleType::Mining => mining.give_received_data(recv), + ModuleType::Construction => construction.give_received_data(recv), + ModuleType::Refinery => refinery.give_received_data(recv), + ModuleType::Tractorbeam => tractorbeam.give_received_data(recv), + ModuleType::Dashboard => (), + } + } + } } diff --git a/src/modules/construction.rs b/src/modules/construction.rs index 0f7f8f2..ca4dd2d 100644 --- a/src/modules/construction.rs +++ b/src/modules/construction.rs @@ -1,21 +1,12 @@ +use std::collections::HashMap; use std::time::SystemTime; use crate::constants; +use crate::item::ItemType; +use crate::mass::Mass; +use crate::math::Vector; use crate::modules::types::ModuleType; -use crate::server::construction::ConstructionData; - -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum ConstructionStatus { - None, - Constructing, - Constructed, -} - -impl Default for ConstructionStatus { - fn default() -> Self { - ConstructionStatus::None - } -} +use crate::storage::Storage; #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Construction { @@ -35,41 +26,98 @@ impl Construction { } } - pub fn process(&mut self) { + pub fn process( + &mut self, + ship_velocity: Vector, + ship_position: Vector, + masses: &mut HashMap, + storage: &mut Storage, + ) { + if !self.has_enough(storage) { + self.off(); + } if let Some(timer) = self.start { if timer.elapsed().unwrap().as_secs() > self.time { self.start = Some(SystemTime::now()); self.status = ConstructionStatus::Constructed; } } + if self.status == ConstructionStatus::Constructed { + storage + .take_items(ItemType::Iron, constants::SHIP_CONSTRUCTION_IRON_COST) + .unwrap(); + masses.insert( + "Station".to_string(), + Mass::new_station( + ModuleType::Refinery, + ship_position.clone(), + ship_velocity.clone(), + ), + ); + self.constructed(); + } } - pub fn give_recv(&mut self, recv: String, construction_data: &ConstructionData) { + pub fn get_client_data(&self, storage: &Storage) -> String { + let client_data = ConstructionClientData { + has_enough: self.has_enough(storage), + status: self.status.clone(), + }; + serde_json::to_string(&client_data).unwrap() + "\n" + } + + pub fn give_received_data(&mut self, recv: String) { if let "c" = recv.as_str() { - if construction_data.has_enough { - self.toggle() - } + self.toggle() } } - pub fn toggle(&mut self) { + fn has_enough(&self, storage: &Storage) -> bool { + storage + .items + .iter() + .filter(|item| item.item_type == ItemType::Iron) + .count() + >= constants::SHIP_CONSTRUCTION_IRON_COST + } + + fn toggle(&mut self) { match self.status { ConstructionStatus::None => self.on(), _ => self.off(), }; } - pub fn on(&mut self) { + fn on(&mut self) { self.start = Some(SystemTime::now()); self.status = ConstructionStatus::Constructing; } - pub fn off(&mut self) { + fn off(&mut self) { self.start = None; self.status = ConstructionStatus::None; } - pub fn constructed(&mut self) { + fn constructed(&mut self) { self.off() } } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ConstructionClientData { + pub status: ConstructionStatus, + pub has_enough: bool, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum ConstructionStatus { + None, + Constructing, + Constructed, +} + +impl Default for ConstructionStatus { + fn default() -> Self { + ConstructionStatus::None + } +} diff --git a/src/modules/engines.rs b/src/modules/engines.rs index 007787c..63e1fcd 100644 --- a/src/modules/engines.rs +++ b/src/modules/engines.rs @@ -1,6 +1,7 @@ use crate::constants; use crate::mass::Mass; use crate::math::Vector; +use crate::modules::navigation::NavigationStatus; #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Engines { @@ -27,7 +28,7 @@ impl Engines { } } - pub fn give_recv( + pub fn give_received_data( &mut self, recv: String, position: Vector, @@ -61,6 +62,14 @@ impl Engines { self.acceleration = acceleration; } + pub fn get_client_data(&self, status: NavigationStatus) -> String { + let client_data = EnginesClientData { + has_target: status == NavigationStatus::Targeted, + fuel: self.fuel, + }; + serde_json::to_string(&client_data).unwrap() + "\n" + } + pub fn take_acceleration(&mut self) -> Vector { let mut acceleration = self.acceleration.clone(); self.acceleration = Vector::default(); @@ -76,3 +85,9 @@ impl Engines { } } } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct EnginesClientData { + pub has_target: bool, + pub fuel: f64, +} diff --git a/src/modules/mining.rs b/src/modules/mining.rs index a6cea92..8e5b001 100644 --- a/src/modules/mining.rs +++ b/src/modules/mining.rs @@ -1,20 +1,11 @@ use std::time::SystemTime; use crate::constants; -use crate::server::mining::MiningData; - -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum MiningStatus { - None, - Mining, - Mined, -} - -impl Default for MiningStatus { - fn default() -> Self { - MiningStatus::None - } -} +use crate::item::ItemType; +use crate::mass::{Mass, MassType}; +use crate::math::Vector; +use crate::storage::Storage; +use std::collections::HashMap; #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Mining { @@ -34,41 +25,122 @@ impl Mining { } } - pub fn process(&mut self) { + pub fn process( + &mut self, + ship_position: Vector, + masses: &mut HashMap, + target: &mut Mass, + storage: &mut Storage, + ) { + if self.range < ship_position.distance_from(target.position.clone()) { + self.off(); + } if let Some(timer) = self.start { if timer.elapsed().unwrap().as_secs() > self.time { self.status = MiningStatus::Mined; - self.start = Some(SystemTime::now()); + self.start = None; + } + } + if self.status == MiningStatus::Mined { + if let MassType::Astroid { + ref mut resources, .. + } = target.mass_type + { + match resources.take_item(ItemType::CrudeMinerals) { + Some(item) => { + if !storage.give_item(item.clone()) { + let mass = Mass::new_item( + item.clone(), + target.position.clone(), + target.velocity.clone(), + ); + masses.insert(item.name.clone(), mass); + } + } + None => self.off(), + } } + self.mined(); } } - pub fn give_recv(&mut self, recv: String, mining_data: MiningData) { - if !mining_data.is_within_range { - self.off(); - } else if let "F" = recv.as_str() { + pub fn give_received_data(&mut self, recv: String) { + if let "F" = recv.as_str() { self.toggle() } } - pub fn toggle(&mut self) { + pub fn get_client_data(&self, ship_position: Vector, target: Option<&Mass>) -> String { + let mut astroid_has_minerals = false; + let mut is_within_range = false; + let has_astroid_target = match target { + Some(target) => match target.mass_type { + MassType::Astroid { ref resources, .. } => { + astroid_has_minerals = resources + .items + .iter() + .any(|item| item.item_type == ItemType::CrudeMinerals); + is_within_range = + self.range > ship_position.distance_from(target.position.clone()); + true + } + _ => false, + }, + None => false, + }; + + let client_data = MiningClientData { + has_astroid_target, + astroid_has_minerals, + is_within_range, + range: self.range, + status: self.status.clone(), + }; + + serde_json::to_string(&client_data).unwrap() + "\n" + } + + fn toggle(&mut self) { match self.status { MiningStatus::None => self.on(), _ => self.off(), }; } - pub fn on(&mut self) { + fn on(&mut self) { self.start = Some(SystemTime::now()); self.status = MiningStatus::Mining; } - pub fn off(&mut self) { + fn off(&mut self) { self.start = None; self.status = MiningStatus::None; } - pub fn mined(&mut self) { + fn mined(&mut self) { self.status = MiningStatus::Mining; + self.start = Some(SystemTime::now()); + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct MiningClientData { + pub has_astroid_target: bool, + pub astroid_has_minerals: bool, + pub is_within_range: bool, + pub status: MiningStatus, + pub range: f64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum MiningStatus { + None, + Mining, + Mined, +} + +impl Default for MiningStatus { + fn default() -> Self { + MiningStatus::None } } diff --git a/src/modules/navigation.rs b/src/modules/navigation.rs index 5fcf89f..b15beef 100644 --- a/src/modules/navigation.rs +++ b/src/modules/navigation.rs @@ -5,19 +5,6 @@ use crate::constants; use crate::mass::Mass; use crate::math::Vector; -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum NavigationStatus { - None, - Targeting, - Targeted, -} - -impl Default for NavigationStatus { - fn default() -> Self { - NavigationStatus::None - } -} - #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Navigation { pub range: f64, @@ -38,7 +25,8 @@ impl Navigation { } } - pub fn process(&mut self) { + pub fn process(&mut self, ship_position: Vector, masses: &mut HashMap) { + self.verify_target(ship_position, masses); if let Some(timer) = self.start { if timer.elapsed().unwrap().as_secs() > self.time { self.status = NavigationStatus::Targeted; @@ -47,7 +35,7 @@ impl Navigation { } } - pub fn give_recv(&mut self, recv: String) { + pub fn give_received_data(&mut self, recv: String) { if !recv.is_empty() { self.start = Some(SystemTime::now()); self.status = NavigationStatus::Targeting; @@ -55,7 +43,22 @@ impl Navigation { } } - pub fn verify_target(&mut self, ship_position: Vector, masses: &HashMap) { + pub fn get_client_data(&self, ship_position: Vector, masses: &HashMap) -> String { + let client_data = NavigationClientData { + ship_position: ship_position.clone(), + status: self.status.clone(), + target_name: self.target_name.clone(), + available_targets: masses + .iter() + .filter(|(_, mass)| ship_position.distance_from(mass.position.clone()) < self.range) + .map(|(name, mass)| (name.to_string(), mass.position.clone())) + .collect(), + }; + + serde_json::to_string(&client_data).unwrap() + "\n" + } + + fn verify_target(&mut self, ship_position: Vector, masses: &HashMap) { if let Some(name) = self.target_name.clone() { let target = masses.get(&name).unwrap(); if target.position.distance_from(ship_position) > self.range { @@ -65,3 +68,24 @@ impl Navigation { } } } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct NavigationClientData { + pub ship_position: Vector, + pub available_targets: Vec<(String, Vector)>, + pub status: NavigationStatus, + pub target_name: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum NavigationStatus { + None, + Targeting, + Targeted, +} + +impl Default for NavigationStatus { + fn default() -> Self { + NavigationStatus::None + } +} diff --git a/src/modules/refinery.rs b/src/modules/refinery.rs index 4a4ca85..a0a401b 100644 --- a/src/modules/refinery.rs +++ b/src/modules/refinery.rs @@ -1,20 +1,8 @@ use std::time::SystemTime; use crate::constants; -use crate::server::refinery::RefineryData; - -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum RefineryStatus { - None, - Refining, - Refined, -} - -impl Default for RefineryStatus { - fn default() -> Self { - RefineryStatus::None - } -} +use crate::item::{Item, ItemType}; +use crate::storage::Storage; #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Refinery { @@ -32,41 +20,84 @@ impl Refinery { } } - pub fn process(&mut self) { + pub fn process(&mut self, storage: &mut Storage) { + if !self.has_crude_minerals(storage) { + self.off(); + } if let Some(timer) = self.start { if timer.elapsed().unwrap().as_secs() > self.time { self.status = RefineryStatus::Refined; - self.start = Some(SystemTime::now()); + self.start = None } } + if self.status == RefineryStatus::Refined { + storage.take_item(ItemType::CrudeMinerals); + storage.give_item(Item::new(ItemType::Iron)); + storage.give_item(Item::new(ItemType::Hydrogen)); + self.taken(); + } } - pub fn give_recv(&mut self, recv: String, refinery_data: RefineryData) { - if !refinery_data.has_crude_minerals { - self.off(); - } else if let "R" = recv.as_str() { + pub fn get_client_data(&self, storage: &Storage) -> String { + let client_data = RefineryClientData { + has_crude_minerals: self.has_crude_minerals(storage), + status: self.status.clone(), + }; + + serde_json::to_string(&client_data).unwrap() + "\n" + } + + pub fn give_received_data(&mut self, recv: String) { + if let "R" = recv.as_str() { self.toggle(); } } - pub fn toggle(&mut self) { + fn has_crude_minerals(&self, storage: &Storage) -> bool { + storage + .items + .iter() + .any(|item| item.item_type == ItemType::CrudeMinerals) + } + + fn toggle(&mut self) { match self.status { RefineryStatus::None => self.on(), _ => self.off(), }; } - pub fn on(&mut self) { + fn on(&mut self) { self.start = Some(SystemTime::now()); self.status = RefineryStatus::Refining; } - pub fn off(&mut self) { + fn off(&mut self) { self.start = None; self.status = RefineryStatus::None; } - pub fn taken(&mut self) { + fn taken(&mut self) { self.status = RefineryStatus::Refining; + self.start = Some(SystemTime::now()); + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct RefineryClientData { + pub has_crude_minerals: bool, + pub status: RefineryStatus, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum RefineryStatus { + None, + Refining, + Refined, +} + +impl Default for RefineryStatus { + fn default() -> Self { + RefineryStatus::None } } diff --git a/src/modules/tractorbeam.rs b/src/modules/tractorbeam.rs index c77ea1f..3bbb32a 100644 --- a/src/modules/tractorbeam.rs +++ b/src/modules/tractorbeam.rs @@ -9,20 +9,6 @@ pub struct Tractorbeam { desired_distance: Option, } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub enum TractorbeamStatus { - None, - Push, - Pull, - Bring, -} - -impl Default for TractorbeamStatus { - fn default() -> Self { - TractorbeamStatus::None - } -} - impl Tractorbeam { pub fn new() -> Tractorbeam { Tractorbeam { @@ -32,7 +18,18 @@ impl Tractorbeam { } } - pub fn give_recv(&mut self, recv: String) { + pub fn process(&mut self) {} + + pub fn get_client_data(&self, target: Option<&Mass>) -> String { + let client_data = TractorbeamClientData { + has_target: target.is_some(), + status: self.status.clone(), + }; + + serde_json::to_string(&client_data).unwrap() + "\n" + } + + pub fn give_received_data(&mut self, recv: String) { match recv.as_str() { "o" => self.toggle_pull(), "p" => self.toggle_push(), @@ -41,7 +38,32 @@ impl Tractorbeam { } } - pub fn toggle_pull(&mut self) { + pub fn get_acceleration(&self, ship_position: Vector, target_position: Vector) -> Vector { + let acceleration = ship_position.clone() - target_position.clone(); + match self.status { + TractorbeamStatus::Push => acceleration.unitize() * -0.05, + TractorbeamStatus::Pull => acceleration.unitize() * 0.05, + TractorbeamStatus::Bring => match self.desired_distance { + Some(desired_distance) => { + if desired_distance > ship_position.distance_from(target_position) { + acceleration.unitize() * -0.05 + //some sort of velocity limiter + //if target.speed_torwards(ship) < 10.0 { + // acceleration.unitize() * -0.05 + //} else { + // Vector::default() + //} + } else { + acceleration.unitize() * 0.05 + } + } + None => Vector::default(), + }, + TractorbeamStatus::None => Vector::default(), + } + } + + fn toggle_pull(&mut self) { self.status = match self.status { TractorbeamStatus::None => TractorbeamStatus::Pull, TractorbeamStatus::Push => TractorbeamStatus::Pull, @@ -50,7 +72,7 @@ impl Tractorbeam { } } - pub fn toggle_push(&mut self) { + fn toggle_push(&mut self) { self.status = match self.status { TractorbeamStatus::None => TractorbeamStatus::Push, TractorbeamStatus::Pull => TractorbeamStatus::Push, @@ -59,7 +81,7 @@ impl Tractorbeam { } } - pub fn toggle_bring(&mut self, desired_distance: f64) { + fn toggle_bring(&mut self, desired_distance: f64) { self.desired_distance = Some(desired_distance); self.status = match self.status { TractorbeamStatus::None => TractorbeamStatus::Bring, @@ -68,33 +90,24 @@ impl Tractorbeam { TractorbeamStatus::Bring => TractorbeamStatus::None, } } +} - pub fn off(&mut self) { - self.status = TractorbeamStatus::None; - } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct TractorbeamClientData { + pub has_target: bool, + pub status: TractorbeamStatus, +} - pub fn get_acceleration(&self, position: Vector, target: Mass) -> Vector { - let acceleration = position.clone() - target.position.clone(); - match self.status { - TractorbeamStatus::Push => acceleration.unitize() * -0.05, - TractorbeamStatus::Pull => acceleration.unitize() * 0.05, - TractorbeamStatus::Bring => match self.desired_distance { - Some(desired_distance) => { - if desired_distance > position.distance_from(target.position) { - acceleration.unitize() * -0.05 - //some sort of velocity limiter - //if target.speed_torwards(ship) < 10.0 { - // acceleration.unitize() * -0.05 - //} else { - // Vector::default() - //} - } else { - acceleration.unitize() * 0.05 - } - } - None => Vector::default(), - }, - TractorbeamStatus::None => Vector::default(), - } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum TractorbeamStatus { + None, + Push, + Pull, + Bring, +} + +impl Default for TractorbeamStatus { + fn default() -> Self { + TractorbeamStatus::None } } diff --git a/src/server/connection.rs b/src/server/connection.rs deleted file mode 100644 index 92a7531..0000000 --- a/src/server/connection.rs +++ /dev/null @@ -1,74 +0,0 @@ -extern crate serde_json; - -use std::collections::HashMap; -use std::io::prelude::*; -use std::io::BufReader; -use std::net::TcpStream; - -use crate::mass::Mass; -use crate::modules::types::ModuleType; - -pub struct ServerConnection { - pub name: String, - pub module_type: ModuleType, - pub stream: TcpStream, - pub buff_r: BufReader, - pub open: bool, -} - -impl ServerConnection { - pub fn new(mut stream: TcpStream, masses: &mut HashMap) -> ServerConnection { - let mut buff_r = BufReader::new(stream.try_clone().unwrap()); - - let mut recv = String::new(); - buff_r.read_line(&mut recv).unwrap(); - let name = &recv[..recv.find(':').unwrap()]; - - let ship = masses - .entry(name.to_string()) - .or_insert_with(Mass::new_ship); - - let send = serde_json::to_string(&ship.get_modules()).unwrap() + "\n"; - stream.write_all(send.as_bytes()).unwrap(); - - let mut recv = String::new(); - buff_r.read_line(&mut recv).unwrap(); - let module_type: ModuleType = serde_json::from_str(&recv.replace("\n", "")).unwrap(); - - stream.set_nonblocking(true).unwrap(); - ServerConnection { - name: String::from(name), - module_type, - stream, - buff_r, - open: true, - } - } - - pub fn process(&mut self, mut masses: &mut HashMap) { - match self.module_type { - ModuleType::Mining => self.server_mining(&mut masses), - ModuleType::Engines => self.server_engines(&mut masses), - ModuleType::Refinery => self.server_refinery(&mut masses), - ModuleType::Dashboard => self.server_dashboard(&mut masses), - ModuleType::Navigation => self.server_navigation(&mut masses), - ModuleType::Tractorbeam => self.server_tractorbeam(&mut masses), - ModuleType::Construction => self.server_construction(&mut masses), - } - } - - pub fn receive(&mut self) -> String { - let mut recv = String::new(); - match self.buff_r.read_line(&mut recv) { - Ok(result) => { - if result == 0 { - self.open = false; - String::new() - } else { - recv.replace("\n", "") - } - } - Err(_) => String::new(), - } - } -} diff --git a/src/server/construction.rs b/src/server/construction.rs deleted file mode 100644 index 0e24952..0000000 --- a/src/server/construction.rs +++ /dev/null @@ -1,69 +0,0 @@ -extern crate serde_json; - -use std::collections::HashMap; -use std::io::Write; - -use crate::constants; -use crate::item::ItemType; -use crate::mass::{Mass, MassType}; -use crate::modules::construction::Construction; -use crate::modules::construction::ConstructionStatus; -use crate::modules::types::ModuleType; -use crate::server::connection::ServerConnection; -use crate::storage::Storage; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ConstructionData { - pub status: ConstructionStatus, - pub has_enough: bool, -} - -impl ServerConnection { - pub fn server_construction(&mut self, masses: &mut HashMap) { - let mut ship = masses.remove(&self.name).unwrap(); - - if let MassType::Ship { - ref mut construction, - ref mut storage, - .. - } = ship.mass_type - { - let construction_data = get_construction_data(storage, construction); - - let send = serde_json::to_string(&construction_data).unwrap() + "\n"; - self.open = self.stream.write(send.as_bytes()).is_ok(); - - let recv = self.receive(); - construction.give_recv(recv, &construction_data); - - if construction_data.status == ConstructionStatus::Constructed { - storage - .take_items(ItemType::Iron, constants::SHIP_CONSTRUCTION_IRON_COST) - .unwrap(); - masses.insert( - "Station".to_string(), - Mass::new_station( - ModuleType::Refinery, - ship.position.clone(), - ship.velocity.clone(), - ), - ); - construction.constructed(); - } - } - - masses.insert(self.name.clone(), ship); - } -} - -fn get_construction_data(storage: &Storage, construction: &Construction) -> ConstructionData { - ConstructionData { - status: construction.status.clone(), - has_enough: storage - .items - .iter() - .filter(|item| item.itemtype == ItemType::Iron) - .count() - >= constants::SHIP_CONSTRUCTION_IRON_COST, - } -} diff --git a/src/server/dashboard.rs b/src/server/dashboard.rs deleted file mode 100644 index cff2398..0000000 --- a/src/server/dashboard.rs +++ /dev/null @@ -1,17 +0,0 @@ -extern crate serde_json; - -use std::collections::HashMap; -use std::io::Write; - -use crate::mass::Mass; -use crate::server::connection::ServerConnection; - -impl ServerConnection { - pub fn server_dashboard(&mut self, masses: &mut HashMap) { - if self.open { - let ship = masses.get(&self.name).unwrap(); - let send = serde_json::to_string(&ship).unwrap() + "\n"; - self.open = self.stream.write(send.as_bytes()).is_ok(); - } - } -} diff --git a/src/server/engines.rs b/src/server/engines.rs deleted file mode 100644 index 067acb5..0000000 --- a/src/server/engines.rs +++ /dev/null @@ -1,47 +0,0 @@ -extern crate serde_json; - -use std::collections::HashMap; -use std::io::Write; - -use crate::mass::{Mass, MassType}; -use crate::modules::navigation::NavigationStatus; -use crate::server::connection::ServerConnection; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct EnginesData { - pub has_target: bool, - pub fuel: f64, -} - -impl ServerConnection { - pub fn server_engines(&mut self, masses: &mut HashMap) { - if self.open { - let mut ship = masses.remove(&self.name).unwrap(); - - if let MassType::Ship { - ref mut engines, - ref navigation, - .. - } = ship.mass_type - { - let engines_data = EnginesData { - has_target: navigation.status == NavigationStatus::Targeted, - fuel: engines.fuel, - }; - - let target = match &navigation.target_name { - Some(name) => masses.get(name), - None => None, - }; - - let send = serde_json::to_string(&engines_data).unwrap() + "\n"; - self.open = self.stream.write(send.as_bytes()).is_ok(); - - let recv = self.receive(); - engines.give_recv(recv, ship.position.clone(), ship.velocity.clone(), target); - } - - masses.insert(self.name.clone(), ship); - } - } -} diff --git a/src/server/mining.rs b/src/server/mining.rs deleted file mode 100644 index 0bf6956..0000000 --- a/src/server/mining.rs +++ /dev/null @@ -1,94 +0,0 @@ -extern crate serde_json; - -use std::collections::HashMap; -use std::io::Write; - -use crate::item::ItemType; -use crate::mass::{Mass, MassType}; -use crate::math::Vector; -use crate::modules::mining::{Mining, MiningStatus}; -use crate::server::connection::ServerConnection; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct MiningData { - pub has_astroid_target: bool, - pub astroid_has_minerals: bool, - pub is_within_range: bool, - pub status: MiningStatus, - pub range: f64, -} - -impl ServerConnection { - pub fn server_mining(&mut self, masses: &mut HashMap) { - let mut ship = masses.remove(&self.name).unwrap(); - - if let MassType::Ship { - ref mut mining, - ref mut storage, - ref navigation, - .. - } = ship.mass_type - { - if let Some(target_name) = navigation.target_name.clone() { - let mut target = masses.remove(&target_name).unwrap(); - - let mining_data = get_mining_data(ship.position.clone(), mining, target.clone()); - - let send = serde_json::to_string(&mining_data).unwrap() + "\n"; - self.open = self.stream.write(send.as_bytes()).is_ok(); - - let recv = self.receive(); - mining.give_recv(recv, mining_data); - - if mining.status == MiningStatus::Mined { - if let MassType::Astroid { - ref mut resources, .. - } = target.mass_type - { - match resources.take_item(ItemType::CrudeMinerals) { - Some(item) => { - if !storage.give_item(item.clone()) { - let mass = Mass::new_item( - item.clone(), - ship.position.clone(), - ship.velocity.clone(), - ); - masses.insert(item.name.clone(), mass); - } - } - None => mining.off(), - } - } - mining.mined(); - } - masses.insert(target_name, target); - } - } - - masses.insert(self.name.clone(), ship); - } -} - -fn get_mining_data(position: Vector, mining: &Mining, target: Mass) -> MiningData { - let mut astroid_has_minerals = false; - let mut is_within_range = false; - let has_astroid_target = match target.mass_type { - MassType::Astroid { ref resources, .. } => { - astroid_has_minerals = resources - .items - .iter() - .any(|item| item.itemtype == ItemType::CrudeMinerals); - is_within_range = mining.range > position.distance_from(target.position.clone()); - true - } - _ => false, - }; - - MiningData { - has_astroid_target, - astroid_has_minerals, - is_within_range, - range: mining.range, - status: mining.status.clone(), - } -} diff --git a/src/server/mod.rs b/src/server/mod.rs deleted file mode 100644 index c195f3d..0000000 --- a/src/server/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub mod connection; -pub mod construction; -pub mod dashboard; -pub mod engines; -pub mod mining; -pub mod navigation; -pub mod refinery; -pub mod tractorbeam; diff --git a/src/server/navigation.rs b/src/server/navigation.rs deleted file mode 100644 index 67d6758..0000000 --- a/src/server/navigation.rs +++ /dev/null @@ -1,38 +0,0 @@ -extern crate serde_json; - -use std::collections::HashMap; -use std::io::Write; - -use crate::mass::{Mass, MassType}; -use crate::server::connection::ServerConnection; - -impl ServerConnection { - pub fn server_navigation(&mut self, masses: &mut HashMap) { - let mut ship = masses.remove(&self.name).unwrap(); - let ship_clone = ship.clone(); - - if let MassType::Ship { - ref mut navigation, .. - } = ship.mass_type - { - navigation.verify_target(ship.position.clone(), &masses); - let mut within_range: HashMap<&String, &Mass> = masses - .iter() - .filter(|&(_, mass)| { - ship_clone.position.distance_from(mass.position.clone()) < navigation.range - }) - .collect(); - within_range.insert(&self.name, &ship_clone); - - if self.open { - let send = serde_json::to_string(&within_range).unwrap() + "\n"; - self.open = self.stream.write(send.as_bytes()).is_ok(); - - let recv = self.receive(); - navigation.give_recv(recv); - } - } - - masses.insert(self.name.clone(), ship); - } -} diff --git a/src/server/refinery.rs b/src/server/refinery.rs deleted file mode 100644 index 1b6c944..0000000 --- a/src/server/refinery.rs +++ /dev/null @@ -1,51 +0,0 @@ -extern crate serde_json; - -use std::collections::HashMap; -use std::io::Write; - -use crate::item::{Item, ItemType}; -use crate::mass::{Mass, MassType}; -use crate::modules::refinery::RefineryStatus; -use crate::server::connection::ServerConnection; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RefineryData { - pub has_crude_minerals: bool, - pub status: RefineryStatus, -} - -impl ServerConnection { - pub fn server_refinery(&mut self, masses: &mut HashMap) { - let mut ship = masses.remove(&self.name).unwrap(); - - if let MassType::Ship { - ref mut refinery, - ref mut storage, - .. - } = ship.mass_type - { - let refinery_data = RefineryData { - has_crude_minerals: storage - .items - .iter() - .any(|item| item.itemtype == ItemType::CrudeMinerals), - status: refinery.status.clone(), - }; - - let send = serde_json::to_string(&refinery_data).unwrap() + "\n"; - self.open = self.stream.write(send.as_bytes()).is_ok(); - - let recv = self.receive(); - refinery.give_recv(recv, refinery_data); - - if refinery.status == RefineryStatus::Refined { - storage.take_item(ItemType::CrudeMinerals); - storage.give_item(Item::new(ItemType::Iron)); - storage.give_item(Item::new(ItemType::Hydrogen)); - refinery.taken(); - } - } - - masses.insert(self.name.clone(), ship); - } -} diff --git a/src/server/tractorbeam.rs b/src/server/tractorbeam.rs deleted file mode 100644 index 9591c0b..0000000 --- a/src/server/tractorbeam.rs +++ /dev/null @@ -1,52 +0,0 @@ -extern crate serde_json; - -use std::collections::HashMap; -use std::io::Write; - -use crate::mass::{Mass, MassType}; -use crate::modules::navigation::NavigationStatus; -use crate::modules::tractorbeam::TractorbeamStatus; -use crate::server::connection::ServerConnection; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TractorbeamData { - pub has_target: bool, - pub status: TractorbeamStatus, -} - -impl ServerConnection { - pub fn server_tractorbeam(&mut self, masses: &mut HashMap) { - let mut ship = masses.remove(&self.name).unwrap(); - - if let MassType::Ship { - ref mut tractorbeam, - ref navigation, - .. - } = ship.mass_type - { - if self.open { - let tractorbeam_data = TractorbeamData { - has_target: navigation.status == NavigationStatus::Targeted, - status: tractorbeam.status.clone(), - }; - - let send = serde_json::to_string(&tractorbeam_data).unwrap() + "\n"; - self.open = self.stream.write(send.as_bytes()).is_ok(); - - let recv = self.receive(); - tractorbeam.give_recv(recv); - } - - if let Some(name) = navigation.target_name.clone() { - let target = masses.get_mut(&name).unwrap(); - let acceleration = - tractorbeam.get_acceleration(ship.position.clone(), target.clone()); - target.effects.give_acceleration(acceleration); - } else { - tractorbeam.off(); - } - } - - masses.insert(self.name.clone(), ship); - } -} diff --git a/src/server_connection.rs b/src/server_connection.rs new file mode 100644 index 0000000..407b842 --- /dev/null +++ b/src/server_connection.rs @@ -0,0 +1,62 @@ +extern crate serde_json; + +use std::collections::HashMap; +use std::io::prelude::*; +use std::io::BufReader; +use std::net::TcpStream; + +use crate::mass::Mass; +use crate::modules::types::ModuleType; + +pub struct ServerConnection { + pub name: String, + pub module_type: ModuleType, + pub stream: TcpStream, + pub buff_r: BufReader, + pub open: bool, +} + +impl ServerConnection { + pub fn new(mut stream: TcpStream, masses: &mut HashMap) -> ServerConnection { + let mut buff_r = BufReader::new(stream.try_clone().unwrap()); + + let mut recv = String::new(); + buff_r.read_line(&mut recv).unwrap(); + let name = &recv[..recv.find(':').unwrap()]; + + let ship = masses + .entry(name.to_string()) + .or_insert_with(Mass::new_ship); + + let send = serde_json::to_string(&ship.get_modules()).unwrap() + "\n"; + stream.write_all(send.as_bytes()).unwrap(); + + let mut recv = String::new(); + buff_r.read_line(&mut recv).unwrap(); + let module_type: ModuleType = serde_json::from_str(&recv.replace("\n", "")).unwrap(); + + stream.set_nonblocking(true).unwrap(); + ServerConnection { + name: String::from(name), + module_type, + stream, + buff_r, + open: true, + } + } + + pub fn receive(&mut self) -> String { + let mut recv = String::new(); + match self.buff_r.read_line(&mut recv) { + Ok(result) => { + if result == 0 { + self.open = false; + String::new() + } else { + recv.replace("\n", "") + } + } + Err(_) => String::new(), + } + } +} diff --git a/src/storage.rs b/src/storage.rs index b9ca287..5cbd55e 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -20,8 +20,12 @@ impl Storage { } } - pub fn take_item(&mut self, itemtype: ItemType) -> Option { - match self.items.iter().position(|item| item.itemtype == itemtype) { + pub fn take_item(&mut self, item_type: ItemType) -> Option { + match self + .items + .iter() + .position(|item| item.item_type == item_type) + { Some(index) => { let item = self.items.remove(index); self.carrying -= item.size; @@ -31,11 +35,11 @@ impl Storage { } } - pub fn take_items(&mut self, itemtype: ItemType, count: usize) -> Option> { + pub fn take_items(&mut self, item_type: ItemType, count: usize) -> Option> { if self .items .iter() - .filter(|item| item.itemtype == itemtype) + .filter(|item| item.item_type == item_type) .count() >= count { @@ -44,7 +48,7 @@ impl Storage { let index = self .items .iter() - .position(|item| item.itemtype == itemtype) + .position(|item| item.item_type == item_type) .unwrap(); let item = self.items.remove(index); self.carrying -= item.size; -- cgit v1.2.3