Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make command dispatcher mutable #405

Merged
merged 1 commit into from
Dec 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions pumpkin/src/command/args/arg_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ impl ArgumentConsumer for CommandTreeArgumentConsumer {
) -> Option<Arg<'a>> {
let s = args.pop()?;

let dispatcher = &server.command_dispatcher;
return dispatcher
let dispatcher = server.command_dispatcher.read().await;
dispatcher
.get_tree(s)
.map_or_else(|_| None, |tree| Some(Arg::CommandTree(tree)));
.map_or_else(|_| None, |tree| Some(Arg::CommandTree(tree)))
}

async fn suggest<'a>(
Expand All @@ -53,8 +53,8 @@ impl ArgumentConsumer for CommandTreeArgumentConsumer {
return Ok(None);
};

let suggestions = server
.command_dispatcher
let dispatcher = server.command_dispatcher.read().await;
let suggestions = dispatcher
.commands
.keys()
.filter(|suggestion| suggestion.starts_with(input))
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/command/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub(crate) enum Arg<'a> {
Pos2D(Vector2<f64>),
Rotation(f32, f32),
GameMode(GameMode),
CommandTree(&'a CommandTree<'a>),
CommandTree(CommandTree<'a>),
Item(&'a str),
ResourceLocation(&'a str),
Block(&'a str),
Expand Down
8 changes: 5 additions & 3 deletions pumpkin/src/command/client_cmd_suggestions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync::Arc;

use pumpkin_protocol::client::play::{CCommands, ProtoNode, ProtoNodeType};
use tokio::sync::RwLock;

use crate::entity::player::Player;

Expand All @@ -11,11 +12,12 @@ use super::{

pub async fn send_c_commands_packet<'a>(
player: &Arc<Player>,
dispatcher: &'a CommandDispatcher<'a>,
dispatcher: &RwLock<CommandDispatcher<'a>>,
) {
let cmd_src = super::CommandSender::Player(player.clone());
let mut first_level = Vec::new();

let dispatcher = dispatcher.read().await;
for key in dispatcher.commands.keys() {
let Ok(tree) = dispatcher.get_tree(key) else {
continue;
Expand Down Expand Up @@ -72,8 +74,8 @@ impl<'a> ProtoNodeBuilder<'a> {

fn nodes_to_proto_node_builders<'a>(
cmd_src: &super::CommandSender,
nodes: &'a [Node<'a>],
children: &'a [usize],
nodes: &[Node<'a>],
children: &[usize],
) -> (bool, Vec<ProtoNodeBuilder<'a>>) {
let mut child_nodes = Vec::new();
let mut is_executable = false;
Expand Down
4 changes: 2 additions & 2 deletions pumpkin/src/command/commands/cmd_help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ impl CommandExecutor for BaseHelpExecutor {
}
};

let mut commands: Vec<&CommandTree> = server
.command_dispatcher
let dispatcher = server.command_dispatcher.read().await;
let mut commands: Vec<&CommandTree> = dispatcher
.commands
.values()
.filter_map(|cmd| match cmd {
Expand Down
24 changes: 18 additions & 6 deletions pumpkin/src/command/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl<'a> CommandDispatcher<'a> {
// try paths and collect the nodes that fail
// todo: make this more fine-grained
for path in tree.iter_paths() {
match Self::try_find_suggestions_on_path(src, server, &path, tree, &mut raw_args, cmd)
match Self::try_find_suggestions_on_path(src, server, &path, &tree, &mut raw_args, cmd)
.await
{
Err(InvalidConsumption(s)) => {
Expand Down Expand Up @@ -151,7 +151,7 @@ impl<'a> CommandDispatcher<'a> {

// try paths until fitting path is found
for path in tree.iter_paths() {
if Self::try_is_fitting_path(src, server, &path, tree, &mut raw_args.clone()).await? {
if Self::try_is_fitting_path(src, server, &path, &tree, &mut raw_args.clone()).await? {
return Ok(());
}
}
Expand All @@ -160,22 +160,22 @@ impl<'a> CommandDispatcher<'a> {
)))
}

pub(crate) fn get_tree(&'a self, key: &str) -> Result<&'a CommandTree<'a>, CommandError> {
pub(crate) fn get_tree(&self, key: &str) -> Result<CommandTree<'a>, CommandError> {
let command = self
.commands
.get(key)
.ok_or(GeneralCommandIssue("Command not found".to_string()))?;

match command {
Command::Tree(tree) => Ok(tree),
Command::Tree(tree) => Ok(tree.clone()),
Command::Alias(target) => {
let Some(Command::Tree(tree)) = &self.commands.get(target) else {
let Some(Command::Tree(tree)) = self.commands.get(target) else {
log::error!("Error while parsing command alias \"{key}\": pointing to \"{target}\" which is not a valid tree");
return Err(GeneralCommandIssue(
"Internal Error (See logs for details)".into(),
));
};
Ok(tree)
Ok(tree.clone())
}
}
}
Expand Down Expand Up @@ -282,3 +282,15 @@ impl<'a> CommandDispatcher<'a> {
self.commands.insert(primary_name, Command::Tree(tree));
}
}

#[cfg(test)]
mod test {
use crate::command::{default_dispatcher, tree::CommandTree};

#[test]
fn test_dynamic_command() {
let mut dispatcher = default_dispatcher();
let tree = CommandTree::new(["test"], "test_desc");
dispatcher.register(tree);
}
}
4 changes: 2 additions & 2 deletions pumpkin/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<'a> CommandSender<'a> {
}

#[must_use]
pub fn default_dispatcher<'a>() -> Arc<CommandDispatcher<'a>> {
pub fn default_dispatcher<'a>() -> CommandDispatcher<'a> {
let mut dispatcher = CommandDispatcher::default();

dispatcher.register(cmd_pumpkin::init_command_tree());
Expand All @@ -129,7 +129,7 @@ pub fn default_dispatcher<'a>() -> Arc<CommandDispatcher<'a>> {
dispatcher.register(cmd_transfer::init_command_tree());
dispatcher.register(cmd_fill::init_command_tree());

Arc::new(dispatcher)
dispatcher
}

#[async_trait]
Expand Down
5 changes: 3 additions & 2 deletions pumpkin/src/command/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ use std::{collections::VecDeque, fmt::Debug};
/// see [`crate::commands::tree_builder::argument`]
pub type RawArgs<'a> = Vec<&'a str>;

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Node<'a> {
pub(crate) children: Vec<usize>,
pub(crate) node_type: NodeType<'a>,
}

#[derive(Clone)]
pub enum NodeType<'a> {
ExecuteLeaf {
executor: &'a dyn CommandExecutor,
Expand Down Expand Up @@ -50,7 +51,7 @@ pub enum Command<'a> {
Alias(&'a str),
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct CommandTree<'a> {
pub(crate) nodes: Vec<Node<'a>>,
pub(crate) children: Vec<usize>,
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ fn setup_console(server: Arc<Server>) {
.expect("Failed to read console line");

if !out.is_empty() {
let dispatcher = server.command_dispatcher.clone();
let dispatcher = server.command_dispatcher.read().await;
dispatcher
.handle_command(&mut command::CommandSender::Console, &server, &out)
.await;
Expand Down
8 changes: 3 additions & 5 deletions pumpkin/src/net/packet/play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ impl Player {
server: &Arc<Server>,
command: SChatCommand,
) {
let dispatcher = server.command_dispatcher.clone();
let dispatcher = server.command_dispatcher.read().await;
dispatcher
.handle_command(
&mut CommandSender::Player(self.clone()),
Expand Down Expand Up @@ -877,10 +877,8 @@ impl Player {
return;
};

let suggestions = server
.command_dispatcher
.find_suggestions(&mut src, server, cmd)
.await;
let dispatcher = server.command_dispatcher.read().await;
let suggestions = dispatcher.find_suggestions(&mut src, server, cmd).await;

let response = CCommandSuggestions::new(
packet.id,
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/net/rcon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl RCONClient {
ServerboundPacket::ExecCommand => {
if self.logged_in {
let output = tokio::sync::Mutex::new(Vec::new());
let dispatcher = server.command_dispatcher.clone();
let dispatcher = server.command_dispatcher.read().await;
dispatcher
.handle_command(
&mut crate::command::CommandSender::Rcon(&output),
Expand Down
4 changes: 2 additions & 2 deletions pumpkin/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub struct Server {
/// Saves server branding information.
server_branding: CachedBranding,
/// Saves and Dispatches commands to appropriate handlers.
pub command_dispatcher: Arc<CommandDispatcher<'static>>,
pub command_dispatcher: RwLock<CommandDispatcher<'static>>,
/// Saves and calls blocks blocks
pub block_manager: Arc<BlockManager>,
/// Manages multiple worlds within the server.
Expand Down Expand Up @@ -79,7 +79,7 @@ impl Server {
});

// First register default command, after that plugins can put in their own
let command_dispatcher = default_dispatcher();
let command_dispatcher = RwLock::new(default_dispatcher());

let world = World::load(
Dimension::OverWorld.into_level(
Expand Down
4 changes: 1 addition & 3 deletions pumpkin/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ impl World {
player: Arc<Player>,
server: &Server,
) {
let command_dispatcher = &server.command_dispatcher;
let dimensions: Vec<Identifier> =
server.dimensions.iter().map(DimensionType::name).collect();

Expand Down Expand Up @@ -270,8 +269,7 @@ impl World {
.await;
// permissions, i. e. the commands a player may use
player.send_permission_lvl_update().await;
client_cmd_suggestions::send_c_commands_packet(&player, command_dispatcher).await;

client_cmd_suggestions::send_c_commands_packet(&player, &server.command_dispatcher).await;
// teleport
let mut position = Vector3::new(10.0, 120.0, 10.0);
let yaw = 10.0;
Expand Down
Loading