From a777b67b2df761c0378b044f17777eaffb4725af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Korg=C3=B3l?= Date: Thu, 15 Aug 2019 16:33:00 +0200 Subject: [PATCH] Add needs_admin bool to check if the commands needs admin perms --- server/src/cmd.rs | 743 +++++++++++++++++++---------------------- server/src/settings.rs | 2 +- 2 files changed, 346 insertions(+), 399 deletions(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 2b75512f6c..3853b0c48e 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -26,6 +26,8 @@ pub struct ChatCommand { arg_fmt: &'static str, /// A message that explains how the command is used. help_string: &'static str, + /// A boolean that is used to check whether the command requires administrator permissions or not. + needs_admin: bool, /// Handler function called when the command is executed. /// # Arguments /// * `&mut Server` - the `Server` instance executing the command. @@ -42,18 +44,32 @@ impl ChatCommand { keyword: &'static str, arg_fmt: &'static str, help_string: &'static str, + needs_admin: bool, handler: fn(&mut Server, EcsEntity, String, &ChatCommand), ) -> Self { Self { keyword, arg_fmt, help_string, + needs_admin, handler, } } /// Calls the contained handler function, passing `&self` as the last argument. pub fn execute(&self, server: &mut Server, entity: EcsEntity, args: String) { - (self.handler)(server, entity, args, self); + if self.needs_admin { + if !server.entity_is_admin(entity) { + server.clients.notify( + entity, + ServerMsg::private(String::from("You have no permission to do that.")), + ); + return; + } else { + (self.handler)(server, entity, args, self); + } + } else { + (self.handler)(server, entity, args, self); + } } } @@ -64,157 +80,157 @@ lazy_static! { "jump", "{d} {d} {d}", "/jump : Offset your current position", + true, handle_jump, ), ChatCommand::new( "goto", "{d} {d} {d}", "/goto : Teleport to a position", + true, handle_goto, ), ChatCommand::new( "alias", "{}", "/alias : Change your alias", + false, handle_alias, ), ChatCommand::new( "tp", "{}", "/tp : Teleport to another player", + true, handle_tp, ), ChatCommand::new( "kill", "{}", "/kill : Kill yourself", + false, handle_kill, ), ChatCommand::new( "time", "{} {s}", "/time or [Time of day] : Set the time of day", + true, handle_time, ), ChatCommand::new( "spawn", "{} {} {d}", "/spawn [amount] : Spawn a test entity", + true, handle_spawn, ), ChatCommand::new( "players", "{}", "/players : Lists players currently online", + false, handle_players, ), ChatCommand::new( - "help", "", "/help: Display this message", handle_help), + "help", "", "/help: Display this message", false, handle_help), ChatCommand::new( "health", "{}", "/health : Set your current health", + true, handle_health, ), ChatCommand::new( "build", "", "/build : Toggles build mode on and off", + true, handle_build, ), ChatCommand::new( "tell", "{}", "/tell : Send a message to another player", + false, handle_tell, ), ChatCommand::new( "killnpcs", "{}", "/killnpcs : Kill the NPCs", + true, handle_killnpcs, ), ChatCommand::new( "object", "{}", "/object [Name]: Spawn an object", + true, handle_object, ), ChatCommand::new( "light", "{} {} {} {} {} {} {}", "/light > < > <>>: Spawn entity with light", + true, handle_light, ), ChatCommand::new( "lantern", "{}", "/lantern : adds/remove light near player", + false, handle_lantern, ), ChatCommand::new( "explosion", "{}", "/explosion : Explodes the ground around you", + false, handle_explosion, ), ]; } fn handle_jump(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) { - match server.state.read_component_cloned::(entity) { - Some(current_pos) => { - server - .state - .write_component(entity, comp::Pos(current_pos.0 + Vec3::new(x, y, z))); - server.state.write_component(entity, comp::ForceUpdate); - } - None => server.clients.notify( - entity, - ServerMsg::private(String::from("You have no position!")), - ), + if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) { + match server.state.read_component_cloned::(entity) { + Some(current_pos) => { + server + .state + .write_component(entity, comp::Pos(current_pos.0 + Vec3::new(x, y, z))); + server.state.write_component(entity, comp::ForceUpdate); } + None => server.clients.notify( + entity, + ServerMsg::private(String::from("You have no position!")), + ), } } } fn handle_goto(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) { - if server - .state - .read_component_cloned::(entity) - .is_some() - { - server - .state - .write_component(entity, comp::Pos(Vec3::new(x, y, z))); - server.state.write_component(entity, comp::ForceUpdate); - } else { - server.clients.notify( - entity, - ServerMsg::private(String::from("You don't have a position!")), - ); - } - } else { + if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) { + if server + .state + .read_component_cloned::(entity) + .is_some() + { server - .clients - .notify(entity, ServerMsg::private(String::from(action.help_string))); + .state + .write_component(entity, comp::Pos(Vec3::new(x, y, z))); + server.state.write_component(entity, comp::ForceUpdate); + } else { + server.clients.notify( + entity, + ServerMsg::private(String::from("You don't have a position!")), + ); } + } else { + server + .clients + .notify(entity, ServerMsg::private(String::from(action.help_string))); } } @@ -228,90 +244,74 @@ fn handle_kill(server: &mut Server, entity: EcsEntity, _args: String, _action: & } fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - let time = scan_fmt_some!(&args, action.arg_fmt, String); - let new_time = match time.as_ref().map(|s| s.as_str()) { - Some("night") => NaiveTime::from_hms(0, 0, 0), - Some("dawn") => NaiveTime::from_hms(5, 0, 0), - Some("day") => NaiveTime::from_hms(12, 0, 0), - Some("dusk") => NaiveTime::from_hms(17, 0, 0), - Some(n) => match n.parse() { - Ok(n) => n, - Err(_) => match NaiveTime::parse_from_str(n, "%H:%M") { - Ok(time) => time, - Err(_) => { - server.clients.notify( - entity, - ServerMsg::private(format!("'{}' is not a valid time.", n)), - ); - return; - } - }, + let time = scan_fmt_some!(&args, action.arg_fmt, String); + let new_time = match time.as_ref().map(|s| s.as_str()) { + Some("night") => NaiveTime::from_hms(0, 0, 0), + Some("dawn") => NaiveTime::from_hms(5, 0, 0), + Some("day") => NaiveTime::from_hms(12, 0, 0), + Some("dusk") => NaiveTime::from_hms(17, 0, 0), + Some(n) => match n.parse() { + Ok(n) => n, + Err(_) => match NaiveTime::parse_from_str(n, "%H:%M") { + Ok(time) => time, + Err(_) => { + server.clients.notify( + entity, + ServerMsg::private(format!("'{}' is not a valid time.", n)), + ); + return; + } }, - None => { - let time_in_seconds = server.state.ecs_mut().read_resource::().0; + }, + None => { + let time_in_seconds = server.state.ecs_mut().read_resource::().0; - let current_time = NaiveTime::from_num_seconds_from_midnight_opt( - // Wraps around back to 0s if it exceeds 24 hours (24 hours = 86400s) - (time_in_seconds as u64 % 86400) as u32, - 0, - ); - let msg = match current_time { - Some(time) => format!("Current time is: {}", time.format("%H:%M").to_string()), - None => String::from("Unknown Time"), - }; - server.clients.notify(entity, ServerMsg::private(msg)); - return; - } - }; + let current_time = NaiveTime::from_num_seconds_from_midnight_opt( + // Wraps around back to 0s if it exceeds 24 hours (24 hours = 86400s) + (time_in_seconds as u64 % 86400) as u32, + 0, + ); + let msg = match current_time { + Some(time) => format!("Current time is: {}", time.format("%H:%M").to_string()), + None => String::from("Unknown Time"), + }; + server.clients.notify(entity, ServerMsg::private(msg)); + return; + } + }; - server.state.ecs_mut().write_resource::().0 = - new_time.num_seconds_from_midnight() as f64; + server.state.ecs_mut().write_resource::().0 = + new_time.num_seconds_from_midnight() as f64; - server.clients.notify( - entity, - ServerMsg::private(format!( - "Time changed to: {}", - new_time.format("%H:%M").to_string() - )), - ); - } + server.clients.notify( + entity, + ServerMsg::private(format!( + "Time changed to: {}", + new_time.format("%H:%M").to_string() + )), + ); } fn handle_health(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - if let Ok(hp) = scan_fmt!(&args, action.arg_fmt, u32) { - if let Some(stats) = server - .state - .ecs_mut() - .write_storage::() - .get_mut(entity) - { - stats.health.set_to(hp, comp::HealthSource::Command); - } else { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no health.")), - ); - } + if let Ok(hp) = scan_fmt!(&args, action.arg_fmt, u32) { + if let Some(stats) = server + .state + .ecs_mut() + .write_storage::() + .get_mut(entity) + { + stats.health.set_to(hp, comp::HealthSource::Command); } else { server.clients.notify( entity, - ServerMsg::private(String::from("You must specify health amount!")), + ServerMsg::private(String::from("You have no health.")), ); } + } else { + server.clients.notify( + entity, + ServerMsg::private(String::from("You must specify health amount!")), + ); } } @@ -331,110 +331,89 @@ fn handle_alias(server: &mut Server, entity: EcsEntity, args: String, action: &C } fn handle_tp(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) { - let ecs = server.state.ecs(); - let opt_player = (&ecs.entities(), &ecs.read_storage::()) - .join() - .find(|(_, player)| player.alias == alias) - .map(|(entity, _)| entity); - match server.state.read_component_cloned::(entity) { - Some(_pos) => match opt_player { - Some(player) => match server.state.read_component_cloned::(player) { - Some(pos) => { - server.state.write_component(entity, pos); - server.state.write_component(entity, comp::ForceUpdate); - } - None => server.clients.notify( - entity, - ServerMsg::private(format!( - "Unable to teleport to player '{}'!", - alias - )), - ), - }, - None => { - server.clients.notify( - entity, - ServerMsg::private(format!("Player '{}' not found!", alias)), - ); - server - .clients - .notify(entity, ServerMsg::private(String::from(action.help_string))); + if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) { + let ecs = server.state.ecs(); + let opt_player = (&ecs.entities(), &ecs.read_storage::()) + .join() + .find(|(_, player)| player.alias == alias) + .map(|(entity, _)| entity); + match server.state.read_component_cloned::(entity) { + Some(_pos) => match opt_player { + Some(player) => match server.state.read_component_cloned::(player) { + Some(pos) => { + server.state.write_component(entity, pos); + server.state.write_component(entity, comp::ForceUpdate); } + None => server.clients.notify( + entity, + ServerMsg::private(format!("Unable to teleport to player '{}'!", alias)), + ), }, None => { + server.clients.notify( + entity, + ServerMsg::private(format!("Player '{}' not found!", alias)), + ); server .clients - .notify(entity, ServerMsg::private(format!("You have no position!"))); + .notify(entity, ServerMsg::private(String::from(action.help_string))); } + }, + None => { + server + .clients + .notify(entity, ServerMsg::private(format!("You have no position!"))); } - } else { - server - .clients - .notify(entity, ServerMsg::private(String::from(action.help_string))); } + } else { + server + .clients + .notify(entity, ServerMsg::private(String::from(action.help_string))); } } fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - match scan_fmt_some!(&args, action.arg_fmt, String, NpcKind, String) { - (Some(opt_align), Some(id), opt_amount) => { - if let Some(agent) = alignment_to_agent(&opt_align, entity) { - let amount = opt_amount - .and_then(|a| a.parse().ok()) - .filter(|x| *x > 0) - .unwrap_or(1) - .min(10); + match scan_fmt_some!(&args, action.arg_fmt, String, NpcKind, String) { + (Some(opt_align), Some(id), opt_amount) => { + if let Some(agent) = alignment_to_agent(&opt_align, entity) { + let amount = opt_amount + .and_then(|a| a.parse().ok()) + .filter(|x| *x > 0) + .unwrap_or(1) + .min(10); - match server.state.read_component_cloned::(entity) { - Some(pos) => { - for _ in 0..amount { - let vel = Vec3::new( - rand::thread_rng().gen_range(-2.0, 3.0), - rand::thread_rng().gen_range(-2.0, 3.0), - 10.0, - ); - - let body = kind_to_body(id); - server - .create_npc(pos, get_npc_name(id), body) - .with(comp::Vel(vel)) - .with(agent) - .build(); - } - server.clients.notify( - entity, - ServerMsg::private( - format!("Spawned {} entities", amount).to_owned(), - ), + match server.state.read_component_cloned::(entity) { + Some(pos) => { + for _ in 0..amount { + let vel = Vec3::new( + rand::thread_rng().gen_range(-2.0, 3.0), + rand::thread_rng().gen_range(-2.0, 3.0), + 10.0, ); + + let body = kind_to_body(id); + server + .create_npc(pos, get_npc_name(id), body) + .with(comp::Vel(vel)) + .with(agent) + .build(); } - None => server.clients.notify( + server.clients.notify( entity, - ServerMsg::private("You have no position!".to_owned()), - ), + ServerMsg::private(format!("Spawned {} entities", amount).to_owned()), + ); } + None => server.clients.notify( + entity, + ServerMsg::private("You have no position!".to_owned()), + ), } } - _ => { - server - .clients - .notify(entity, ServerMsg::private(String::from(action.help_string))); - } + } + _ => { + server + .clients + .notify(entity, ServerMsg::private(String::from(action.help_string))); } } } @@ -464,39 +443,31 @@ fn handle_players(server: &mut Server, entity: EcsEntity, _args: String, _action } fn handle_build(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) { - if !server.entity_is_admin(entity) { + if server + .state + .read_storage::() + .get(entity) + .is_some() + { + server + .state + .ecs() + .write_storage::() + .remove(entity); server.clients.notify( entity, - ServerMsg::private(String::from("You have no permission to do that")), + ServerMsg::private(String::from("Toggled off build mode!")), ); - return; } else { - if server + let _ = server .state - .read_storage::() - .get(entity) - .is_some() - { - server - .state - .ecs() - .write_storage::() - .remove(entity); - server.clients.notify( - entity, - ServerMsg::private(String::from("Toggled off build mode!")), - ); - } else { - let _ = server - .state - .ecs() - .write_storage::() - .insert(entity, comp::CanBuild); - server.clients.notify( - entity, - ServerMsg::private(String::from("Toggled on build mode!")), - ); - } + .ecs() + .write_storage::() + .insert(entity, comp::CanBuild); + server.clients.notify( + entity, + ServerMsg::private(String::from("Toggled on build mode!")), + ); } } @@ -530,184 +501,160 @@ fn kind_to_body(kind: NpcKind) -> comp::Body { } fn handle_killnpcs(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - let ecs = server.state.ecs(); - let mut stats = ecs.write_storage::(); - let players = ecs.read_storage::(); - let mut count = 0; - for (stats, ()) in (&mut stats, !&players).join() { - count += 1; - stats.health.set_to(0, comp::HealthSource::Command); - } - let text = if count > 0 { - format!("Destroyed {} NPCs.", count) - } else { - "No NPCs on server.".to_string() - }; - server.clients.notify(entity, ServerMsg::private(text)); + let ecs = server.state.ecs(); + let mut stats = ecs.write_storage::(); + let players = ecs.read_storage::(); + let mut count = 0; + for (stats, ()) in (&mut stats, !&players).join() { + count += 1; + stats.health.set_to(0, comp::HealthSource::Command); } + let text = if count > 0 { + format!("Destroyed {} NPCs.", count) + } else { + "No NPCs on server.".to_string() + }; + server.clients.notify(entity, ServerMsg::private(text)); } fn handle_object(server: &mut Server, entity: EcsEntity, args: String, _action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - let obj_type = scan_fmt!(&args, _action.arg_fmt, String); + let obj_type = scan_fmt!(&args, _action.arg_fmt, String); - let pos = server - .state - .ecs() - .read_storage::() - .get(entity) - .copied(); - let ori = server - .state - .ecs() - .read_storage::() - .get(entity) - .copied(); - /*let builder = server - .create_object(pos, ori, obj_type) - .with(ori);*/ - if let (Some(pos), Some(ori)) = (pos, ori) { - let obj_type = match obj_type.as_ref().map(String::as_str) { - Ok("scarecrow") => comp::object::Body::Scarecrow, - Ok("cauldron") => comp::object::Body::Cauldron, - Ok("chest_vines") => comp::object::Body::ChestVines, - Ok("chest") => comp::object::Body::Chest, - Ok("chest_dark") => comp::object::Body::ChestDark, - Ok("chest_demon") => comp::object::Body::ChestDemon, - Ok("chest_gold") => comp::object::Body::ChestGold, - Ok("chest_light") => comp::object::Body::ChestLight, - Ok("chest_open") => comp::object::Body::ChestOpen, - Ok("chest_skull") => comp::object::Body::ChestSkull, - Ok("pumpkin") => comp::object::Body::Pumpkin, - Ok("pumpkin_2") => comp::object::Body::Pumpkin2, - Ok("pumpkin_3") => comp::object::Body::Pumpkin3, - Ok("pumpkin_4") => comp::object::Body::Pumpkin4, - Ok("pumpkin_5") => comp::object::Body::Pumpkin5, - Ok("campfire") => comp::object::Body::Campfire, - Ok("lantern_ground") => comp::object::Body::LanternGround, - Ok("lantern_ground_open") => comp::object::Body::LanternGroundOpen, - Ok("lantern_2") => comp::object::Body::LanternStanding2, - Ok("lantern") => comp::object::Body::LanternStanding, - Ok("potion_blue") => comp::object::Body::PotionBlue, - Ok("potion_green") => comp::object::Body::PotionGreen, - Ok("potion_red") => comp::object::Body::PotionRed, - Ok("crate") => comp::object::Body::Crate, - Ok("tent") => comp::object::Body::Tent, - Ok("bomb") => comp::object::Body::Bomb, - Ok("window_spooky") => comp::object::Body::WindowSpooky, - Ok("door_spooky") => comp::object::Body::DoorSpooky, - Ok("carpet") => comp::object::Body::Carpet, - Ok("table_human") => comp::object::Body::Table, - Ok("table_human_2") => comp::object::Body::Table2, - Ok("table_human_3") => comp::object::Body::Table3, - Ok("drawer") => comp::object::Body::Drawer, - Ok("bed_human_blue") => comp::object::Body::BedBlue, - Ok("anvil") => comp::object::Body::Anvil, - Ok("gravestone") => comp::object::Body::Gravestone, - Ok("gravestone_2") => comp::object::Body::Gravestone2, - Ok("chair") => comp::object::Body::Chair, - Ok("chair_2") => comp::object::Body::Chair2, - Ok("chair_3") => comp::object::Body::Chair3, - Ok("bench_human") => comp::object::Body::Bench, - Ok("bedroll") => comp::object::Body::Bedroll, - Ok("carpet_human_round") => comp::object::Body::CarpetHumanRound, - Ok("carpet_human_square") => comp::object::Body::CarpetHumanSquare, - Ok("carpet_human_square_2") => comp::object::Body::CarpetHumanSquare2, - Ok("carpet_human_squircle") => comp::object::Body::CarpetHumanSquircle, - _ => { - return server.clients.notify( - entity, - ServerMsg::private(String::from("Object not found!")), - ); - } - }; - server - .create_object(pos, obj_type) - .with(comp::Ori( - // converts player orientation into a 90° rotation for the object by using the axis with the highest value - ori.0 - .map(|e| { - if e.abs() == ori.0.map(|e| e.abs()).reduce_partial_max() { - e - } else { - 0.0 - } - }) - .normalized(), - )) - .build(); - server - .clients - .notify(entity, ServerMsg::private(format!("Spawned object."))); - } else { - server - .clients - .notify(entity, ServerMsg::private(format!("You have no position!"))); - } + let pos = server + .state + .ecs() + .read_storage::() + .get(entity) + .copied(); + let ori = server + .state + .ecs() + .read_storage::() + .get(entity) + .copied(); + /*let builder = server + .create_object(pos, ori, obj_type) + .with(ori);*/ + if let (Some(pos), Some(ori)) = (pos, ori) { + let obj_type = match obj_type.as_ref().map(String::as_str) { + Ok("scarecrow") => comp::object::Body::Scarecrow, + Ok("cauldron") => comp::object::Body::Cauldron, + Ok("chest_vines") => comp::object::Body::ChestVines, + Ok("chest") => comp::object::Body::Chest, + Ok("chest_dark") => comp::object::Body::ChestDark, + Ok("chest_demon") => comp::object::Body::ChestDemon, + Ok("chest_gold") => comp::object::Body::ChestGold, + Ok("chest_light") => comp::object::Body::ChestLight, + Ok("chest_open") => comp::object::Body::ChestOpen, + Ok("chest_skull") => comp::object::Body::ChestSkull, + Ok("pumpkin") => comp::object::Body::Pumpkin, + Ok("pumpkin_2") => comp::object::Body::Pumpkin2, + Ok("pumpkin_3") => comp::object::Body::Pumpkin3, + Ok("pumpkin_4") => comp::object::Body::Pumpkin4, + Ok("pumpkin_5") => comp::object::Body::Pumpkin5, + Ok("campfire") => comp::object::Body::Campfire, + Ok("lantern_ground") => comp::object::Body::LanternGround, + Ok("lantern_ground_open") => comp::object::Body::LanternGroundOpen, + Ok("lantern_2") => comp::object::Body::LanternStanding2, + Ok("lantern") => comp::object::Body::LanternStanding, + Ok("potion_blue") => comp::object::Body::PotionBlue, + Ok("potion_green") => comp::object::Body::PotionGreen, + Ok("potion_red") => comp::object::Body::PotionRed, + Ok("crate") => comp::object::Body::Crate, + Ok("tent") => comp::object::Body::Tent, + Ok("bomb") => comp::object::Body::Bomb, + Ok("window_spooky") => comp::object::Body::WindowSpooky, + Ok("door_spooky") => comp::object::Body::DoorSpooky, + Ok("carpet") => comp::object::Body::Carpet, + Ok("table_human") => comp::object::Body::Table, + Ok("table_human_2") => comp::object::Body::Table2, + Ok("table_human_3") => comp::object::Body::Table3, + Ok("drawer") => comp::object::Body::Drawer, + Ok("bed_human_blue") => comp::object::Body::BedBlue, + Ok("anvil") => comp::object::Body::Anvil, + Ok("gravestone") => comp::object::Body::Gravestone, + Ok("gravestone_2") => comp::object::Body::Gravestone2, + Ok("chair") => comp::object::Body::Chair, + Ok("chair_2") => comp::object::Body::Chair2, + Ok("chair_3") => comp::object::Body::Chair3, + Ok("bench_human") => comp::object::Body::Bench, + Ok("bedroll") => comp::object::Body::Bedroll, + Ok("carpet_human_round") => comp::object::Body::CarpetHumanRound, + Ok("carpet_human_square") => comp::object::Body::CarpetHumanSquare, + Ok("carpet_human_square_2") => comp::object::Body::CarpetHumanSquare2, + Ok("carpet_human_squircle") => comp::object::Body::CarpetHumanSquircle, + _ => { + return server.clients.notify( + entity, + ServerMsg::private(String::from("Object not found!")), + ); + } + }; + server + .create_object(pos, obj_type) + .with(comp::Ori( + // converts player orientation into a 90° rotation for the object by using the axis with the highest value + ori.0 + .map(|e| { + if e.abs() == ori.0.map(|e| e.abs()).reduce_partial_max() { + e + } else { + 0.0 + } + }) + .normalized(), + )) + .build(); + server + .clients + .notify(entity, ServerMsg::private(format!("Spawned object."))); + } else { + server + .clients + .notify(entity, ServerMsg::private(format!("You have no position!"))); } } fn handle_light(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { - if !server.entity_is_admin(entity) { - server.clients.notify( - entity, - ServerMsg::private(String::from("You have no permission to do that")), - ); - return; - } else { - let (opt_r, opt_g, opt_b, opt_x, opt_y, opt_z, opt_s) = - scan_fmt_some!(&args, action.arg_fmt, f32, f32, f32, f32, f32, f32, f32); + let (opt_r, opt_g, opt_b, opt_x, opt_y, opt_z, opt_s) = + scan_fmt_some!(&args, action.arg_fmt, f32, f32, f32, f32, f32, f32, f32); - let mut light_emitter = comp::LightEmitter::default(); + let mut light_emitter = comp::LightEmitter::default(); - if let (Some(r), Some(g), Some(b)) = (opt_r, opt_g, opt_b) { - let r = r.max(0.0).min(1.0); - let g = g.max(0.0).min(1.0); - let b = b.max(0.0).min(1.0); - light_emitter.col = Rgb::new(r, g, b) - }; - if let (Some(x), Some(y), Some(z)) = (opt_x, opt_y, opt_z) { - light_emitter.offset = Vec3::new(x, y, z) - }; - if let Some(s) = opt_s { - light_emitter.strength = s.max(0.0) - }; - let pos = server + if let (Some(r), Some(g), Some(b)) = (opt_r, opt_g, opt_b) { + let r = r.max(0.0).min(1.0); + let g = g.max(0.0).min(1.0); + let b = b.max(0.0).min(1.0); + light_emitter.col = Rgb::new(r, g, b) + }; + if let (Some(x), Some(y), Some(z)) = (opt_x, opt_y, opt_z) { + light_emitter.offset = Vec3::new(x, y, z) + }; + if let Some(s) = opt_s { + light_emitter.strength = s.max(0.0) + }; + let pos = server + .state + .ecs() + .read_storage::() + .get(entity) + .copied(); + if let Some(pos) = pos { + server .state - .ecs() - .read_storage::() - .get(entity) - .copied(); - if let Some(pos) = pos { - server - .state - .ecs_mut() - .create_entity_synced() - .with(pos) - .with(comp::ForceUpdate) - .with(light_emitter) - .build(); - server - .clients - .notify(entity, ServerMsg::private(format!("Spawned object."))); - } else { - server - .clients - .notify(entity, ServerMsg::private(format!("You have no position!"))); - } + .ecs_mut() + .create_entity_synced() + .with(pos) + .with(comp::ForceUpdate) + .with(light_emitter) + .build(); + server + .clients + .notify(entity, ServerMsg::private(format!("Spawned object."))); + } else { + server + .clients + .notify(entity, ServerMsg::private(format!("You have no position!"))); } } diff --git a/server/src/settings.rs b/server/src/settings.rs index 4a83b6569e..0897c5da0e 100644 --- a/server/src/settings.rs +++ b/server/src/settings.rs @@ -66,7 +66,7 @@ impl ServerSettings { address: SocketAddr::from(([0; 4], 14004)), world_seed: 1337, server_name: "Singleplayer".to_owned(), - server_description: "This is the best Veloren singleplayer server.".to_owned(), + server_description: "The main feature is loneliness!".to_owned(), max_players: 100, start_time: 9.0 * 3600.0, admins: vec!["singleplayer".to_string()], // TODO: Let the player choose if they want to use admin commands or not