mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add build_area_list command
* Reworks CanBuild to use HashSet * Removes player argument from build permission, use sudo instead
This commit is contained in:
parent
21f794f84c
commit
165065725e
@ -41,6 +41,7 @@ pub enum ChatCommand {
|
|||||||
Ban,
|
Ban,
|
||||||
Build,
|
Build,
|
||||||
BuildAreaAdd,
|
BuildAreaAdd,
|
||||||
|
BuildAreaList,
|
||||||
BuildAreaRemove,
|
BuildAreaRemove,
|
||||||
Campfire,
|
Campfire,
|
||||||
Debug,
|
Debug,
|
||||||
@ -100,6 +101,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
|
|||||||
ChatCommand::Ban,
|
ChatCommand::Ban,
|
||||||
ChatCommand::Build,
|
ChatCommand::Build,
|
||||||
ChatCommand::BuildAreaAdd,
|
ChatCommand::BuildAreaAdd,
|
||||||
|
ChatCommand::BuildAreaList,
|
||||||
ChatCommand::BuildAreaRemove,
|
ChatCommand::BuildAreaRemove,
|
||||||
ChatCommand::Campfire,
|
ChatCommand::Campfire,
|
||||||
ChatCommand::Debug,
|
ChatCommand::Debug,
|
||||||
@ -259,6 +261,7 @@ impl ChatCommand {
|
|||||||
"Adds a new build area",
|
"Adds a new build area",
|
||||||
Admin,
|
Admin,
|
||||||
),
|
),
|
||||||
|
ChatCommand::BuildAreaList => cmd(vec![], "List all build areas", Admin),
|
||||||
ChatCommand::BuildAreaRemove => cmd(
|
ChatCommand::BuildAreaRemove => cmd(
|
||||||
vec![Any("name", Required)],
|
vec![Any("name", Required)],
|
||||||
"Removes specified build area",
|
"Removes specified build area",
|
||||||
@ -397,7 +400,7 @@ impl ChatCommand {
|
|||||||
Admin,
|
Admin,
|
||||||
),
|
),
|
||||||
ChatCommand::PermitBuild => cmd(
|
ChatCommand::PermitBuild => cmd(
|
||||||
vec![PlayerName(Required), Any("area_name", Required)],
|
vec![Any("area_name", Required)],
|
||||||
"Grants player a bounded box they can build in",
|
"Grants player a bounded box they can build in",
|
||||||
Admin,
|
Admin,
|
||||||
),
|
),
|
||||||
@ -408,13 +411,13 @@ impl ChatCommand {
|
|||||||
Admin,
|
Admin,
|
||||||
),
|
),
|
||||||
ChatCommand::RevokeBuild => cmd(
|
ChatCommand::RevokeBuild => cmd(
|
||||||
vec![PlayerName(Required), Any("area_name", Required)],
|
vec![Any("area_name", Required)],
|
||||||
"Revokes build area permission for given player",
|
"Revokes build area permission for player",
|
||||||
Admin,
|
Admin,
|
||||||
),
|
),
|
||||||
ChatCommand::RevokeBuildAll => cmd(
|
ChatCommand::RevokeBuildAll => cmd(
|
||||||
vec![PlayerName(Required)],
|
vec![],
|
||||||
"Revokes all build area permissions for given player",
|
"Revokes all build area permissions for player",
|
||||||
Admin,
|
Admin,
|
||||||
),
|
),
|
||||||
ChatCommand::Region => cmd(
|
ChatCommand::Region => cmd(
|
||||||
@ -504,6 +507,7 @@ impl ChatCommand {
|
|||||||
ChatCommand::Ban => "ban",
|
ChatCommand::Ban => "ban",
|
||||||
ChatCommand::Build => "build",
|
ChatCommand::Build => "build",
|
||||||
ChatCommand::BuildAreaAdd => "build_area_add",
|
ChatCommand::BuildAreaAdd => "build_area_add",
|
||||||
|
ChatCommand::BuildAreaList => "build_area_list",
|
||||||
ChatCommand::BuildAreaRemove => "build_area_remove",
|
ChatCommand::BuildAreaRemove => "build_area_remove",
|
||||||
ChatCommand::Campfire => "campfire",
|
ChatCommand::Campfire => "campfire",
|
||||||
ChatCommand::Debug => "debug",
|
ChatCommand::Debug => "debug",
|
||||||
|
@ -2,12 +2,13 @@ use crate::depot::Id;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DerefFlaggedStorage};
|
use specs::{Component, DerefFlaggedStorage};
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
|
use std::collections::HashSet;
|
||||||
use vek::geom::Aabb;
|
use vek::geom::Aabb;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct CanBuild {
|
pub struct CanBuild {
|
||||||
pub building_is_on: bool,
|
pub enabled: bool,
|
||||||
pub build_areas: Vec<Id<Aabb<i32>>>,
|
pub build_areas: HashSet<Id<Aabb<i32>>>,
|
||||||
}
|
}
|
||||||
impl Component for CanBuild {
|
impl Component for CanBuild {
|
||||||
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
|
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
|
||||||
|
@ -34,6 +34,7 @@ use common_sys::state::BuildAreas;
|
|||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use specs::{Builder, Entity as EcsEntity, Join, WorldExt};
|
use specs::{Builder, Entity as EcsEntity, Join, WorldExt};
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
@ -87,6 +88,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
|
|||||||
ChatCommand::Ban => handle_ban,
|
ChatCommand::Ban => handle_ban,
|
||||||
ChatCommand::Build => handle_build,
|
ChatCommand::Build => handle_build,
|
||||||
ChatCommand::BuildAreaAdd => handle_build_area_add,
|
ChatCommand::BuildAreaAdd => handle_build_area_add,
|
||||||
|
ChatCommand::BuildAreaList => handle_build_area_list,
|
||||||
ChatCommand::BuildAreaRemove => handle_build_area_remove,
|
ChatCommand::BuildAreaRemove => handle_build_area_remove,
|
||||||
ChatCommand::Campfire => handle_spawn_campfire,
|
ChatCommand::Campfire => handle_spawn_campfire,
|
||||||
ChatCommand::Debug => handle_debug,
|
ChatCommand::Debug => handle_debug,
|
||||||
@ -1129,31 +1131,23 @@ fn handle_safezone(
|
|||||||
fn handle_permit_build(
|
fn handle_permit_build(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
client: EcsEntity,
|
client: EcsEntity,
|
||||||
_target: EcsEntity,
|
target: EcsEntity,
|
||||||
args: String,
|
args: String,
|
||||||
action: &ChatCommand,
|
action: &ChatCommand,
|
||||||
) {
|
) {
|
||||||
if let (Some(target_alias), Some(area_name)) =
|
if let Some(area_name) = scan_fmt_some!(&args, &action.arg_fmt(), String) {
|
||||||
scan_fmt_some!(&args, &action.arg_fmt(), String, String)
|
|
||||||
{
|
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
let target_player_opt = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
|
|
||||||
.join()
|
|
||||||
.find(|(_, player)| player.alias == target_alias)
|
|
||||||
.map(|(entity, _)| entity);
|
|
||||||
|
|
||||||
if let Some(target_player) = target_player_opt {
|
|
||||||
if server
|
if server
|
||||||
.state
|
.state
|
||||||
.read_storage::<comp::CanBuild>()
|
.read_storage::<comp::CanBuild>()
|
||||||
.get(target_player)
|
.get(target)
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
let _ =
|
let _ = ecs
|
||||||
ecs.write_storage::<comp::CanBuild>()
|
.write_storage::<comp::CanBuild>()
|
||||||
.insert(target_player, comp::CanBuild {
|
.insert(target, comp::CanBuild {
|
||||||
building_is_on: false,
|
enabled: false,
|
||||||
build_areas: Vec::new(),
|
build_areas: HashSet::new(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(bb_id) = ecs
|
if let Some(bb_id) = ecs
|
||||||
@ -1162,28 +1156,18 @@ fn handle_permit_build(
|
|||||||
.area_names
|
.area_names
|
||||||
.get(&area_name)
|
.get(&area_name)
|
||||||
{
|
{
|
||||||
if let Some(mut comp_can_build) =
|
if let Some(mut comp_can_build) = ecs.write_storage::<comp::CanBuild>().get_mut(target)
|
||||||
ecs.write_storage::<comp::CanBuild>().get_mut(target_player)
|
|
||||||
{
|
{
|
||||||
comp_can_build.build_areas.push(*bb_id);
|
comp_can_build.build_areas.insert(*bb_id);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(
|
ServerGeneral::server_msg(
|
||||||
ChatType::CommandInfo,
|
ChatType::CommandInfo,
|
||||||
format!("Gave {} permission to build in {}", target_alias, area_name),
|
format!("Permission to build in {} granted", area_name),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
server.notify_client(
|
|
||||||
client,
|
|
||||||
ServerGeneral::server_msg(
|
|
||||||
ChatType::CommandError,
|
|
||||||
format!("Player '{}' not found!", target_alias),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
@ -1195,51 +1179,30 @@ fn handle_permit_build(
|
|||||||
fn handle_revoke_build(
|
fn handle_revoke_build(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
client: EcsEntity,
|
client: EcsEntity,
|
||||||
_target: EcsEntity,
|
target: EcsEntity,
|
||||||
args: String,
|
args: String,
|
||||||
action: &ChatCommand,
|
action: &ChatCommand,
|
||||||
) {
|
) {
|
||||||
if let (Some(target_alias), Some(area_name)) =
|
if let Some(area_name) = scan_fmt_some!(&args, &action.arg_fmt(), String) {
|
||||||
scan_fmt_some!(&args, &action.arg_fmt(), String, String)
|
|
||||||
{
|
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
let target_player_opt = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
|
|
||||||
.join()
|
|
||||||
.find(|(_, player)| player.alias == target_alias)
|
|
||||||
.map(|(entity, _)| entity);
|
|
||||||
|
|
||||||
if let Some(target_player) = target_player_opt {
|
|
||||||
if let Some(bb_id) = ecs
|
if let Some(bb_id) = ecs
|
||||||
.read_resource::<BuildAreas>()
|
.read_resource::<BuildAreas>()
|
||||||
.deref()
|
.deref()
|
||||||
.area_names
|
.area_names
|
||||||
.get(&area_name)
|
.get(&area_name)
|
||||||
{
|
{
|
||||||
if let Some(mut comp_can_build) =
|
if let Some(mut comp_can_build) = ecs.write_storage::<comp::CanBuild>().get_mut(target)
|
||||||
ecs.write_storage::<comp::CanBuild>().get_mut(target_player)
|
|
||||||
{
|
{
|
||||||
comp_can_build.build_areas.retain(|&x| x != *bb_id);
|
comp_can_build.build_areas.retain(|&x| x != *bb_id);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(
|
ServerGeneral::server_msg(
|
||||||
ChatType::CommandInfo,
|
ChatType::CommandInfo,
|
||||||
format!(
|
format!("Permission to build in {} revoked", area_name),
|
||||||
"Revoked {}'s permission to build in {}",
|
|
||||||
target_alias, area_name
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
server.notify_client(
|
|
||||||
client,
|
|
||||||
ServerGeneral::server_msg(
|
|
||||||
ChatType::CommandError,
|
|
||||||
format!("Player '{}' not found!", target_alias),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
@ -1251,41 +1214,17 @@ fn handle_revoke_build(
|
|||||||
fn handle_revoke_build_all(
|
fn handle_revoke_build_all(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
client: EcsEntity,
|
client: EcsEntity,
|
||||||
_target: EcsEntity,
|
target: EcsEntity,
|
||||||
args: String,
|
_args: String,
|
||||||
action: &ChatCommand,
|
_action: &ChatCommand,
|
||||||
) {
|
) {
|
||||||
if let Some(target_alias) = scan_fmt_some!(&args, &action.arg_fmt(), String) {
|
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
let target_player_opt = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
|
|
||||||
.join()
|
|
||||||
.find(|(_, player)| player.alias == target_alias)
|
|
||||||
.map(|(entity, _)| entity);
|
|
||||||
|
|
||||||
if let Some(target_player) = target_player_opt {
|
ecs.write_storage::<comp::CanBuild>().remove(target);
|
||||||
ecs.write_storage::<comp::CanBuild>().remove(target_player);
|
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(
|
ServerGeneral::server_msg(ChatType::CommandInfo, "All build permissions revoked"),
|
||||||
ChatType::CommandInfo,
|
|
||||||
format!("Revoked {}'s permission to build everywhere", target_alias),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
server.notify_client(
|
|
||||||
client,
|
|
||||||
ServerGeneral::server_msg(
|
|
||||||
ChatType::CommandError,
|
|
||||||
format!("Player '{}' not found!", target_alias),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
server.notify_client(
|
|
||||||
client,
|
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, action.help_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_players(
|
fn handle_players(
|
||||||
@ -1328,14 +1267,14 @@ fn handle_build(
|
|||||||
.write_storage::<comp::CanBuild>()
|
.write_storage::<comp::CanBuild>()
|
||||||
.get_mut(target)
|
.get_mut(target)
|
||||||
{
|
{
|
||||||
if can_build.building_is_on {
|
if can_build.enabled {
|
||||||
can_build.building_is_on = false;
|
can_build.enabled = false;
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled off build mode!"),
|
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled off build mode!"),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
can_build.building_is_on = true;
|
can_build.enabled = true;
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled on build mode!"),
|
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled on build mode!"),
|
||||||
@ -1371,13 +1310,28 @@ fn handle_build_area_add(
|
|||||||
i32
|
i32
|
||||||
) {
|
) {
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
|
if ecs
|
||||||
|
.read_resource::<BuildAreas>()
|
||||||
|
.deref()
|
||||||
|
.area_names
|
||||||
|
.contains_key(&area_name)
|
||||||
|
{
|
||||||
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Build zone {} already exists!", area_name),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
let bb_id = ecs
|
let bb_id = ecs
|
||||||
.write_resource::<BuildAreas>()
|
.write_resource::<BuildAreas>()
|
||||||
.deref_mut()
|
.deref_mut()
|
||||||
.areas
|
.areas
|
||||||
.insert(Aabb {
|
.insert(Aabb {
|
||||||
min: Vec3::new(xlo, ylo, zlo),
|
min: Vec3::new(xlo.min(xhi), ylo.min(yhi), zlo.min(zhi)),
|
||||||
max: Vec3::new(xhi, yhi, zhi),
|
max: Vec3::new(xhi.max(xlo), yhi.max(ylo), zhi.max(zlo)),
|
||||||
});
|
});
|
||||||
ecs.write_resource::<BuildAreas>()
|
ecs.write_resource::<BuildAreas>()
|
||||||
.deref_mut()
|
.deref_mut()
|
||||||
@ -1393,6 +1347,34 @@ fn handle_build_area_add(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_build_area_list(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
_args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
|
let ecs = server.state.ecs();
|
||||||
|
let build_areas = ecs.read_resource::<BuildAreas>();
|
||||||
|
|
||||||
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
build_areas.area_names.iter().fold(
|
||||||
|
"Build Areas:".to_string(),
|
||||||
|
|acc, (area_name, bb_id)| {
|
||||||
|
if let Some(aabb) = build_areas.areas.get(*bb_id) {
|
||||||
|
format!("{}\n{}: {} to {}", acc, area_name, aabb.min, aabb.max)
|
||||||
|
} else {
|
||||||
|
acc
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_build_area_remove(
|
fn handle_build_area_remove(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
client: EcsEntity,
|
client: EcsEntity,
|
||||||
|
@ -104,31 +104,39 @@ impl Sys {
|
|||||||
},
|
},
|
||||||
ClientGeneral::BreakBlock(pos) => {
|
ClientGeneral::BreakBlock(pos) => {
|
||||||
if let Some(comp_can_build) = can_build.get(entity) {
|
if let Some(comp_can_build) = can_build.get(entity) {
|
||||||
if comp_can_build.building_is_on {
|
if comp_can_build.enabled {
|
||||||
for area in comp_can_build.build_areas.iter() {
|
for area in comp_can_build.build_areas.iter() {
|
||||||
if let Some(aabb) = build_areas.areas.get(*area) {
|
if let Some(block) = build_areas
|
||||||
if aabb.contains_point(pos) {
|
.areas
|
||||||
if let Ok(block) = terrain.get(pos) {
|
.get(*area)
|
||||||
|
// TODO: Make this an exclusive check on the upper bound of the AABB
|
||||||
|
// Vek defaults to inclusive which is not optimal
|
||||||
|
.filter(|aabb| aabb.contains_point(pos))
|
||||||
|
.and_then(|_| terrain.get(pos).ok())
|
||||||
|
{
|
||||||
block_changes.set(pos, block.into_vacant());
|
block_changes.set(pos, block.into_vacant());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ClientGeneral::PlaceBlock(pos, block) => {
|
ClientGeneral::PlaceBlock(pos, block) => {
|
||||||
if let Some(comp_can_build) = can_build.get(entity) {
|
if let Some(comp_can_build) = can_build.get(entity) {
|
||||||
if comp_can_build.building_is_on {
|
if comp_can_build.enabled {
|
||||||
for area in comp_can_build.build_areas.iter() {
|
for area in comp_can_build.build_areas.iter() {
|
||||||
if let Some(aabb) = build_areas.areas.get(*area) {
|
if build_areas
|
||||||
if aabb.contains_point(pos) {
|
.areas
|
||||||
|
.get(*area)
|
||||||
|
// TODO: Make this an exclusive check on the upper bound of the AABB
|
||||||
|
// Vek defaults to inclusive which is not optimal
|
||||||
|
.filter(|aabb| aabb.contains_point(pos))
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
block_changes.try_set(pos, block);
|
block_changes.try_set(pos, block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ClientGeneral::UnlockSkill(skill) => {
|
ClientGeneral::UnlockSkill(skill) => {
|
||||||
stats
|
stats
|
||||||
|
@ -317,7 +317,7 @@ impl PlayState for SessionState {
|
|||||||
.state()
|
.state()
|
||||||
.read_storage::<comp::CanBuild>()
|
.read_storage::<comp::CanBuild>()
|
||||||
.get(player_entity)
|
.get(player_entity)
|
||||||
.map_or_else(|| false, |cb| cb.building_is_on);
|
.map_or_else(|| false, |cb| cb.enabled);
|
||||||
|
|
||||||
let is_mining = self
|
let is_mining = self
|
||||||
.client
|
.client
|
||||||
|
Loading…
Reference in New Issue
Block a user