mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Implement /sudo command
This commit is contained in:
parent
1831c0e20c
commit
bbbe03a033
@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added waypoints next to dungeons
|
- Added waypoints next to dungeons
|
||||||
- Made players spawn in towns
|
- Made players spawn in towns
|
||||||
- Added non-uniform block heights
|
- Added non-uniform block heights
|
||||||
|
- Added `/sudo` command
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -40,12 +40,14 @@ pub struct ChatCommand {
|
|||||||
/// * `&mut Server` - the `Server` instance executing the command.
|
/// * `&mut Server` - the `Server` instance executing the command.
|
||||||
/// * `EcsEntity` - an `Entity` corresponding to the player that invoked the
|
/// * `EcsEntity` - an `Entity` corresponding to the player that invoked the
|
||||||
/// command.
|
/// command.
|
||||||
|
/// * `EcsEntity` - an `Entity` for the player on whom the command is
|
||||||
|
/// invoked. This differs from the previous argument when using /sudo
|
||||||
/// * `String` - a `String` containing the part of the command after the
|
/// * `String` - a `String` containing the part of the command after the
|
||||||
/// keyword.
|
/// keyword.
|
||||||
/// * `&ChatCommand` - the command to execute with the above arguments.
|
/// * `&ChatCommand` - the command to execute with the above arguments.
|
||||||
/// Handler functions must parse arguments from the the given `String`
|
/// Handler functions must parse arguments from the the given `String`
|
||||||
/// (`scan_fmt!` is included for this purpose).
|
/// (`scan_fmt!` is included for this purpose).
|
||||||
handler: fn(&mut Server, EcsEntity, String, &ChatCommand),
|
handler: fn(&mut Server, EcsEntity, EcsEntity, String, &ChatCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChatCommand {
|
impl ChatCommand {
|
||||||
@ -55,7 +57,7 @@ impl ChatCommand {
|
|||||||
arg_fmt: &'static str,
|
arg_fmt: &'static str,
|
||||||
help_string: &'static str,
|
help_string: &'static str,
|
||||||
needs_admin: bool,
|
needs_admin: bool,
|
||||||
handler: fn(&mut Server, EcsEntity, String, &ChatCommand),
|
handler: fn(&mut Server, EcsEntity, EcsEntity, String, &ChatCommand),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
keyword,
|
keyword,
|
||||||
@ -80,10 +82,10 @@ impl ChatCommand {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
(self.handler)(server, entity, args, self);
|
(self.handler)(server, entity, entity, args, self);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(self.handler)(server, entity, args, self);
|
(self.handler)(server, entity, entity, args, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,79 +263,116 @@ lazy_static! {
|
|||||||
true,
|
true,
|
||||||
handle_debug,
|
handle_debug,
|
||||||
),
|
),
|
||||||
|
ChatCommand::new(
|
||||||
|
"sudo",
|
||||||
|
"{} {} {/.*/}",
|
||||||
|
"/sudo <player> /<command> [args...] : Run command as if you were another player",
|
||||||
|
true,
|
||||||
|
handle_sudo,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_give(server: &mut Server, entity: EcsEntity, args: String, _action: &ChatCommand) {
|
fn handle_give(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
if let Ok(item) = assets::load_cloned(&args) {
|
if let Ok(item) = assets::load_cloned(&args) {
|
||||||
server
|
server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::Inventory>()
|
.write_storage::<comp::Inventory>()
|
||||||
.get_mut(entity)
|
.get_mut(target)
|
||||||
.map(|inv| inv.push(item));
|
.map(|inv| inv.push(item));
|
||||||
let _ = server
|
let _ = server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::InventoryUpdate>()
|
.write_storage::<comp::InventoryUpdate>()
|
||||||
.insert(
|
.insert(
|
||||||
entity,
|
target,
|
||||||
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Given),
|
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Given),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from("Invalid item!")));
|
server.notify_client(client, ServerMsg::private(String::from("Invalid item!")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_jump(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_jump(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) {
|
if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) {
|
||||||
match server.state.read_component_cloned::<comp::Pos>(entity) {
|
match server.state.read_component_cloned::<comp::Pos>(target) {
|
||||||
Some(current_pos) => {
|
Some(current_pos) => {
|
||||||
server
|
server
|
||||||
.state
|
.state
|
||||||
.write_component(entity, comp::Pos(current_pos.0 + Vec3::new(x, y, z)));
|
.write_component(target, comp::Pos(current_pos.0 + Vec3::new(x, y, z)));
|
||||||
server.state.write_component(entity, comp::ForceUpdate);
|
server.state.write_component(target, comp::ForceUpdate);
|
||||||
},
|
},
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You have no position.")),
|
ServerMsg::private(String::from("You have no position.")),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_goto(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_goto(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) {
|
if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) {
|
||||||
if server
|
if server
|
||||||
.state
|
.state
|
||||||
.read_component_cloned::<comp::Pos>(entity)
|
.read_component_cloned::<comp::Pos>(target)
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
server
|
server
|
||||||
.state
|
.state
|
||||||
.write_component(entity, comp::Pos(Vec3::new(x, y, z)));
|
.write_component(target, comp::Pos(Vec3::new(x, y, z)));
|
||||||
server.state.write_component(entity, comp::ForceUpdate);
|
server.state.write_component(target, comp::ForceUpdate);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You have no position.")),
|
ServerMsg::private(String::from("You have no position.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(action.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_kill(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
|
fn handle_kill(
|
||||||
|
server: &mut Server,
|
||||||
|
_client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
_args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
server
|
server
|
||||||
.state
|
.state
|
||||||
.ecs_mut()
|
.ecs_mut()
|
||||||
.write_storage::<comp::Stats>()
|
.write_storage::<comp::Stats>()
|
||||||
.get_mut(entity)
|
.get_mut(target)
|
||||||
.map(|s| s.health.set_to(0, comp::HealthSource::Suicide));
|
.map(|s| s.health.set_to(0, comp::HealthSource::Suicide));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_time(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
let time = scan_fmt_some!(&args, action.arg_fmt, String);
|
let time = scan_fmt_some!(&args, action.arg_fmt, String);
|
||||||
let new_time = match time.as_ref().map(|s| s.as_str()) {
|
let new_time = match time.as_ref().map(|s| s.as_str()) {
|
||||||
Some("midnight") => NaiveTime::from_hms(0, 0, 0),
|
Some("midnight") => NaiveTime::from_hms(0, 0, 0),
|
||||||
@ -349,7 +388,7 @@ fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
|
|||||||
Ok(time) => time,
|
Ok(time) => time,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!("'{}' is not a valid time.", n)),
|
ServerMsg::private(format!("'{}' is not a valid time.", n)),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@ -368,7 +407,7 @@ fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
|
|||||||
Some(time) => format!("It is {}", time.format("%H:%M").to_string()),
|
Some(time) => format!("It is {}", time.format("%H:%M").to_string()),
|
||||||
None => String::from("Unknown Time"),
|
None => String::from("Unknown Time"),
|
||||||
};
|
};
|
||||||
server.notify_client(entity, ServerMsg::private(msg));
|
server.notify_client(client, ServerMsg::private(msg));
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -377,7 +416,7 @@ fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
|
|||||||
new_time.num_seconds_from_midnight() as f64;
|
new_time.num_seconds_from_midnight() as f64;
|
||||||
|
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!(
|
ServerMsg::private(format!(
|
||||||
"Time changed to: {}",
|
"Time changed to: {}",
|
||||||
new_time.format("%H:%M").to_string()
|
new_time.format("%H:%M").to_string()
|
||||||
@ -385,43 +424,55 @@ fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_health(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_health(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
if let Ok(hp) = scan_fmt!(&args, action.arg_fmt, u32) {
|
if let Ok(hp) = scan_fmt!(&args, action.arg_fmt, u32) {
|
||||||
if let Some(stats) = server
|
if let Some(stats) = server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::Stats>()
|
.write_storage::<comp::Stats>()
|
||||||
.get_mut(entity)
|
.get_mut(target)
|
||||||
{
|
{
|
||||||
stats.health.set_to(hp, comp::HealthSource::Command);
|
stats.health.set_to(hp, comp::HealthSource::Command);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You have no health.")),
|
ServerMsg::private(String::from("You have no health.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You must specify health amount!")),
|
ServerMsg::private(String::from("You must specify health amount!")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_alias(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_alias(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) {
|
if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) {
|
||||||
server
|
server
|
||||||
.state
|
.state
|
||||||
.ecs_mut()
|
.ecs_mut()
|
||||||
.write_storage::<comp::Player>()
|
.write_storage::<comp::Player>()
|
||||||
.get_mut(entity)
|
.get_mut(target)
|
||||||
.map(|player| player.alias = alias);
|
.map(|player| player.alias = alias);
|
||||||
|
|
||||||
// Update name on client player lists
|
// Update name on client player lists
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
if let (Some(uid), Some(player)) = (
|
if let (Some(uid), Some(player)) = (
|
||||||
ecs.read_storage::<Uid>().get(entity),
|
ecs.read_storage::<Uid>().get(target),
|
||||||
ecs.read_storage::<comp::Player>().get(entity),
|
ecs.read_storage::<comp::Player>().get(target),
|
||||||
) {
|
) {
|
||||||
let msg = ServerMsg::PlayerListUpdate(PlayerListUpdate::Alias(
|
let msg = ServerMsg::PlayerListUpdate(PlayerListUpdate::Alias(
|
||||||
(*uid).into(),
|
(*uid).into(),
|
||||||
@ -430,60 +481,72 @@ fn handle_alias(server: &mut Server, entity: EcsEntity, args: String, action: &C
|
|||||||
server.state.notify_registered_clients(msg);
|
server.state.notify_registered_clients(msg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(action.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_tp(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_tp(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) {
|
if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) {
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
let opt_player = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
|
let opt_player = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
|
||||||
.join()
|
.join()
|
||||||
.find(|(_, player)| player.alias == alias)
|
.find(|(_, player)| player.alias == alias)
|
||||||
.map(|(entity, _)| entity);
|
.map(|(entity, _)| entity);
|
||||||
match server.state.read_component_cloned::<comp::Pos>(entity) {
|
match server.state.read_component_cloned::<comp::Pos>(target) {
|
||||||
Some(_pos) => match opt_player {
|
Some(_pos) => match opt_player {
|
||||||
Some(player) => match server.state.read_component_cloned::<comp::Pos>(player) {
|
Some(player) => match server.state.read_component_cloned::<comp::Pos>(player) {
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
server.state.write_component(entity, pos);
|
server.state.write_component(target, pos);
|
||||||
server.state.write_component(entity, comp::ForceUpdate);
|
server.state.write_component(target, comp::ForceUpdate);
|
||||||
},
|
},
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!("Unable to teleport to player '{}'!", alias)),
|
ServerMsg::private(format!("Unable to teleport to player '{}'!", alias)),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!("Player '{}' not found!", alias)),
|
ServerMsg::private(format!("Player '{}' not found!", alias)),
|
||||||
);
|
);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from(action.help_string)),
|
ServerMsg::private(String::from(action.help_string)),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
server.notify_client(entity, ServerMsg::private(format!("You have no position!")));
|
server.notify_client(client, ServerMsg::private(format!("You have no position!")));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(action.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_spawn(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
match scan_fmt_some!(&args, action.arg_fmt, String, npc::NpcBody, String) {
|
match scan_fmt_some!(&args, action.arg_fmt, String, npc::NpcBody, String) {
|
||||||
(Some(opt_align), Some(npc::NpcBody(id, mut body)), opt_amount) => {
|
(Some(opt_align), Some(npc::NpcBody(id, mut body)), opt_amount) => {
|
||||||
if let Some(alignment) = parse_alignment(entity, &opt_align) {
|
if let Some(alignment) = parse_alignment(target, &opt_align) {
|
||||||
let amount = opt_amount
|
let amount = opt_amount
|
||||||
.and_then(|a| a.parse().ok())
|
.and_then(|a| a.parse().ok())
|
||||||
.filter(|x| *x > 0)
|
.filter(|x| *x > 0)
|
||||||
.unwrap_or(1)
|
.unwrap_or(1)
|
||||||
.min(10);
|
.min(10);
|
||||||
|
|
||||||
match server.state.read_component_cloned::<comp::Pos>(entity) {
|
match server.state.read_component_cloned::<comp::Pos>(target) {
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
let agent =
|
let agent =
|
||||||
if let comp::Alignment::Owned(_) | comp::Alignment::Npc = alignment {
|
if let comp::Alignment::Owned(_) | comp::Alignment::Npc = alignment {
|
||||||
@ -517,7 +580,7 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C
|
|||||||
|
|
||||||
if let Some(uid) = server.state.ecs().uid_from_entity(new_entity) {
|
if let Some(uid) = server.state.ecs().uid_from_entity(new_entity) {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(
|
ServerMsg::private(
|
||||||
format!("Spawned entity with ID: {}", uid).to_owned(),
|
format!("Spawned entity with ID: {}", uid).to_owned(),
|
||||||
),
|
),
|
||||||
@ -525,24 +588,30 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!("Spawned {} entities", amount).to_owned()),
|
ServerMsg::private(format!("Spawned {} entities", amount).to_owned()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private("You have no position!".to_owned()),
|
ServerMsg::private("You have no position!".to_owned()),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(action.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_players(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
|
fn handle_players(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
_args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
let players = ecs.read_storage::<comp::Player>();
|
let players = ecs.read_storage::<comp::Player>();
|
||||||
let count = players.join().count();
|
let count = players.join().count();
|
||||||
@ -560,26 +629,32 @@ fn handle_players(server: &mut Server, entity: EcsEntity, _args: String, _action
|
|||||||
s
|
s
|
||||||
});
|
});
|
||||||
|
|
||||||
server.notify_client(entity, ServerMsg::private(header_message + &player_list));
|
server.notify_client(client, ServerMsg::private(header_message + &player_list));
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(header_message));
|
server.notify_client(client, ServerMsg::private(header_message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_build(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
|
fn handle_build(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
_args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
if server
|
if server
|
||||||
.state
|
.state
|
||||||
.read_storage::<comp::CanBuild>()
|
.read_storage::<comp::CanBuild>()
|
||||||
.get(entity)
|
.get(target)
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
server
|
server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::CanBuild>()
|
.write_storage::<comp::CanBuild>()
|
||||||
.remove(entity);
|
.remove(target);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("Toggled off build mode!")),
|
ServerMsg::private(String::from("Toggled off build mode!")),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -587,18 +662,24 @@ fn handle_build(server: &mut Server, entity: EcsEntity, _args: String, _action:
|
|||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::CanBuild>()
|
.write_storage::<comp::CanBuild>()
|
||||||
.insert(entity, comp::CanBuild);
|
.insert(target, comp::CanBuild);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("Toggled on build mode!")),
|
ServerMsg::private(String::from("Toggled on build mode!")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_help(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
|
fn handle_help(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
_args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
for cmd in CHAT_COMMANDS.iter() {
|
for cmd in CHAT_COMMANDS.iter() {
|
||||||
if !cmd.needs_admin || server.entity_is_admin(entity) {
|
if !cmd.needs_admin || server.entity_is_admin(client) {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(cmd.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(cmd.help_string)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,7 +694,13 @@ fn parse_alignment(owner: EcsEntity, alignment: &str) -> Option<comp::Alignment>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_killnpcs(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
|
fn handle_killnpcs(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
_args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
let mut stats = ecs.write_storage::<comp::Stats>();
|
let mut stats = ecs.write_storage::<comp::Stats>();
|
||||||
let players = ecs.read_storage::<comp::Player>();
|
let players = ecs.read_storage::<comp::Player>();
|
||||||
@ -627,23 +714,29 @@ fn handle_killnpcs(server: &mut Server, entity: EcsEntity, _args: String, _actio
|
|||||||
} else {
|
} else {
|
||||||
"No NPCs on server.".to_string()
|
"No NPCs on server.".to_string()
|
||||||
};
|
};
|
||||||
server.notify_client(entity, ServerMsg::private(text));
|
server.notify_client(client, ServerMsg::private(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_object(server: &mut Server, entity: EcsEntity, args: String, _action: &ChatCommand) {
|
fn handle_object(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
let obj_type = scan_fmt!(&args, _action.arg_fmt, String);
|
let obj_type = scan_fmt!(&args, _action.arg_fmt, String);
|
||||||
|
|
||||||
let pos = server
|
let pos = server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.read_storage::<comp::Pos>()
|
.read_storage::<comp::Pos>()
|
||||||
.get(entity)
|
.get(target)
|
||||||
.copied();
|
.copied();
|
||||||
let ori = server
|
let ori = server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.read_storage::<comp::Ori>()
|
.read_storage::<comp::Ori>()
|
||||||
.get(entity)
|
.get(target)
|
||||||
.copied();
|
.copied();
|
||||||
/*let builder = server.state
|
/*let builder = server.state
|
||||||
.create_object(pos, ori, obj_type)
|
.create_object(pos, ori, obj_type)
|
||||||
@ -701,7 +794,7 @@ fn handle_object(server: &mut Server, entity: EcsEntity, args: String, _action:
|
|||||||
Ok("crafting_bench") => comp::object::Body::CraftingBench,
|
Ok("crafting_bench") => comp::object::Body::CraftingBench,
|
||||||
_ => {
|
_ => {
|
||||||
return server.notify_client(
|
return server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("Object not found!")),
|
ServerMsg::private(String::from("Object not found!")),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -723,18 +816,24 @@ fn handle_object(server: &mut Server, entity: EcsEntity, args: String, _action:
|
|||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!(
|
ServerMsg::private(format!(
|
||||||
"Spawned: {}",
|
"Spawned: {}",
|
||||||
obj_str_res.unwrap_or("<Unknown object>")
|
obj_str_res.unwrap_or("<Unknown object>")
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(format!("You have no position!")));
|
server.notify_client(client, ServerMsg::private(format!("You have no position!")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_light(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_light(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
let (opt_r, opt_g, opt_b, opt_x, opt_y, opt_z, opt_s) =
|
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);
|
scan_fmt_some!(&args, action.arg_fmt, f32, f32, f32, f32, f32, f32, f32);
|
||||||
|
|
||||||
@ -756,7 +855,7 @@ fn handle_light(server: &mut Server, entity: EcsEntity, args: String, action: &C
|
|||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.read_storage::<comp::Pos>()
|
.read_storage::<comp::Pos>()
|
||||||
.get(entity)
|
.get(target)
|
||||||
.copied();
|
.copied();
|
||||||
if let Some(pos) = pos {
|
if let Some(pos) = pos {
|
||||||
server
|
server
|
||||||
@ -767,19 +866,25 @@ fn handle_light(server: &mut Server, entity: EcsEntity, args: String, action: &C
|
|||||||
.with(comp::ForceUpdate)
|
.with(comp::ForceUpdate)
|
||||||
.with(light_emitter)
|
.with(light_emitter)
|
||||||
.build();
|
.build();
|
||||||
server.notify_client(entity, ServerMsg::private(format!("Spawned object.")));
|
server.notify_client(client, ServerMsg::private(format!("Spawned object.")));
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(format!("You have no position!")));
|
server.notify_client(client, ServerMsg::private(format!("You have no position!")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_lantern(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_lantern(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
let opt_s = scan_fmt_some!(&args, action.arg_fmt, f32);
|
let opt_s = scan_fmt_some!(&args, action.arg_fmt, f32);
|
||||||
|
|
||||||
if server
|
if server
|
||||||
.state
|
.state
|
||||||
.read_storage::<comp::LightEmitter>()
|
.read_storage::<comp::LightEmitter>()
|
||||||
.get(entity)
|
.get(target)
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
if let Some(s) = opt_s {
|
if let Some(s) = opt_s {
|
||||||
@ -787,11 +892,11 @@ fn handle_lantern(server: &mut Server, entity: EcsEntity, args: String, action:
|
|||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::LightEmitter>()
|
.write_storage::<comp::LightEmitter>()
|
||||||
.get_mut(entity)
|
.get_mut(target)
|
||||||
{
|
{
|
||||||
light.strength = s.max(0.1).min(10.0);
|
light.strength = s.max(0.1).min(10.0);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You adjusted flame strength.")),
|
ServerMsg::private(String::from("You adjusted flame strength.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -800,9 +905,9 @@ fn handle_lantern(server: &mut Server, entity: EcsEntity, args: String, action:
|
|||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::LightEmitter>()
|
.write_storage::<comp::LightEmitter>()
|
||||||
.remove(entity);
|
.remove(target);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You put out the lantern.")),
|
ServerMsg::private(String::from("You put out the lantern.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -811,7 +916,7 @@ fn handle_lantern(server: &mut Server, entity: EcsEntity, args: String, action:
|
|||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::LightEmitter>()
|
.write_storage::<comp::LightEmitter>()
|
||||||
.insert(entity, comp::LightEmitter {
|
.insert(target, comp::LightEmitter {
|
||||||
offset: Vec3::new(0.5, 0.2, 0.8),
|
offset: Vec3::new(0.5, 0.2, 0.8),
|
||||||
col: Rgb::new(1.0, 0.75, 0.3),
|
col: Rgb::new(1.0, 0.75, 0.3),
|
||||||
strength: if let Some(s) = opt_s {
|
strength: if let Some(s) = opt_s {
|
||||||
@ -822,50 +927,68 @@ fn handle_lantern(server: &mut Server, entity: EcsEntity, args: String, action:
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You lit your lantern.")),
|
ServerMsg::private(String::from("You lit your lantern.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_explosion(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_explosion(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
let power = scan_fmt!(&args, action.arg_fmt, f32).unwrap_or(8.0);
|
let power = scan_fmt!(&args, action.arg_fmt, f32).unwrap_or(8.0);
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
|
|
||||||
match server.state.read_component_cloned::<comp::Pos>(entity) {
|
match server.state.read_component_cloned::<comp::Pos>(target) {
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
ecs.read_resource::<EventBus<ServerEvent>>()
|
ecs.read_resource::<EventBus<ServerEvent>>()
|
||||||
.emit_now(ServerEvent::Explosion {
|
.emit_now(ServerEvent::Explosion {
|
||||||
pos: pos.0,
|
pos: pos.0,
|
||||||
power,
|
power,
|
||||||
owner: ecs.read_storage::<Uid>().get(entity).copied(),
|
owner: ecs.read_storage::<Uid>().get(target).copied(),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You have no position!")),
|
ServerMsg::private(String::from("You have no position!")),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_waypoint(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
|
fn handle_waypoint(
|
||||||
match server.state.read_component_cloned::<comp::Pos>(entity) {
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
_args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
|
match server.state.read_component_cloned::<comp::Pos>(target) {
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
let _ = server
|
let _ = server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::Waypoint>()
|
.write_storage::<comp::Waypoint>()
|
||||||
.insert(entity, comp::Waypoint::new(pos.0));
|
.insert(target, comp::Waypoint::new(pos.0));
|
||||||
server.notify_client(entity, ServerMsg::private(String::from("Waypoint set!")));
|
server.notify_client(client, ServerMsg::private(String::from("Waypoint set!")));
|
||||||
},
|
},
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You have no position!")),
|
ServerMsg::private(String::from("You have no position!")),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_adminify(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_adminify(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) {
|
if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) {
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
let opt_player = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
|
let opt_player = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
|
||||||
@ -883,18 +1006,31 @@ fn handle_adminify(server: &mut Server, entity: EcsEntity, args: String, action:
|
|||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!("Player '{}' not found!", alias)),
|
ServerMsg::private(format!("Player '{}' not found!", alias)),
|
||||||
);
|
);
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(action.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(action.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_tell(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_tell(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
|
if client != target {
|
||||||
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerMsg::tell(String::from("It's rude to impersonate people")),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) {
|
if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) {
|
||||||
let ecs = server.state.ecs();
|
let ecs = server.state.ecs();
|
||||||
let msg = &args[alias.len()..args.len()];
|
let msg = &args[alias.len()..args.len()];
|
||||||
@ -903,11 +1039,11 @@ fn handle_tell(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
|
|||||||
.find(|(_, player)| player.alias == alias)
|
.find(|(_, player)| player.alias == alias)
|
||||||
.map(|(entity, _)| entity)
|
.map(|(entity, _)| entity)
|
||||||
{
|
{
|
||||||
if player != entity {
|
if player != target {
|
||||||
if msg.len() > 1 {
|
if msg.len() > 1 {
|
||||||
if let Some(name) = ecs
|
if let Some(name) = ecs
|
||||||
.read_storage::<comp::Player>()
|
.read_storage::<comp::Player>()
|
||||||
.get(entity)
|
.get(target)
|
||||||
.map(|s| s.alias.clone())
|
.map(|s| s.alias.clone())
|
||||||
{
|
{
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
@ -915,53 +1051,60 @@ fn handle_tell(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
|
|||||||
ServerMsg::tell(format!("[{}] tells:{}", name, msg)),
|
ServerMsg::tell(format!("[{}] tells:{}", name, msg)),
|
||||||
);
|
);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::tell(format!("To [{}]:{}", alias, msg)),
|
ServerMsg::tell(format!("To [{}]:{}", alias, msg)),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("Failed to send message.")),
|
ServerMsg::private(String::from("Failed to send message.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!("[{}] wants to talk to you.", alias)),
|
ServerMsg::private(format!("[{}] wants to talk to you.", alias)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!("You can't /tell yourself.")),
|
ServerMsg::private(format!("You can't /tell yourself.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(format!("Player '{}' not found!", alias)),
|
ServerMsg::private(format!("Player '{}' not found!", alias)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(action.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "worldgen"))]
|
#[cfg(not(feature = "worldgen"))]
|
||||||
fn handle_debug_column(
|
fn handle_debug_column(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
entity: EcsEntity,
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
_args: String,
|
_args: String,
|
||||||
_action: &ChatCommand,
|
_action: &ChatCommand,
|
||||||
) {
|
) {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("Unsupported without worldgen enabled")),
|
ServerMsg::private(String::from("Unsupported without worldgen enabled")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "worldgen")]
|
#[cfg(feature = "worldgen")]
|
||||||
fn handle_debug_column(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_debug_column(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
let sim = server.world.sim();
|
let sim = server.world.sim();
|
||||||
let sampler = server.world.sample_columns();
|
let sampler = server.world.sample_columns();
|
||||||
if let Ok((x, y)) = scan_fmt!(&args, action.arg_fmt, i32, i32) {
|
if let Ok((x, y)) = scan_fmt!(&args, action.arg_fmt, i32, i32) {
|
||||||
@ -1020,15 +1163,15 @@ spawn_rate {:?} "#,
|
|||||||
))
|
))
|
||||||
};
|
};
|
||||||
if let Some(s) = foo() {
|
if let Some(s) = foo() {
|
||||||
server.notify_client(entity, ServerMsg::private(s));
|
server.notify_client(client, ServerMsg::private(s));
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("Not a pregenerated chunk.")),
|
ServerMsg::private(String::from("Not a pregenerated chunk.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(entity, ServerMsg::private(String::from(action.help_string)));
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1048,12 +1191,18 @@ fn find_target(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_exp(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_exp(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
let (a_exp, a_alias) = scan_fmt_some!(&args, action.arg_fmt, i64, String);
|
let (a_exp, a_alias) = scan_fmt_some!(&args, action.arg_fmt, i64, String);
|
||||||
|
|
||||||
if let Some(exp) = a_exp {
|
if let Some(exp) = a_exp {
|
||||||
let ecs = server.state.ecs_mut();
|
let ecs = server.state.ecs_mut();
|
||||||
let target = find_target(&ecs, a_alias, entity);
|
let target = find_target(&ecs, a_alias, target);
|
||||||
|
|
||||||
let mut error_msg = None;
|
let mut error_msg = None;
|
||||||
|
|
||||||
@ -1071,17 +1220,23 @@ fn handle_exp(server: &mut Server, entity: EcsEntity, args: String, action: &Cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(msg) = error_msg {
|
if let Some(msg) = error_msg {
|
||||||
server.notify_client(entity, msg);
|
server.notify_client(client, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_level(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
fn handle_level(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
let (a_lvl, a_alias) = scan_fmt_some!(&args, action.arg_fmt, u32, String);
|
let (a_lvl, a_alias) = scan_fmt_some!(&args, action.arg_fmt, u32, String);
|
||||||
|
|
||||||
if let Some(lvl) = a_lvl {
|
if let Some(lvl) = a_lvl {
|
||||||
let ecs = server.state.ecs_mut();
|
let ecs = server.state.ecs_mut();
|
||||||
let target = find_target(&ecs, a_alias, entity);
|
let target = find_target(&ecs, a_alias, target);
|
||||||
|
|
||||||
let mut error_msg = None;
|
let mut error_msg = None;
|
||||||
|
|
||||||
@ -1104,19 +1259,25 @@ fn handle_level(server: &mut Server, entity: EcsEntity, args: String, action: &C
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(msg) = error_msg {
|
if let Some(msg) = error_msg {
|
||||||
server.notify_client(entity, msg);
|
server.notify_client(client, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use common::comp::Item;
|
use common::comp::Item;
|
||||||
fn handle_debug(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
|
fn handle_debug(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
|
_args: String,
|
||||||
|
_action: &ChatCommand,
|
||||||
|
) {
|
||||||
if let Ok(items) = assets::load_glob::<Item>("common.items.debug.*") {
|
if let Ok(items) = assets::load_glob::<Item>("common.items.debug.*") {
|
||||||
server
|
server
|
||||||
.state()
|
.state()
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::Inventory>()
|
.write_storage::<comp::Inventory>()
|
||||||
.get_mut(entity)
|
.get_mut(target)
|
||||||
// TODO: Consider writing a `load_glob_cloned` in `assets` and using that here
|
// TODO: Consider writing a `load_glob_cloned` in `assets` and using that here
|
||||||
.map(|inv| inv.push_all_unique(items.iter().map(|item| item.as_ref().clone())));
|
.map(|inv| inv.push_all_unique(items.iter().map(|item| item.as_ref().clone())));
|
||||||
let _ = server
|
let _ = server
|
||||||
@ -1124,12 +1285,12 @@ fn handle_debug(server: &mut Server, entity: EcsEntity, _args: String, _action:
|
|||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::InventoryUpdate>()
|
.write_storage::<comp::InventoryUpdate>()
|
||||||
.insert(
|
.insert(
|
||||||
entity,
|
target,
|
||||||
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Debug),
|
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Debug),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from(
|
ServerMsg::private(String::from(
|
||||||
"Debug items not found? Something is very broken.",
|
"Debug items not found? Something is very broken.",
|
||||||
)),
|
)),
|
||||||
@ -1139,12 +1300,13 @@ fn handle_debug(server: &mut Server, entity: EcsEntity, _args: String, _action:
|
|||||||
|
|
||||||
fn handle_remove_lights(
|
fn handle_remove_lights(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
entity: EcsEntity,
|
client: EcsEntity,
|
||||||
|
target: EcsEntity,
|
||||||
args: String,
|
args: String,
|
||||||
action: &ChatCommand,
|
action: &ChatCommand,
|
||||||
) {
|
) {
|
||||||
let opt_radius = scan_fmt_some!(&args, action.arg_fmt, f32);
|
let opt_radius = scan_fmt_some!(&args, action.arg_fmt, f32);
|
||||||
let opt_player_pos = server.state.read_component_cloned::<comp::Pos>(entity);
|
let opt_player_pos = server.state.read_component_cloned::<comp::Pos>(target);
|
||||||
let mut to_delete = vec![];
|
let mut to_delete = vec![];
|
||||||
|
|
||||||
match opt_player_pos {
|
match opt_player_pos {
|
||||||
@ -1168,7 +1330,7 @@ fn handle_remove_lights(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from("You have no position.")),
|
ServerMsg::private(String::from("You have no position.")),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -1182,7 +1344,49 @@ fn handle_remove_lights(
|
|||||||
}
|
}
|
||||||
|
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
client,
|
||||||
ServerMsg::private(String::from(format!("Removed {} lights!", size))),
|
ServerMsg::private(String::from(format!("Removed {} lights!", size))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_sudo(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
args: String,
|
||||||
|
action: &ChatCommand,
|
||||||
|
) {
|
||||||
|
if let (Some(player_alias), Some(mut cmd), cmd_args) =
|
||||||
|
scan_fmt_some!(&args, action.arg_fmt, String, String, String)
|
||||||
|
{
|
||||||
|
let cmd_args = cmd_args.unwrap_or(String::from(""));
|
||||||
|
if cmd.chars().next() == Some('/') {
|
||||||
|
cmd.remove(0);
|
||||||
|
}
|
||||||
|
if let Some(action) = CHAT_COMMANDS.iter().find(|c| c.keyword == cmd) {
|
||||||
|
let mut entity_opt = None;
|
||||||
|
let ecs = server.state.ecs();
|
||||||
|
for (ent, player) in (&ecs.entities(), &ecs.read_storage::<comp::Player>()).join() {
|
||||||
|
if player.alias == player_alias {
|
||||||
|
entity_opt = Some(ent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(entity) = entity_opt {
|
||||||
|
(action.handler)(server, client, entity, cmd_args, action);
|
||||||
|
} else {
|
||||||
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerMsg::private(format!("Could not find that player")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerMsg::private(format!("Unknown command: /{}", cmd)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
server.notify_client(client, ServerMsg::private(String::from(action.help_string)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user