From ff66c7fa2afb78fa3885ced4664b23e282ec0f1c Mon Sep 17 00:00:00 2001 From: QiuHu <74653499+2982136527@users.noreply.github.com> Date: Sat, 15 Aug 2026 16:10:51 +0800 Subject: [PATCH] fix(command): send success message after teleport (#2921) * fix(command): send success message after teleport All seven executors in teleport.rs performed the teleport but never sent a feedback message to the command sender. Send the existing success translation keys (entity/location, single/multiple) via sender.send_message. Fixes #2920 * fix(command): elide needless lifetime in tp success helper * fix(command): add bedrock translations for tp success message --- .../pumpkin/src/command/commands/teleport.rs | 130 +++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/crates/pumpkin/src/command/commands/teleport.rs b/crates/pumpkin/src/command/commands/teleport.rs index 8f8d518bb..6d78cb933 100644 --- a/crates/pumpkin/src/command/commands/teleport.rs +++ b/crates/pumpkin/src/command/commands/teleport.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use pumpkin_data::translation; use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::vector3::Vector3; @@ -62,12 +64,24 @@ fn resolve_sender_world( .expect("Server should have at least one world") } +async fn success_key_and_arg( + targets: &[Arc], + single_key: &'static str, + multiple_key: &'static str, +) -> (&'static str, TextComponent) { + if targets.len() == 1 { + (single_key, targets[0].get_display_name().await) + } else { + (multiple_key, TextComponent::text(targets.len().to_string())) + } +} + struct EntitiesToEntityExecutor; impl CommandExecutor for EntitiesToEntityExecutor { fn execute<'a>( &'a self, - _sender: &'a CommandSender, + sender: &'a CommandSender, _server: &'a crate::server::Server, args: &'a ConsumedArgs<'a>, ) -> CommandResult<'a> { @@ -94,6 +108,20 @@ impl CommandExecutor for EntitiesToEntityExecutor { .await; } + let (key, target_arg) = success_key_and_arg( + targets, + translation::java::COMMANDS_TELEPORT_SUCCESS_ENTITY_SINGLE, + translation::java::COMMANDS_TELEPORT_SUCCESS_ENTITY_MULTIPLE, + ) + .await; + sender + .send_message(TextComponent::translate_cross( + key, + translation::bedrock::COMMANDS_TP_SUCCESSVICTIM, + [target_arg, destination.get_display_name().await], + )) + .await; + Ok(targets.len() as i32) }) } @@ -130,6 +158,25 @@ impl CommandExecutor for EntitiesToPosFacingPosExecutor { .await; } + let (key, target_arg) = success_key_and_arg( + targets, + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_SINGLE, + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_MULTIPLE, + ) + .await; + sender + .send_message(TextComponent::translate_cross( + key, + translation::bedrock::COMMANDS_TP_SUCCESS_COORDINATES, + [ + target_arg, + TextComponent::text(pos.x.to_string()), + TextComponent::text(pos.y.to_string()), + TextComponent::text(pos.z.to_string()), + ], + )) + .await; + Ok(targets.len() as i32) }) } @@ -167,6 +214,25 @@ impl CommandExecutor for EntitiesToPosFacingEntityExecutor { .await; } + let (key, target_arg) = success_key_and_arg( + targets, + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_SINGLE, + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_MULTIPLE, + ) + .await; + sender + .send_message(TextComponent::translate_cross( + key, + translation::bedrock::COMMANDS_TP_SUCCESS_COORDINATES, + [ + target_arg, + TextComponent::text(pos.x.to_string()), + TextComponent::text(pos.y.to_string()), + TextComponent::text(pos.z.to_string()), + ], + )) + .await; + Ok(targets.len() as i32) }) } @@ -204,6 +270,25 @@ impl CommandExecutor for EntitiesToPosWithRotationExecutor { .await; } + let (key, target_arg) = success_key_and_arg( + targets, + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_SINGLE, + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_MULTIPLE, + ) + .await; + sender + .send_message(TextComponent::translate_cross( + key, + translation::bedrock::COMMANDS_TP_SUCCESS_COORDINATES, + [ + target_arg, + TextComponent::text(pos.x.to_string()), + TextComponent::text(pos.y.to_string()), + TextComponent::text(pos.z.to_string()), + ], + )) + .await; + Ok(targets.len() as i32) }) } @@ -239,6 +324,25 @@ impl CommandExecutor for EntitiesToPosExecutor { .await; } + let (key, target_arg) = success_key_and_arg( + targets, + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_SINGLE, + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_MULTIPLE, + ) + .await; + sender + .send_message(TextComponent::translate_cross( + key, + translation::bedrock::COMMANDS_TP_SUCCESS_COORDINATES, + [ + target_arg, + TextComponent::text(pos.x.to_string()), + TextComponent::text(pos.y.to_string()), + TextComponent::text(pos.z.to_string()), + ], + )) + .await; + Ok(targets.len() as i32) }) } @@ -275,6 +379,17 @@ impl CommandExecutor for SelfToEntityExecutor { .teleport(pos, Some(yaw), Some(pitch), world) .await; + sender + .send_message(TextComponent::translate_cross( + translation::java::COMMANDS_TELEPORT_SUCCESS_ENTITY_SINGLE, + translation::bedrock::COMMANDS_TP_SUCCESSVICTIM, + [ + player.get_display_name().await, + destination.get_display_name().await, + ], + )) + .await; + Ok(1) } _ => Err(CommandError::CommandFailed(TextComponent::translate_cross( @@ -313,6 +428,19 @@ impl CommandExecutor for SelfToPosExecutor { .teleport(pos, Some(yaw), Some(pitch), player.world().clone()) .await; + sender + .send_message(TextComponent::translate_cross( + translation::java::COMMANDS_TELEPORT_SUCCESS_LOCATION_SINGLE, + translation::bedrock::COMMANDS_TP_SUCCESS_COORDINATES, + [ + player.get_display_name().await, + TextComponent::text(pos.x.to_string()), + TextComponent::text(pos.y.to_string()), + TextComponent::text(pos.z.to_string()), + ], + )) + .await; + Ok(1) } _ => Err(CommandError::CommandFailed(TextComponent::translate_cross(