limit tp command range (#1015)

* fix: /tp command server crash

Set bounds for /tp command arguments

* fix: formatting

fixed formatting

* Update teleport.rs

switched from else to return

* Update teleport.rs

Switch to is_valid method added in world

* Update mod.rs

Added is_valid_horizontally, is_valid_vertically, and is_valid functions.

* Update teleport.rs

fixed if checks

* Update mod.rs

Fixed error. switched to .contains() instead of checking bounds with >= <=

* Update mod.rs

added must use. (because of test error)

* chore: Switch to return Err() instead of manually sending error message.

* fix: formatting

* removed unused sender variables

* chore: fix formatting again
This commit is contained in:
Greened
2025-07-07 22:36:36 +04:00
committed by GitHub
parent 6461067b60
commit 46d63e9a90
2 changed files with 50 additions and 8 deletions

View File

@@ -12,6 +12,7 @@ use crate::command::args::rotation::RotationArgumentConsumer;
use crate::command::tree::CommandTree;
use crate::command::tree::builder::{argument, literal};
use crate::command::{CommandExecutor, CommandSender};
use crate::world::World;
const NAMES: [&str; 2] = ["teleport", "tp"];
const DESCRIPTION: &str = "Teleports entities, including players."; // todo
@@ -63,7 +64,11 @@ impl CommandExecutor for EntitiesToEntityExecutor {
let destination = EntityArgumentConsumer::find_arg(args, ARG_DESTINATION)?;
let pos = destination.living_entity.entity.pos.load();
if !World::is_valid(pos) {
return Err(CommandError::CommandFailed(Box::new(
TextComponent::translate("argument.pos.outofbounds", []),
)));
}
for target in targets {
let yaw = target.living_entity.entity.yaw.load();
let pitch = target.living_entity.entity.pitch.load();
@@ -87,7 +92,11 @@ impl CommandExecutor for EntitiesToPosFacingPosExecutor {
let targets = EntitiesArgumentConsumer::find_arg(args, ARG_TARGETS)?;
let pos = Position3DArgumentConsumer::find_arg(args, ARG_LOCATION)?;
if !World::is_valid(pos) {
return Err(CommandError::CommandFailed(Box::new(
TextComponent::translate("argument.pos.outofbounds", []),
)));
}
let facing_pos = Position3DArgumentConsumer::find_arg(args, ARG_FACING_LOCATION)?;
let (yaw, pitch) = yaw_pitch_facing_position(&pos, &facing_pos);
@@ -112,7 +121,11 @@ impl CommandExecutor for EntitiesToPosFacingEntityExecutor {
let targets = EntitiesArgumentConsumer::find_arg(args, ARG_TARGETS)?;
let pos = Position3DArgumentConsumer::find_arg(args, ARG_LOCATION)?;
if !World::is_valid(pos) {
return Err(CommandError::CommandFailed(Box::new(
TextComponent::translate("argument.pos.outofbounds", []),
)));
}
let facing_entity = &EntityArgumentConsumer::find_arg(args, ARG_FACING_ENTITY)?
.living_entity
.entity;
@@ -139,7 +152,11 @@ impl CommandExecutor for EntitiesToPosWithRotationExecutor {
let targets = EntitiesArgumentConsumer::find_arg(args, ARG_TARGETS)?;
let pos = Position3DArgumentConsumer::find_arg(args, ARG_LOCATION)?;
if !World::is_valid(pos) {
return Err(CommandError::CommandFailed(Box::new(
TextComponent::translate("argument.pos.outofbounds", []),
)));
}
let (yaw, pitch) = RotationArgumentConsumer::find_arg(args, ARG_ROTATION)?;
for target in targets {
@@ -163,7 +180,11 @@ impl CommandExecutor for EntitiesToPosExecutor {
let targets = EntitiesArgumentConsumer::find_arg(args, ARG_TARGETS)?;
let pos = Position3DArgumentConsumer::find_arg(args, ARG_LOCATION)?;
if !World::is_valid(pos) {
return Err(CommandError::CommandFailed(Box::new(
TextComponent::translate("argument.pos.outofbounds", []),
)));
}
for target in targets {
let yaw = target.living_entity.entity.yaw.load();
let pitch = target.living_entity.entity.pitch.load();
@@ -191,6 +212,11 @@ impl CommandExecutor for SelfToEntityExecutor {
CommandSender::Player(player) => {
let yaw = player.living_entity.entity.yaw.load();
let pitch = player.living_entity.entity.pitch.load();
if !World::is_valid(pos) {
return Err(CommandError::CommandFailed(Box::new(
TextComponent::translate("argument.pos.outofbounds", []),
)));
}
player.teleport(pos, yaw, pitch).await;
}
_ => {
@@ -203,7 +229,6 @@ impl CommandExecutor for SelfToEntityExecutor {
Ok(())
}
}
struct SelfToPosExecutor;
#[async_trait]
@@ -219,6 +244,11 @@ impl CommandExecutor for SelfToPosExecutor {
let pos = Position3DArgumentConsumer::find_arg(args, ARG_LOCATION)?;
let yaw = player.living_entity.entity.yaw.load();
let pitch = player.living_entity.entity.pitch.load();
if !World::is_valid(pos) {
return Err(CommandError::CommandFailed(Box::new(
TextComponent::translate("argument.pos.outofbounds", []),
)));
}
player.teleport(pos, yaw, pitch).await;
}
_ => {

View File

@@ -203,7 +203,7 @@ impl World {
players: Arc::new(RwLock::new(HashMap::new())),
entities: Arc::new(RwLock::new(HashMap::new())),
scoreboard: Mutex::new(Scoreboard::new()),
worldborder: Mutex::new(Worldborder::new(0.0, 0.0, 29_999_984.0, 0, 0, 0)),
worldborder: Mutex::new(Worldborder::new(0.0, 0.0, 30_000_000.0, 0, 0, 0)),
level_time: Mutex::new(LevelTime::new()),
dimension_type,
weather: Mutex::new(Weather::new()),
@@ -1983,7 +1983,19 @@ impl World {
self.broadcast_packet_all(&CWorldEvent::new(world_event as i32, position, data, false))
.await;
}
#[must_use]
pub fn is_valid(dest: Vector3<f64>) -> bool {
Self::is_valid_horizontally(dest) && Self::is_valid_vertically(dest.y)
}
#[must_use]
pub fn is_valid_horizontally(dest: Vector3<f64>) -> bool {
(-30_000_000.0..=30_000_000.0).contains(&dest.x)
&& (-30_000_000.0..=30_000_000.0).contains(&dest.z)
}
#[must_use]
pub fn is_valid_vertically(y: f64) -> bool {
(-20_000_000.0..=20_000_000.0).contains(&y)
}
/// Gets a `Block` from the block registry. Returns `Block::AIR` if the block was not found.
pub async fn get_block(&self, position: &BlockPos) -> &'static pumpkin_data::Block {
let id = self.get_block_state_id(position).await;