remove repeating command aliases in /help
This commit is contained in:
parent
5041b441eb
commit
ab8956a7b5
@ -1,6 +1,6 @@
|
|||||||
use crate::commands::dispatcher::InvalidTreeError::InvalidConsumptionError;
|
use crate::commands::dispatcher::InvalidTreeError::InvalidConsumptionError;
|
||||||
use crate::commands::dispatcher::{CommandDispatcher, InvalidTreeError};
|
use crate::commands::dispatcher::{CommandDispatcher, InvalidTreeError};
|
||||||
use crate::commands::tree::{CommandTree, ConsumedArgs, RawArgs};
|
use crate::commands::tree::{Command, CommandTree, ConsumedArgs, RawArgs};
|
||||||
use crate::commands::tree_builder::argument;
|
use crate::commands::tree_builder::argument;
|
||||||
use crate::commands::{dispatcher_init, CommandSender, DISPATCHER};
|
use crate::commands::{dispatcher_init, CommandSender, DISPATCHER};
|
||||||
use pumpkin_text::TextComponent;
|
use pumpkin_text::TextComponent;
|
||||||
@ -16,26 +16,20 @@ fn consume_arg_command(_src: &CommandSender, args: &mut RawArgs) -> Option<Strin
|
|||||||
|
|
||||||
let dispatcher = DISPATCHER.get_or_init(dispatcher_init);
|
let dispatcher = DISPATCHER.get_or_init(dispatcher_init);
|
||||||
|
|
||||||
if dispatcher.commands.contains_key(s) {
|
dispatcher.get_tree(s).ok().map(|tree| tree.names[0].into())
|
||||||
Some(s.into())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_arg_command<'a>(
|
fn parse_arg_command<'a>(
|
||||||
consumed_args: &'a ConsumedArgs,
|
consumed_args: &'a ConsumedArgs,
|
||||||
dispatcher: &'a CommandDispatcher,
|
dispatcher: &'a CommandDispatcher,
|
||||||
) -> Result<(&'a str, &'a CommandTree<'a>), InvalidTreeError> {
|
) -> Result<&'a CommandTree<'a>, InvalidTreeError> {
|
||||||
let command_name = consumed_args
|
let command_name = consumed_args
|
||||||
.get(ARG_COMMAND)
|
.get(ARG_COMMAND)
|
||||||
.ok_or(InvalidConsumptionError(None))?;
|
.ok_or(InvalidConsumptionError(None))?;
|
||||||
|
|
||||||
if let Some(tree) = dispatcher.commands.get::<&str>(&command_name.as_str()) {
|
dispatcher
|
||||||
Ok((command_name, tree))
|
.get_tree(command_name)
|
||||||
} else {
|
.map_err(|_| InvalidConsumptionError(Some(command_name.into())))
|
||||||
Err(InvalidConsumptionError(Some(command_name.into())))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> {
|
pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> {
|
||||||
@ -44,11 +38,13 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> {
|
|||||||
argument(ARG_COMMAND, consume_arg_command).execute(&|sender, args| {
|
argument(ARG_COMMAND, consume_arg_command).execute(&|sender, args| {
|
||||||
let dispatcher = DISPATCHER.get_or_init(dispatcher_init);
|
let dispatcher = DISPATCHER.get_or_init(dispatcher_init);
|
||||||
|
|
||||||
let (name, tree) = parse_arg_command(args, dispatcher)?;
|
let tree = parse_arg_command(args, dispatcher)?;
|
||||||
|
|
||||||
sender.send_message(TextComponent::text(&format!(
|
sender.send_message(TextComponent::text(&format!(
|
||||||
"{} - {} Usage: {}",
|
"{} - {} Usage: {}",
|
||||||
name, tree.description, tree
|
tree.names.join("/"),
|
||||||
|
tree.description,
|
||||||
|
tree
|
||||||
)));
|
)));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -57,15 +53,19 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> {
|
|||||||
.execute(&|sender, _args| {
|
.execute(&|sender, _args| {
|
||||||
let dispatcher = DISPATCHER.get_or_init(dispatcher_init);
|
let dispatcher = DISPATCHER.get_or_init(dispatcher_init);
|
||||||
|
|
||||||
let mut names: Vec<&str> = dispatcher.commands.keys().copied().collect();
|
let mut keys: Vec<&str> = dispatcher.commands.keys().copied().collect();
|
||||||
names.sort();
|
keys.sort();
|
||||||
|
|
||||||
for name in names {
|
for key in keys {
|
||||||
let tree = &dispatcher.commands[name];
|
let Command::Tree(tree) = &dispatcher.commands[key] else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
sender.send_message(TextComponent::text(&format!(
|
sender.send_message(TextComponent::text(&format!(
|
||||||
"{} - {} Usage: {}",
|
"{} - {} Usage: {}",
|
||||||
name, tree.description, tree
|
tree.names.join("/"),
|
||||||
|
tree.description,
|
||||||
|
tree
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::commands::dispatcher::InvalidTreeError::{
|
use crate::commands::dispatcher::InvalidTreeError::{
|
||||||
InvalidConsumptionError, InvalidRequirementError,
|
InvalidConsumptionError, InvalidRequirementError,
|
||||||
};
|
};
|
||||||
use crate::commands::tree::{CommandTree, ConsumedArgs, NodeType, RawArgs};
|
use crate::commands::tree::{Command, CommandTree, ConsumedArgs, NodeType, RawArgs};
|
||||||
use crate::commands::CommandSender;
|
use crate::commands::CommandSender;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ pub(crate) enum InvalidTreeError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct CommandDispatcher<'a> {
|
pub(crate) struct CommandDispatcher<'a> {
|
||||||
pub(crate) commands: HashMap<&'a str, CommandTree<'a>>,
|
pub(crate) commands: HashMap<&'a str, Command<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores registered [CommandTree]s and dispatches commands to them.
|
/// Stores registered [CommandTree]s and dispatches commands to them.
|
||||||
@ -28,7 +28,7 @@ impl<'a> CommandDispatcher<'a> {
|
|||||||
let key = parts.next().ok_or("Empty Command")?;
|
let key = parts.next().ok_or("Empty Command")?;
|
||||||
let raw_args: Vec<&str> = parts.rev().collect();
|
let raw_args: Vec<&str> = parts.rev().collect();
|
||||||
|
|
||||||
let tree = self.commands.get(key).ok_or("Command not found")?;
|
let tree = self.get_tree(key)?;
|
||||||
|
|
||||||
// try paths until fitting path is found
|
// try paths until fitting path is found
|
||||||
for path in tree.iter_paths() {
|
for path in tree.iter_paths() {
|
||||||
@ -52,6 +52,21 @@ impl<'a> CommandDispatcher<'a> {
|
|||||||
Err(format!("Invalid Syntax. Usage: {}", tree))
|
Err(format!("Invalid Syntax. Usage: {}", tree))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_tree(&'a self, key: &str) -> Result<&'a CommandTree<'a>, String> {
|
||||||
|
let command = self.commands.get(key).ok_or("Command not found")?;
|
||||||
|
|
||||||
|
match command {
|
||||||
|
Command::Tree(tree) => Ok(tree),
|
||||||
|
Command::Alias(target) => {
|
||||||
|
let Some(Command::Tree(tree)) = &self.commands.get(target) else {
|
||||||
|
println!("Error while parsing command alias \"{key}\": pointing to \"{target}\" which is not a valid tree");
|
||||||
|
return Err("Internal Error (See logs for details)".into());
|
||||||
|
};
|
||||||
|
Ok(tree)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn try_is_fitting_path(
|
fn try_is_fitting_path(
|
||||||
src: &mut CommandSender,
|
src: &mut CommandSender,
|
||||||
path: Vec<usize>,
|
path: Vec<usize>,
|
||||||
@ -104,9 +119,9 @@ impl<'a> CommandDispatcher<'a> {
|
|||||||
let primary_name = names.next().expect("at least one name must be provided");
|
let primary_name = names.next().expect("at least one name must be provided");
|
||||||
|
|
||||||
for &name in names {
|
for &name in names {
|
||||||
self.commands.insert(name, tree.clone());
|
self.commands.insert(name, Command::Alias(primary_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.commands.insert(primary_name, tree);
|
self.commands.insert(primary_name, Command::Tree(tree));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,13 +12,11 @@ pub(crate) type ConsumedArgs<'a> = HashMap<&'a str, String>;
|
|||||||
/// see [crate::commands::tree_builder::argument]
|
/// see [crate::commands::tree_builder::argument]
|
||||||
pub(crate) type ArgumentConsumer<'a> = fn(&CommandSender, &mut RawArgs) -> Option<String>;
|
pub(crate) type ArgumentConsumer<'a> = fn(&CommandSender, &mut RawArgs) -> Option<String>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub(crate) struct Node<'a> {
|
pub(crate) struct Node<'a> {
|
||||||
pub(crate) children: Vec<usize>,
|
pub(crate) children: Vec<usize>,
|
||||||
pub(crate) node_type: NodeType<'a>,
|
pub(crate) node_type: NodeType<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub(crate) enum NodeType<'a> {
|
pub(crate) enum NodeType<'a> {
|
||||||
ExecuteLeaf {
|
ExecuteLeaf {
|
||||||
run: &'a (dyn Fn(&mut CommandSender, &ConsumedArgs) -> Result<(), InvalidTreeError> + Sync),
|
run: &'a (dyn Fn(&mut CommandSender, &ConsumedArgs) -> Result<(), InvalidTreeError> + Sync),
|
||||||
@ -34,7 +32,11 @@ pub(crate) enum NodeType<'a> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub(crate) enum Command<'a> {
|
||||||
|
Tree(CommandTree<'a>),
|
||||||
|
Alias(&'a str),
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct CommandTree<'a> {
|
pub(crate) struct CommandTree<'a> {
|
||||||
pub(crate) nodes: Vec<Node<'a>>,
|
pub(crate) nodes: Vec<Node<'a>>,
|
||||||
pub(crate) children: Vec<usize>,
|
pub(crate) children: Vec<usize>,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user