mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
cleanup and fixes + added change to CHANGELOG.md
This commit is contained in:
parent
74cb514094
commit
d774319cf0
@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Command to toggle experimental shaders.
|
- Command to toggle experimental shaders.
|
||||||
- Faster Energy Regeneration while sitting.
|
- Faster Energy Regeneration while sitting.
|
||||||
- Lantern glow for dropped lanterns.
|
- Lantern glow for dropped lanterns.
|
||||||
|
- Suggests commands when an invalid one is entered in chat and added Client-side commands to /help.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Bats move slower and use a simple proportional controller to maintain altitude
|
- Bats move slower and use a simple proportional controller to maintain altitude
|
||||||
|
@ -246,7 +246,7 @@ pub enum ServerChatCommand {
|
|||||||
BattleMode,
|
BattleMode,
|
||||||
BattleModeForce,
|
BattleModeForce,
|
||||||
Body,
|
Body,
|
||||||
ApplyBuff,
|
Buff,
|
||||||
Build,
|
Build,
|
||||||
BuildAreaAdd,
|
BuildAreaAdd,
|
||||||
BuildAreaList,
|
BuildAreaList,
|
||||||
@ -269,6 +269,7 @@ pub enum ServerChatCommand {
|
|||||||
GroupLeave,
|
GroupLeave,
|
||||||
GroupPromote,
|
GroupPromote,
|
||||||
Health,
|
Health,
|
||||||
|
Help,
|
||||||
Home,
|
Home,
|
||||||
JoinFaction,
|
JoinFaction,
|
||||||
Jump,
|
Jump,
|
||||||
@ -338,7 +339,7 @@ impl ServerChatCommand {
|
|||||||
"Change your alias",
|
"Change your alias",
|
||||||
Some(Moderator),
|
Some(Moderator),
|
||||||
),
|
),
|
||||||
ServerChatCommand::ApplyBuff => cmd(
|
ServerChatCommand::Buff => cmd(
|
||||||
vec![
|
vec![
|
||||||
Enum("buff", BUFFS.clone(), Required),
|
Enum("buff", BUFFS.clone(), Required),
|
||||||
Float("strength", 0.01, Optional),
|
Float("strength", 0.01, Optional),
|
||||||
@ -479,6 +480,11 @@ impl ServerChatCommand {
|
|||||||
"Set your current health",
|
"Set your current health",
|
||||||
Some(Admin),
|
Some(Admin),
|
||||||
),
|
),
|
||||||
|
ServerChatCommand::Help => ChatCommandData::new(
|
||||||
|
vec![Command(Optional)],
|
||||||
|
"Display information about commands",
|
||||||
|
None,
|
||||||
|
),
|
||||||
ServerChatCommand::Home => cmd(vec![], "Return to the home town", Some(Moderator)),
|
ServerChatCommand::Home => cmd(vec![], "Return to the home town", Some(Moderator)),
|
||||||
ServerChatCommand::JoinFaction => ChatCommandData::new(
|
ServerChatCommand::JoinFaction => ChatCommandData::new(
|
||||||
vec![Any("faction", Optional)],
|
vec![Any("faction", Optional)],
|
||||||
@ -728,11 +734,11 @@ impl ServerChatCommand {
|
|||||||
ServerChatCommand::Adminify => "adminify",
|
ServerChatCommand::Adminify => "adminify",
|
||||||
ServerChatCommand::Airship => "airship",
|
ServerChatCommand::Airship => "airship",
|
||||||
ServerChatCommand::Alias => "alias",
|
ServerChatCommand::Alias => "alias",
|
||||||
ServerChatCommand::ApplyBuff => "buff",
|
|
||||||
ServerChatCommand::Ban => "ban",
|
ServerChatCommand::Ban => "ban",
|
||||||
ServerChatCommand::BattleMode => "battlemode",
|
ServerChatCommand::BattleMode => "battlemode",
|
||||||
ServerChatCommand::BattleModeForce => "battlemode_force",
|
ServerChatCommand::BattleModeForce => "battlemode_force",
|
||||||
ServerChatCommand::Body => "body",
|
ServerChatCommand::Body => "body",
|
||||||
|
ServerChatCommand::Buff => "buff",
|
||||||
ServerChatCommand::Build => "build",
|
ServerChatCommand::Build => "build",
|
||||||
ServerChatCommand::BuildAreaAdd => "build_area_add",
|
ServerChatCommand::BuildAreaAdd => "build_area_add",
|
||||||
ServerChatCommand::BuildAreaList => "build_area_list",
|
ServerChatCommand::BuildAreaList => "build_area_list",
|
||||||
@ -753,6 +759,7 @@ impl ServerChatCommand {
|
|||||||
ServerChatCommand::GroupPromote => "group_promote",
|
ServerChatCommand::GroupPromote => "group_promote",
|
||||||
ServerChatCommand::GroupLeave => "group_leave",
|
ServerChatCommand::GroupLeave => "group_leave",
|
||||||
ServerChatCommand::Health => "health",
|
ServerChatCommand::Health => "health",
|
||||||
|
ServerChatCommand::Help => "help",
|
||||||
ServerChatCommand::Home => "home",
|
ServerChatCommand::Home => "home",
|
||||||
ServerChatCommand::JoinFaction => "join_faction",
|
ServerChatCommand::JoinFaction => "join_faction",
|
||||||
ServerChatCommand::Jump => "jump",
|
ServerChatCommand::Jump => "jump",
|
||||||
@ -817,7 +824,9 @@ impl ServerChatCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Produce an iterator over all the available commands
|
/// Produce an iterator over all the available commands
|
||||||
pub fn iter() -> impl Iterator<Item = Self> + Clone { <Self as IntoEnumIterator>::iter() }
|
pub fn iter() -> impl Iterator<Item = Self> + Clone {
|
||||||
|
<Self as IntoEnumIterator>::iter()
|
||||||
|
}
|
||||||
|
|
||||||
/// A message that explains what the command does
|
/// A message that explains what the command does
|
||||||
pub fn help_string(&self) -> String {
|
pub fn help_string(&self) -> String {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use clap::arg_enum;
|
use clap::arg_enum;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DenseVecStorage, DerefFlaggedStorage};
|
use specs::{Component, DerefFlaggedStorage, VecStorage};
|
||||||
|
|
||||||
arg_enum! {
|
arg_enum! {
|
||||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
@ -14,5 +14,5 @@ arg_enum! {
|
|||||||
pub struct Admin(pub AdminRole);
|
pub struct Admin(pub AdminRole);
|
||||||
|
|
||||||
impl Component for Admin {
|
impl Component for Admin {
|
||||||
type Storage = DerefFlaggedStorage<Self, DenseVecStorage<Self>>;
|
type Storage = DerefFlaggedStorage<Self, VecStorage<Self>>;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ use crate::{
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::Entity as EcsEntity;
|
use specs::Entity as EcsEntity;
|
||||||
use std::{collections::VecDeque, ops::DerefMut, sync::Mutex};
|
use std::{collections::VecDeque, ops::DerefMut, sync::Mutex};
|
||||||
|
use uuid::Uuid;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub type SiteId = u64;
|
pub type SiteId = u64;
|
||||||
@ -230,6 +231,7 @@ pub enum ServerEvent {
|
|||||||
MakeAdmin {
|
MakeAdmin {
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
admin: comp::Admin,
|
admin: comp::Admin,
|
||||||
|
uuid: Uuid,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,11 +124,11 @@ fn do_command(
|
|||||||
ServerChatCommand::Adminify => handle_adminify,
|
ServerChatCommand::Adminify => handle_adminify,
|
||||||
ServerChatCommand::Airship => handle_spawn_airship,
|
ServerChatCommand::Airship => handle_spawn_airship,
|
||||||
ServerChatCommand::Alias => handle_alias,
|
ServerChatCommand::Alias => handle_alias,
|
||||||
ServerChatCommand::ApplyBuff => handle_apply_buff,
|
|
||||||
ServerChatCommand::Ban => handle_ban,
|
ServerChatCommand::Ban => handle_ban,
|
||||||
ServerChatCommand::BattleMode => handle_battlemode,
|
ServerChatCommand::BattleMode => handle_battlemode,
|
||||||
ServerChatCommand::BattleModeForce => handle_battlemode_force,
|
ServerChatCommand::BattleModeForce => handle_battlemode_force,
|
||||||
ServerChatCommand::Body => handle_body,
|
ServerChatCommand::Body => handle_body,
|
||||||
|
ServerChatCommand::Buff => handle_buff,
|
||||||
ServerChatCommand::Build => handle_build,
|
ServerChatCommand::Build => handle_build,
|
||||||
ServerChatCommand::BuildAreaAdd => handle_build_area_add,
|
ServerChatCommand::BuildAreaAdd => handle_build_area_add,
|
||||||
ServerChatCommand::BuildAreaList => handle_build_area_list,
|
ServerChatCommand::BuildAreaList => handle_build_area_list,
|
||||||
@ -149,6 +149,7 @@ fn do_command(
|
|||||||
ServerChatCommand::GroupLeave => handle_group_leave,
|
ServerChatCommand::GroupLeave => handle_group_leave,
|
||||||
ServerChatCommand::GroupPromote => handle_group_promote,
|
ServerChatCommand::GroupPromote => handle_group_promote,
|
||||||
ServerChatCommand::Health => handle_health,
|
ServerChatCommand::Health => handle_health,
|
||||||
|
ServerChatCommand::Help => handle_help,
|
||||||
ServerChatCommand::Home => handle_home,
|
ServerChatCommand::Home => handle_home,
|
||||||
ServerChatCommand::JoinFaction => handle_join_faction,
|
ServerChatCommand::JoinFaction => handle_join_faction,
|
||||||
ServerChatCommand::Jump => handle_jump,
|
ServerChatCommand::Jump => handle_jump,
|
||||||
@ -1779,6 +1780,44 @@ fn handle_build_area_remove(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_help(
|
||||||
|
server: &mut Server,
|
||||||
|
client: EcsEntity,
|
||||||
|
_target: EcsEntity,
|
||||||
|
args: Vec<String>,
|
||||||
|
_action: &ServerChatCommand,
|
||||||
|
) -> CmdResult<()> {
|
||||||
|
if let Some(cmd) = parse_cmd_args!(args, ServerChatCommand) {
|
||||||
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandInfo, cmd.help_string()),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let mut message = String::new();
|
||||||
|
let entity_role = server.entity_admin_role(client);
|
||||||
|
|
||||||
|
// Iterate through all commands you have permission to use.
|
||||||
|
ServerChatCommand::iter()
|
||||||
|
.filter(|cmd| cmd.needs_role() <= entity_role)
|
||||||
|
.for_each(|cmd| {
|
||||||
|
message += &cmd.help_string();
|
||||||
|
message += "\n";
|
||||||
|
});
|
||||||
|
message += "Additionally, you can use the following shortcuts:";
|
||||||
|
ServerChatCommand::iter()
|
||||||
|
.filter_map(|cmd| cmd.short_keyword().map(|k| (k, cmd)))
|
||||||
|
.for_each(|(k, cmd)| {
|
||||||
|
message += &format!(" /{} => /{}", k, cmd.keyword());
|
||||||
|
});
|
||||||
|
|
||||||
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandInfo, message),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_alignment(owner: Uid, alignment: &str) -> CmdResult<Alignment> {
|
fn parse_alignment(owner: Uid, alignment: &str) -> CmdResult<Alignment> {
|
||||||
match alignment {
|
match alignment {
|
||||||
"wild" => Ok(Alignment::Wild),
|
"wild" => Ok(Alignment::Wild),
|
||||||
@ -3470,7 +3509,7 @@ fn handle_server_physics(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_apply_buff(
|
fn handle_buff(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
_client: EcsEntity,
|
_client: EcsEntity,
|
||||||
target: EcsEntity,
|
target: EcsEntity,
|
||||||
|
@ -11,6 +11,7 @@ use crate::{
|
|||||||
sys::terrain::SAFE_ZONE_RADIUS,
|
sys::terrain::SAFE_ZONE_RADIUS,
|
||||||
Server, SpawnPoint, StateExt,
|
Server, SpawnPoint, StateExt,
|
||||||
};
|
};
|
||||||
|
use authc::Uuid;
|
||||||
use common::{
|
use common::{
|
||||||
combat,
|
combat,
|
||||||
combat::DamageContributor,
|
combat::DamageContributor,
|
||||||
@ -1458,3 +1459,16 @@ pub fn handle_update_map_marker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_make_admin(server: &mut Server, entity: EcsEntity, admin: comp::Admin, uuid: Uuid) {
|
||||||
|
if server
|
||||||
|
.state
|
||||||
|
.read_storage::<Player>()
|
||||||
|
.get(entity)
|
||||||
|
.map_or(false, |player| player.uuid() == uuid)
|
||||||
|
{
|
||||||
|
server
|
||||||
|
.state
|
||||||
|
.write_component_ignore_entity_dead(entity, admin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,7 +13,8 @@ use entity_manipulation::{
|
|||||||
handle_aura, handle_bonk, handle_buff, handle_change_ability, handle_combo_change,
|
handle_aura, handle_bonk, handle_buff, handle_change_ability, handle_combo_change,
|
||||||
handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook,
|
handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook,
|
||||||
handle_explosion, handle_health_change, handle_knockback, handle_land_on_ground,
|
handle_explosion, handle_health_change, handle_knockback, handle_land_on_ground,
|
||||||
handle_parry_hook, handle_poise, handle_respawn, handle_teleport_to, handle_update_map_marker,
|
handle_make_admin, handle_parry_hook, handle_poise, handle_respawn, handle_teleport_to,
|
||||||
|
handle_update_map_marker,
|
||||||
};
|
};
|
||||||
use group_manip::handle_group;
|
use group_manip::handle_group;
|
||||||
use information::handle_site_info;
|
use information::handle_site_info;
|
||||||
@ -288,9 +289,11 @@ impl Server {
|
|||||||
ServerEvent::UpdateMapMarker { entity, update } => {
|
ServerEvent::UpdateMapMarker { entity, update } => {
|
||||||
handle_update_map_marker(self, entity, update)
|
handle_update_map_marker(self, entity, update)
|
||||||
},
|
},
|
||||||
ServerEvent::MakeAdmin { entity, admin } => {
|
ServerEvent::MakeAdmin {
|
||||||
let _ = self.state.ecs_mut().write_storage().insert(entity, admin);
|
entity,
|
||||||
},
|
admin,
|
||||||
|
uuid,
|
||||||
|
} => handle_make_admin(self, entity, admin, uuid),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +379,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
.into_values()
|
.into_values()
|
||||||
.map(|(entity, player, admin, msg)| {
|
.map(|(entity, player, admin, msg)| {
|
||||||
let username = &player.alias;
|
let username = &player.alias;
|
||||||
|
let uuid = player.uuid();
|
||||||
info!(?username, "New User");
|
info!(?username, "New User");
|
||||||
// Add Player component to this client.
|
// Add Player component to this client.
|
||||||
//
|
//
|
||||||
@ -396,9 +397,12 @@ impl<'a> System<'a> for Sys {
|
|||||||
// Give the Admin component to the player if their name exists in
|
// Give the Admin component to the player if their name exists in
|
||||||
// admin list
|
// admin list
|
||||||
if let Some(admin) = admin {
|
if let Some(admin) = admin {
|
||||||
|
// We need to defer writing to the Admin storage since it's borrowed immutably
|
||||||
|
// by this system via TrackedStorages.
|
||||||
event_bus.emit_now(ServerEvent::MakeAdmin {
|
event_bus.emit_now(ServerEvent::MakeAdmin {
|
||||||
entity,
|
entity,
|
||||||
admin: Admin(admin.role.into()),
|
admin: Admin(admin.role.into()),
|
||||||
|
uuid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
msg
|
msg
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
extern crate levenshtein;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
render::ExperimentalShader, session::settings_change::change_render_mode, GlobalState,
|
render::ExperimentalShader, session::settings_change::change_render_mode, GlobalState,
|
||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use common::{cmd::*, parse_cmd_args, uuid::Uuid};
|
use common::{cmd::*, comp::Admin, parse_cmd_args, uuid::Uuid};
|
||||||
use strum::IntoEnumIterator;
|
|
||||||
use common_net::synced_components::Admin;
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
use levenshtein::levenshtein;
|
use levenshtein::levenshtein;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
// Please keep this sorted alphabetically, same as with server commands :-)
|
// Please keep this sorted alphabetically, same as with server commands :-)
|
||||||
#[derive(Clone, Copy, strum::EnumIter)]
|
#[derive(Clone, Copy, strum::EnumIter)]
|
||||||
@ -38,7 +34,11 @@ impl ClientChatCommand {
|
|||||||
"Toggles an experimental shader.",
|
"Toggles an experimental shader.",
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
ClientChatCommand::Help => cmd(vec![], "", None),
|
ClientChatCommand::Help => cmd(
|
||||||
|
vec![Command(Optional)],
|
||||||
|
"Display information about commands",
|
||||||
|
None,
|
||||||
|
),
|
||||||
ClientChatCommand::Mute => cmd(
|
ClientChatCommand::Mute => cmd(
|
||||||
vec![PlayerName(Required)],
|
vec![PlayerName(Required)],
|
||||||
"Mutes chat messages from a player.",
|
"Mutes chat messages from a player.",
|
||||||
@ -93,7 +93,9 @@ impl ClientChatCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Produce an iterator over all the available commands
|
/// Produce an iterator over all the available commands
|
||||||
pub fn iter() -> impl Iterator<Item = Self> + Clone { <Self as strum::IntoEnumIterator>::iter() }
|
pub fn iter() -> impl Iterator<Item = Self> + Clone {
|
||||||
|
<Self as strum::IntoEnumIterator>::iter()
|
||||||
|
}
|
||||||
|
|
||||||
/// Produce an iterator that first goes over all the short keywords
|
/// Produce an iterator that first goes over all the short keywords
|
||||||
/// and their associated commands and then iterates over all the normal
|
/// and their associated commands and then iterates over all the normal
|
||||||
@ -160,12 +162,39 @@ pub fn run_command(
|
|||||||
Ok(ChatCommandKind::Client(cmd)) => {
|
Ok(ChatCommandKind::Client(cmd)) => {
|
||||||
Ok(Some(run_client_command(client, global_state, cmd, args)?))
|
Ok(Some(run_client_command(client, global_state, cmd, args)?))
|
||||||
},
|
},
|
||||||
Err(()) => {
|
Err(()) => Err(invalid_command_message(client, cmd.to_string())),
|
||||||
Ok(Some(handle_invalid_command(client, global_state, vec![cmd.to_string()])?))
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn invalid_command_message(client: &Client, user_entered_invalid_command: String) -> String {
|
||||||
|
let entity_role = client
|
||||||
|
.state()
|
||||||
|
.read_storage::<Admin>()
|
||||||
|
.get(client.entity())
|
||||||
|
.map(|admin| admin.0);
|
||||||
|
|
||||||
|
let usable_commands = ServerChatCommand::iter()
|
||||||
|
.filter(|cmd| cmd.needs_role() <= entity_role)
|
||||||
|
.map(|cmd| cmd.keyword())
|
||||||
|
.chain(ClientChatCommand::iter().map(|cmd| cmd.keyword()));
|
||||||
|
|
||||||
|
let most_similar_str = usable_commands
|
||||||
|
.clone()
|
||||||
|
.min_by_key(|cmd| levenshtein(&user_entered_invalid_command, cmd))
|
||||||
|
.expect("At least one command exists.");
|
||||||
|
|
||||||
|
let commands_with_same_prefix = usable_commands
|
||||||
|
.filter(|cmd| cmd.starts_with(&user_entered_invalid_command) && cmd != &most_similar_str);
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"Could not find a command named {}. Did you mean any of the following? \n/{} {} \n\nType \
|
||||||
|
/help to see a list of all commands.",
|
||||||
|
user_entered_invalid_command,
|
||||||
|
most_similar_str,
|
||||||
|
commands_with_same_prefix.fold(String::new(), |s, arg| s + "\n/" + arg)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn run_client_command(
|
fn run_client_command(
|
||||||
client: &mut Client,
|
client: &mut Client,
|
||||||
global_state: &mut GlobalState,
|
global_state: &mut GlobalState,
|
||||||
@ -174,7 +203,7 @@ fn run_client_command(
|
|||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let command = match command {
|
let command = match command {
|
||||||
ClientChatCommand::ExperimentalShader => handle_experimental_shader,
|
ClientChatCommand::ExperimentalShader => handle_experimental_shader,
|
||||||
ClientChatCommand::Help => handle_help
|
ClientChatCommand::Help => handle_help,
|
||||||
ClientChatCommand::Mute => handle_mute,
|
ClientChatCommand::Mute => handle_mute,
|
||||||
ClientChatCommand::Unmute => handle_unmute,
|
ClientChatCommand::Unmute => handle_unmute,
|
||||||
};
|
};
|
||||||
@ -197,11 +226,10 @@ fn handle_help(
|
|||||||
.get(client.entity())
|
.get(client.entity())
|
||||||
.map(|admin| admin.0);
|
.map(|admin| admin.0);
|
||||||
|
|
||||||
ClientChatCommand::iter()
|
ClientChatCommand::iter().for_each(|cmd| {
|
||||||
.for_each(|cmd| {
|
message += &cmd.help_string();
|
||||||
message += &cmd.help_string();
|
message += "\n";
|
||||||
message += "\n";
|
});
|
||||||
});
|
|
||||||
// Iterate through all ServerChatCommands you have permission to use.
|
// Iterate through all ServerChatCommands you have permission to use.
|
||||||
ServerChatCommand::iter()
|
ServerChatCommand::iter()
|
||||||
.filter(|cmd| cmd.needs_role() <= entity_role)
|
.filter(|cmd| cmd.needs_role() <= entity_role)
|
||||||
@ -211,6 +239,7 @@ fn handle_help(
|
|||||||
});
|
});
|
||||||
message += "Additionally, you can use the following shortcuts:";
|
message += "Additionally, you can use the following shortcuts:";
|
||||||
ServerChatCommand::iter()
|
ServerChatCommand::iter()
|
||||||
|
.filter(|cmd| cmd.needs_role() <= entity_role)
|
||||||
.filter_map(|cmd| cmd.short_keyword().map(|k| (k, cmd)))
|
.filter_map(|cmd| cmd.short_keyword().map(|k| (k, cmd)))
|
||||||
.for_each(|(k, cmd)| {
|
.for_each(|(k, cmd)| {
|
||||||
message += &format!(" /{} => /{}", k, cmd.keyword());
|
message += &format!(" /{} => /{}", k, cmd.keyword());
|
||||||
@ -219,43 +248,6 @@ fn handle_help(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_invalid_command(
|
|
||||||
client: &Client,
|
|
||||||
_global_state: &mut GlobalState,
|
|
||||||
args: Vec<String>,
|
|
||||||
) -> Result<String, String> {
|
|
||||||
if let Some(user_entered_invalid_command) = parse_cmd_args!(args, String) {
|
|
||||||
let entity_role = client
|
|
||||||
.state()
|
|
||||||
.read_storage::<Admin>()
|
|
||||||
.get(client.entity())
|
|
||||||
.map(|admin| admin.0);
|
|
||||||
|
|
||||||
let usable_commands = ServerChatCommand::iter()
|
|
||||||
.filter(|cmd| cmd.needs_role() <= entity_role)
|
|
||||||
.map(|cmd| cmd.keyword())
|
|
||||||
.chain(ClientChatCommand::iter().map(|cmd| cmd.keyword()));
|
|
||||||
|
|
||||||
let most_similar_str = usable_commands.clone()
|
|
||||||
.sorted_by_key(|cmd| levenshtein(&user_entered_invalid_command, cmd))
|
|
||||||
.collect::<Vec<&str>>()[0];
|
|
||||||
|
|
||||||
let commands_with_same_prefix = usable_commands
|
|
||||||
.filter(|cmd| {
|
|
||||||
cmd.starts_with(&user_entered_invalid_command) && cmd != &most_similar_str
|
|
||||||
});
|
|
||||||
|
|
||||||
return Err(format!(
|
|
||||||
"Could not find a command named {}. Did you mean any of the following? \n/{} {} \
|
|
||||||
\n\nType /help to see a list of all commands.",
|
|
||||||
user_entered_invalid_command,
|
|
||||||
most_similar_str,
|
|
||||||
commands_with_same_prefix.fold(String::new(), |s, arg| s + "\n/" + arg)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Err("Command failed parsing".to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_mute(
|
fn handle_mute(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
global_state: &mut GlobalState,
|
global_state: &mut GlobalState,
|
||||||
|
Loading…
Reference in New Issue
Block a user