Added shortcut for chat commands /g=>/group, /s=>/say, /w=>/world, etc.

This commit is contained in:
CapsizeGlimmer 2020-06-05 14:12:18 -04:00 committed by Forest Anderson
parent c984bdcdf1
commit 22315a6e1d
4 changed files with 58 additions and 18 deletions

View File

@ -47,9 +47,10 @@ fn complete_player(part: &str, client: &Client) -> Vec<String> {
}
fn complete_command(part: &str) -> Vec<String> {
CHAT_COMMANDS
.iter()
.map(|com| com.keyword())
CHAT_SHORTCUTS
.keys()
.map(ToString::to_string)
.chain(CHAT_COMMANDS.iter().map(ToString::to_string))
.filter(|kwd| kwd.starts_with(part) || format!("/{}", kwd).starts_with(part))
.map(|c| format!("/{}", c))
.collect()

View File

@ -1,7 +1,13 @@
use crate::{assets, comp, npc};
use lazy_static::lazy_static;
use std::{ops::Deref, path::Path, str::FromStr};
use tracing::warn;
use std::{
collections::HashMap,
fmt::{self, Display},
ops::Deref,
path::Path,
str::FromStr,
};
/// Struct representing a command that a user can run from server chat.
pub struct ChatCommandData {
@ -109,6 +115,15 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
];
lazy_static! {
pub static ref CHAT_SHORTCUTS: HashMap<char, ChatCommand> = [
('f', ChatCommand::Faction),
('g', ChatCommand::Group),
('r', ChatCommand::Region),
('s', ChatCommand::Say),
('t', ChatCommand::Tell),
('w', ChatCommand::World),
].iter().cloned().collect();
static ref ALIGNMENTS: Vec<String> = vec!["wild", "enemy", "npc", "pet"]
.iter()
.map(|s| s.to_string())
@ -404,13 +419,19 @@ impl ChatCommand {
ArgumentSpec::Command(_) => "{}",
ArgumentSpec::Message(_) => "{/.*/}",
ArgumentSpec::SubCommand => "{} {/.*/}",
ArgumentSpec::Enum(_, _, _) => "{}", // TODO
ArgumentSpec::Enum(_, _, _) => "{}",
})
.collect::<Vec<_>>()
.join(" ")
}
}
impl Display for ChatCommand {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", self.keyword())
}
}
impl FromStr for ChatCommand {
type Err = ();
@ -420,10 +441,21 @@ impl FromStr for ChatCommand {
} else {
&keyword[..]
};
for c in CHAT_COMMANDS {
if kwd == c.keyword() {
if keyword.len() == 1 {
if let Some(c) = keyword
.chars()
.nth(0)
.as_ref()
.and_then(|k| CHAT_SHORTCUTS.get(k))
{
return Ok(*c);
}
} else {
for c in CHAT_COMMANDS {
if kwd == c.keyword() {
return Ok(*c);
}
}
}
Err(())
}

View File

@ -6,7 +6,7 @@ use crate::{Server, StateExt};
use chrono::{NaiveTime, Timelike};
use common::{
assets,
cmd::{ChatCommand, CHAT_COMMANDS},
cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS},
comp,
comp::Item,
event::{EventBus, ServerEvent},
@ -657,6 +657,11 @@ fn handle_help(
server.notify_client(client, ServerMsg::private(String::from(cmd.help_string())));
}
}
let shortcuts = CHAT_SHORTCUTS.iter().fold(
"Aditionally, you can use the following shortcuts:".to_string(),
|s, (k, v)| format!("{}\n/{} => /{}", s, k, v.keyword()),
);
server.notify_client(client, ServerMsg::private(shortcuts.to_string()));
}
}
@ -1591,19 +1596,14 @@ fn handle_sudo(
scan_fmt_some!(&args, &action.arg_fmt(), String, String, String)
{
let cmd_args = cmd_args.unwrap_or(String::from(""));
let cmd = if cmd.chars().next() == Some('/') {
cmd.chars().skip(1).collect()
} else {
cmd
};
if let Some(action) = CHAT_COMMANDS.iter().find(|c| c.keyword() == cmd) {
if let Ok(action) = cmd.parse() {
let ecs = server.state.ecs();
let entity_opt = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
.join()
.find(|(_, player)| player.alias == player_alias)
.map(|(entity, _)| entity);
if let Some(entity) = entity_opt {
get_handler(action)(server, client, entity, cmd_args, action);
get_handler(&action)(server, client, entity, cmd_args, &action);
} else {
server.notify_client(
client,

View File

@ -20,9 +20,16 @@ mod inventory_manip;
mod player;
pub enum Event {
ClientConnected { entity: EcsEntity },
ClientDisconnected { entity: EcsEntity },
Chat { entity: Option<EcsEntity>, msg: String },
ClientConnected {
entity: EcsEntity,
},
ClientDisconnected {
entity: EcsEntity,
},
Chat {
entity: Option<EcsEntity>,
msg: String,
},
}
impl Server {