Skip to content

Commit

Permalink
Fix players timing out after a command executes for a while (#460)
Browse files Browse the repository at this point in the history
* Fix players not being removed from world on timeout

* Spawn new task for each command
Undo bandaid fix

* Fix cargo fmt

* Move console commands and RCON commands into seperate tokio task
  • Loading branch information
neeleshpoli authored Jan 10, 2025
1 parent 9964972 commit 7885da7
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 28 deletions.
3 changes: 1 addition & 2 deletions pumpkin/src/entity/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,8 +719,7 @@ impl Player {
.await;
}
SChatCommand::PACKET_ID => {
self.handle_chat_command(server, SChatCommand::read(bytebuf)?)
.await;
self.handle_chat_command(server, &(SChatCommand::read(bytebuf)?));
}
SChatMessage::PACKET_ID => {
self.handle_chat_message(SChatMessage::read(bytebuf)?).await;
Expand Down
11 changes: 7 additions & 4 deletions pumpkin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,13 @@ fn setup_console(server: Arc<Server>) {
.expect("Failed to read console line");

if !out.is_empty() {
let dispatcher = server.command_dispatcher.read().await;
dispatcher
.handle_command(&mut command::CommandSender::Console, &server, &out)
.await;
let server_clone = server.clone();
tokio::spawn(async move {
let dispatcher = server_clone.command_dispatcher.read().await;
dispatcher
.handle_command(&mut command::CommandSender::Console, &server_clone, &out)
.await;
});
}
}
});
Expand Down
30 changes: 17 additions & 13 deletions pumpkin/src/net/packet/play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,19 +300,23 @@ impl Player {
.await;
}

pub async fn handle_chat_command(
self: &Arc<Self>,
server: &Arc<Server>,
command: SChatCommand,
) {
let dispatcher = server.command_dispatcher.read().await;
dispatcher
.handle_command(
&mut CommandSender::Player(self.clone()),
server,
&command.command,
)
.await;
pub fn handle_chat_command(self: &Arc<Self>, server: &Arc<Server>, command: &SChatCommand) {
let player_clone = self.clone();
let server_clone = server.clone();
let command_clone = command.command.clone();
// Some commands can take a long time to execute. If they do, they block packet processing for the player
// Thats why we will spawn a task instead
tokio::spawn(async move {
let dispatcher = server_clone.command_dispatcher.read().await;
dispatcher
.handle_command(
&mut CommandSender::Player(player_clone),
&server_clone,
&command_clone,
)
.await;
});

if ADVANCED_CONFIG.commands.log_console {
log::info!(
"Player ({}): executed command /{}",
Expand Down
25 changes: 16 additions & 9 deletions pumpkin/src/net/rcon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,22 @@ impl RCONClient {
}
ServerboundPacket::ExecCommand => {
if self.logged_in {
let output = tokio::sync::Mutex::new(Vec::new());
let dispatcher = server.command_dispatcher.read().await;
dispatcher
.handle_command(
&mut crate::command::CommandSender::Rcon(&output),
server,
packet.get_body(),
)
.await;
let output = Arc::new(tokio::sync::Mutex::new(Vec::new()));

let server_clone = server.clone();
let output_clone = output.clone();
let packet_body = packet.get_body().to_owned();
tokio::spawn(async move {
let dispatcher = server_clone.command_dispatcher.read().await;
dispatcher
.handle_command(
&mut crate::command::CommandSender::Rcon(&output_clone),
&server_clone,
&packet_body,
)
.await;
});

let output = output.lock().await;
for line in output.iter() {
if config.logging.log_commands {
Expand Down

0 comments on commit 7885da7

Please sign in to comment.