chore: update to latest build

This commit is contained in:
Alexander Medvedev 2026-08-27 11:31:28 +02:00
parent 46d7ee1be2
commit 4ba797cca2
10 changed files with 358 additions and 391 deletions

30
rust/Cargo.lock generated
View File

@ -696,9 +696,9 @@ dependencies = [
[[package]] [[package]]
name = "combine" name = "combine"
version = "4.6.7" version = "4.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e"
dependencies = [ dependencies = [
"bytes", "bytes",
"memchr", "memchr",
@ -3512,7 +3512,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin" name = "pumpkin"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"aes 0.9.2", "aes 0.9.2",
"arc-swap", "arc-swap",
@ -3578,7 +3578,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-api-macros" name = "pumpkin-api-macros"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"proc-macro-error2", "proc-macro-error2",
"proc-macro2", "proc-macro2",
@ -3589,7 +3589,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-codecs" name = "pumpkin-codecs"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"serde_json", "serde_json",
"tracing", "tracing",
@ -3598,7 +3598,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-config" name = "pumpkin-config"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"pumpkin-util", "pumpkin-util",
"serde", "serde",
@ -3610,7 +3610,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-data" name = "pumpkin-data"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"crc-fast", "crc-fast",
"phf", "phf",
@ -3623,7 +3623,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-inventory" name = "pumpkin-inventory"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"pumpkin-data", "pumpkin-data",
"pumpkin-protocol", "pumpkin-protocol",
@ -3638,7 +3638,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-macros" name = "pumpkin-macros"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error2", "proc-macro-error2",
@ -3651,7 +3651,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-nbt" name = "pumpkin-nbt"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"bytes", "bytes",
"cesu8", "cesu8",
@ -3665,7 +3665,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-protocol" name = "pumpkin-protocol"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"aes 0.9.2", "aes 0.9.2",
"async-compression", "async-compression",
@ -3690,7 +3690,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-util" name = "pumpkin-util"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"base64 0.23.1", "base64 0.23.1",
"bytes", "bytes",
@ -3716,7 +3716,7 @@ dependencies = [
[[package]] [[package]]
name = "pumpkin-world" name = "pumpkin-world"
version = "0.1.0-dev+26.2-26.40" version = "0.1.0-dev+26.2-26.40"
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#d8c7c23c0bd547a72dc3df84c5e2855aba975cf8" source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#3d69190a3766fd901adc6023f1c1c399d7e591bf"
dependencies = [ dependencies = [
"arc-swap", "arc-swap",
"bitflags 2.13.1", "bitflags 2.13.1",
@ -5359,9 +5359,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.25.0" version = "1.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" checksum = "b5772d71c9be8a8a6ac2117d949c5b224c1b72241bb611d9a3012edcf8af7812"
dependencies = [ dependencies = [
"getrandom 0.4.3", "getrandom 0.4.3",
"js-sys", "js-sys",

View File

@ -50,27 +50,23 @@ impl ArgumentConsumer for AnyCommandNode {
_server: &'a pumpkin::server::Server, _server: &'a pumpkin::server::Server,
args: &mut pumpkin::command::tree::RawArgs<'a>, args: &mut pumpkin::command::tree::RawArgs<'a>,
) -> pumpkin::command::args::ConsumeResult<'a> { ) -> pumpkin::command::args::ConsumeResult<'a> {
let first_word_opt = args.pop(); let first_word = args.pop()?;
let mut msg = first_word.value.to_string();
let mut msg = match first_word_opt {
Some(word) => word.value.to_string(),
None => return Box::pin(async { None }),
};
while let Some(word) = args.pop() { while let Some(word) = args.pop() {
msg.push(' '); msg.push(' ');
msg.push_str(word.value); msg.push_str(word.value);
} }
Box::pin(async move { Some(Arg::Msg(msg)) }) Some(Arg::Msg(msg))
} }
fn suggest<'a>( fn suggest(
&'a self, &self,
sender: &pumpkin::command::CommandSender, sender: &pumpkin::command::CommandSender,
_server: &'a pumpkin::server::Server, _server: &pumpkin::server::Server,
input: &'a str, input: &str,
) -> SuggestResult<'a> { ) -> SuggestResult {
let location = if let Some(position) = sender.position() let location = if let Some(position) = sender.position()
&& let Some(world) = sender.world() && let Some(world) = sender.world()
{ {
@ -92,7 +88,9 @@ impl ArgumentConsumer for AnyCommandNode {
let command_sender: SimpleCommandSender = sender.into(); let command_sender: SimpleCommandSender = sender.into();
Box::pin(async move { if let Ok(handle) = tokio::runtime::Handle::try_current() {
tokio::task::block_in_place(|| {
handle.block_on(async move {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
if let Err(e) = self if let Err(e) = self
.command_tx .command_tx
@ -113,6 +111,27 @@ impl ArgumentConsumer for AnyCommandNode {
Err(_) => Ok(None), Err(_) => Ok(None),
} }
}) })
})
} else {
let (tx, rx) = oneshot::channel();
if let Err(e) = self
.command_tx
.blocking_send(JvmCommand::GetCommandTabComplete {
command_sender,
full_command: input.to_string(),
respond_to: tx,
location,
})
{
tracing::warn!("Failed to send tab complete to JVM worker: {e}");
return Ok(None);
}
match rx.blocking_recv() {
Ok(res) => res,
Err(_) => Ok(None),
}
}
} }
} }
@ -135,17 +154,16 @@ impl From<&CommandSender> for SimpleCommandSender {
} }
impl CommandExecutor for JavaCommandExecutor { impl CommandExecutor for JavaCommandExecutor {
fn execute<'a>( fn execute(
&'a self, &self,
sender: &'a pumpkin::command::CommandSender, sender: &pumpkin::command::CommandSender,
_server: &'a pumpkin::server::Server, _server: &pumpkin::server::Server,
args: &'a pumpkin::command::args::ConsumedArgs<'a>, args: &pumpkin::command::args::ConsumedArgs,
) -> pumpkin::command::CommandResult<'a> { ) -> pumpkin::command::CommandResult {
if let CommandSender::Player(player) = sender { if let CommandSender::Player(player) = sender {
crate::java::native_callbacks::utils::cache_player(player.clone()); crate::java::native_callbacks::utils::cache_player(player.clone());
} }
Box::pin(async move {
let full_command = match args.get(ARG_ANY) { let full_command = match args.get(ARG_ANY) {
Some(Arg::Msg(msg)) => { Some(Arg::Msg(msg)) => {
if self.cmd_name.starts_with('/') { if self.cmd_name.starts_with('/') {
@ -163,13 +181,18 @@ impl CommandExecutor for JavaCommandExecutor {
} }
}; };
let command_sender: SimpleCommandSender = sender.into();
if let Ok(handle) = tokio::runtime::Handle::try_current() {
tokio::task::block_in_place(|| {
handle.block_on(async move {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
if let Err(e) = self if let Err(e) = self
.command_tx .command_tx
.send(JvmCommand::TriggerCommand { .send(JvmCommand::TriggerCommand {
full_command, full_command,
respond_to: tx, respond_to: tx,
command_sender: sender.into(), command_sender,
}) })
.await .await
{ {
@ -180,6 +203,21 @@ impl CommandExecutor for JavaCommandExecutor {
let _ = rx.await; let _ = rx.await;
Ok(1) Ok(1)
}) })
})
} else {
let (tx, rx) = oneshot::channel();
if let Err(e) = self.command_tx.blocking_send(JvmCommand::TriggerCommand {
full_command,
respond_to: tx,
command_sender,
}) {
tracing::error!("Failed to send command to JVM worker: {e}");
return Ok(0);
}
let _ = rx.blocking_recv();
Ok(1)
}
} }
} }

View File

@ -1,4 +1,4 @@
use crate::java::native_callbacks::{CALLBACK_CONTEXT, utils::with_player}; use crate::java::native_callbacks::utils::with_player;
use crate::proto::patchbukkit::{ use crate::proto::patchbukkit::{
abilities::{Abilities, SetAbilitiesRequest}, abilities::{Abilities, SetAbilitiesRequest},
common::Uuid, common::Uuid,
@ -50,13 +50,13 @@ pub fn ffi_native_bridge_get_abilities_impl(request: Uuid) -> Option<Abilities>
} }
pub fn ffi_native_bridge_set_abilities_impl(request: SetAbilitiesRequest) -> Option<bool> { pub fn ffi_native_bridge_set_abilities_impl(request: SetAbilitiesRequest) -> Option<bool> {
let ctx = CALLBACK_CONTEXT.get()?;
let abilities = request.abilities?; let abilities = request.abilities?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let player = player.clone();
ctx.runtime.spawn(async move {
{ {
let mut pumpkin_abilities = player.abilities.lock().await; let mut pumpkin_abilities = player
.abilities
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
pumpkin_abilities.invulnerable = abilities.invulnerable; pumpkin_abilities.invulnerable = abilities.invulnerable;
pumpkin_abilities.flying = abilities.flying; pumpkin_abilities.flying = abilities.flying;
pumpkin_abilities.allow_flying = abilities.allow_flying; pumpkin_abilities.allow_flying = abilities.allow_flying;
@ -65,8 +65,7 @@ pub fn ffi_native_bridge_set_abilities_impl(request: SetAbilitiesRequest) -> Opt
pumpkin_abilities.fly_speed = abilities.fly_speed; pumpkin_abilities.fly_speed = abilities.fly_speed;
pumpkin_abilities.walk_speed = abilities.walk_speed; pumpkin_abilities.walk_speed = abilities.walk_speed;
} }
player.send_abilities_update().await; player.send_abilities_update();
});
Some(true) Some(true)
})? })?

View File

@ -62,9 +62,7 @@ pub fn ffi_native_bridge_register_command_impl(request: RegisterCommandRequest)
tracing::debug!("Permission '{}' registration notice: {}", permission, e); tracing::debug!("Permission '{}' registration notice: {}", permission, e);
} }
plugin_context plugin_context.register_command(node, permission.clone());
.register_command(node, permission.clone())
.await;
tracing::info!( tracing::info!(
"Successfully registered command '{}' with names {:?} and permission '{}'", "Successfully registered command '{}' with names {:?} and permission '{}'",

View File

@ -33,25 +33,17 @@ pub fn ffi_native_bridge_get_entity_health_impl(request: Uuid) -> Option<EntityH
} }
pub fn ffi_native_bridge_set_entity_health_impl(request: SetEntityHealthRequest) -> Option<()> { pub fn ffi_native_bridge_set_entity_health_impl(request: SetEntityHealthRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let health = request.health as f32; let health = request.health as f32;
let player = player.clone(); player.set_health(health);
ctx.runtime.spawn(async move {
player.set_health(health).await;
});
}) })
} }
pub fn ffi_native_bridge_damage_entity_impl(request: DamageEntityRequest) -> Option<()> { pub fn ffi_native_bridge_damage_entity_impl(request: DamageEntityRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let amount = request.amount as f32; let amount = request.amount as f32;
let player = player.clone();
ctx.runtime.spawn(async move {
let current = player.living_entity.health.load(); let current = player.living_entity.health.load();
player.set_health((current - amount).max(0.0)).await; player.set_health((current - amount).max(0.0));
});
}) })
} }
@ -95,14 +87,10 @@ pub fn ffi_native_bridge_get_gamemode_impl(
pub fn ffi_native_bridge_set_gamemode_impl( pub fn ffi_native_bridge_set_gamemode_impl(
request: crate::proto::patchbukkit::entity::SetGamemodeRequest, request: crate::proto::patchbukkit::entity::SetGamemodeRequest,
) -> Option<()> { ) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let gamemode_val = request.gamemode as i8; let gamemode_val = request.gamemode as i8;
if let Ok(gamemode) = pumpkin_util::gamemode::GameMode::try_from(gamemode_val) { if let Ok(gamemode) = pumpkin_util::gamemode::GameMode::try_from(gamemode_val) {
let player = player.clone(); player.set_gamemode(gamemode);
ctx.runtime.spawn(async move {
player.set_gamemode(gamemode).await;
});
} }
}) })
} }
@ -211,26 +199,18 @@ pub fn ffi_native_bridge_get_food_level_impl(request: Uuid) -> Option<GetFoodLev
} }
pub fn ffi_native_bridge_set_food_level_impl(request: SetFoodLevelRequest) -> Option<()> { pub fn ffi_native_bridge_set_food_level_impl(request: SetFoodLevelRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let food_level = request.food_level as u8; let food_level = request.food_level as u8;
let player = player.clone();
ctx.runtime.spawn(async move {
player.hunger_manager.set_level(food_level); player.hunger_manager.set_level(food_level);
player.send_health().await; player.send_health();
});
}) })
} }
pub fn ffi_native_bridge_set_saturation_impl(request: SetSaturationRequest) -> Option<()> { pub fn ffi_native_bridge_set_saturation_impl(request: SetSaturationRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let saturation = request.saturation; let saturation = request.saturation;
let player = player.clone();
ctx.runtime.spawn(async move {
player.hunger_manager.set_saturation(saturation); player.hunger_manager.set_saturation(saturation);
player.send_health().await; player.send_health();
});
}) })
} }
@ -254,122 +234,82 @@ pub fn ffi_native_bridge_get_experience_impl(request: Uuid) -> Option<GetExperie
} }
pub fn ffi_native_bridge_set_experience_impl(request: SetExperienceRequest) -> Option<()> { pub fn ffi_native_bridge_set_experience_impl(request: SetExperienceRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let level = request.level; let level = request.level;
let progress = request.progress; let progress = request.progress;
let total_experience = request.total_experience; let total_experience = request.total_experience;
let player = player.clone(); player.set_experience(level, progress, total_experience);
ctx.runtime.spawn(async move {
player
.set_experience(level, progress, total_experience)
.await;
});
}) })
} }
pub fn ffi_native_bridge_kick_player_impl(request: KickPlayerRequest) -> Option<()> { pub fn ffi_native_bridge_kick_player_impl(request: KickPlayerRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let msg = request.message; let msg = request.message;
let player = player.clone();
ctx.runtime.spawn(async move {
let text = pumpkin_util::text::TextComponent::from_legacy_string(&msg); let text = pumpkin_util::text::TextComponent::from_legacy_string(&msg);
player player.kick(pumpkin::net::DisconnectReason::Kicked, &text);
.kick(pumpkin::net::DisconnectReason::Kicked, text)
.await;
});
}) })
} }
pub fn ffi_native_bridge_send_title_impl(request: SendTitleRequest) -> Option<()> { pub fn ffi_native_bridge_send_title_impl(request: SendTitleRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let player = player.clone();
let title = request.title; let title = request.title;
let subtitle = request.subtitle; let subtitle = request.subtitle;
let fade_in = request.fade_in; let fade_in = request.fade_in;
let stay = request.stay; let stay = request.stay;
let fade_out = request.fade_out; let fade_out = request.fade_out;
ctx.runtime.spawn(async move {
if fade_in >= 0 && stay >= 0 && fade_out >= 0 { if fade_in >= 0 && stay >= 0 && fade_out >= 0 {
player.send_title_animation(fade_in, stay, fade_out).await; player.send_title_animation(fade_in, stay, fade_out);
} }
if !title.is_empty() { if !title.is_empty() {
let text = pumpkin_util::text::TextComponent::from_legacy_string(&title); let text = pumpkin_util::text::TextComponent::from_legacy_string(&title);
player player.show_title(&text, &pumpkin::entity::player::TitleMode::Title);
.show_title(&text, &pumpkin::entity::player::TitleMode::Title)
.await;
} }
if !subtitle.is_empty() { if !subtitle.is_empty() {
let text = pumpkin_util::text::TextComponent::from_legacy_string(&subtitle); let text = pumpkin_util::text::TextComponent::from_legacy_string(&subtitle);
player player.show_title(&text, &pumpkin::entity::player::TitleMode::SubTitle);
.show_title(&text, &pumpkin::entity::player::TitleMode::SubTitle)
.await;
} }
});
}) })
} }
pub fn ffi_native_bridge_send_action_bar_impl(request: SendActionBarRequest) -> Option<()> { pub fn ffi_native_bridge_send_action_bar_impl(request: SendActionBarRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let msg = request.message; let msg = request.message;
let player = player.clone();
ctx.runtime.spawn(async move {
let text = pumpkin_util::text::TextComponent::from_legacy_string(&msg); let text = pumpkin_util::text::TextComponent::from_legacy_string(&msg);
player.send_system_message_raw(&text, true).await; player.send_system_message_raw(&text, true);
});
}) })
} }
pub fn ffi_native_bridge_reset_title_impl(request: Uuid) -> Option<()> { pub fn ffi_native_bridge_reset_title_impl(request: Uuid) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(Some(&request), |player| { with_player(Some(&request), |player| {
let player = player.clone();
ctx.runtime.spawn(async move {
let text = pumpkin_util::text::TextComponent::text(""); let text = pumpkin_util::text::TextComponent::text("");
player player.show_title(&text, &pumpkin::entity::player::TitleMode::Title);
.show_title(&text, &pumpkin::entity::player::TitleMode::Title) player.show_title(&text, &pumpkin::entity::player::TitleMode::SubTitle);
.await;
player
.show_title(&text, &pumpkin::entity::player::TitleMode::SubTitle)
.await;
});
}) })
} }
pub fn ffi_native_bridge_set_display_name_impl(request: SetDisplayNameRequest) -> Option<()> { pub fn ffi_native_bridge_set_display_name_impl(request: SetDisplayNameRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let name = request.display_name; let name = request.display_name;
let player = player.clone();
ctx.runtime.spawn(async move {
let comp = if name.is_empty() { let comp = if name.is_empty() {
None None
} else { } else {
Some(pumpkin_util::text::TextComponent::from_legacy_string(&name)) Some(pumpkin_util::text::TextComponent::from_legacy_string(&name))
}; };
player.set_display_name(comp).await; player.set_display_name(comp);
});
}) })
} }
pub fn ffi_native_bridge_set_player_list_name_impl( pub fn ffi_native_bridge_set_player_list_name_impl(
request: SetPlayerListNameRequest, request: SetPlayerListNameRequest,
) -> Option<()> { ) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let name = request.list_name; let name = request.list_name;
let player = player.clone();
ctx.runtime.spawn(async move {
let comp = if name.is_empty() { let comp = if name.is_empty() {
None None
} else { } else {
Some(pumpkin_util::text::TextComponent::from_legacy_string(&name)) Some(pumpkin_util::text::TextComponent::from_legacy_string(&name))
}; };
player.set_tab_list_name(comp).await; player.set_tab_list_name(comp);
});
}) })
} }
@ -425,24 +365,16 @@ pub fn ffi_native_bridge_get_player_pose_state_impl(
} }
pub fn ffi_native_bridge_set_sneaking_impl(request: SetSneakingRequest) -> Option<()> { pub fn ffi_native_bridge_set_sneaking_impl(request: SetSneakingRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let player = player.clone();
let sneaking = request.sneaking; let sneaking = request.sneaking;
ctx.runtime.spawn(async move { player.living_entity.entity.set_sneaking(sneaking);
player.living_entity.entity.set_sneaking(sneaking).await;
});
}) })
} }
pub fn ffi_native_bridge_set_sprinting_impl(request: SetSprintingRequest) -> Option<()> { pub fn ffi_native_bridge_set_sprinting_impl(request: SetSprintingRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let player = player.clone();
let sprinting = request.sprinting; let sprinting = request.sprinting;
ctx.runtime.spawn(async move { player.living_entity.entity.set_sprinting(sprinting);
player.living_entity.entity.set_sprinting(sprinting).await;
});
}) })
} }
@ -464,7 +396,12 @@ pub fn ffi_native_bridge_reset_player_time_impl(request: Uuid) -> Option<()> {
with_player(Some(&request), |player| { with_player(Some(&request), |player| {
let player = player.clone(); let player = player.clone();
ctx.runtime.spawn(async move { ctx.runtime.spawn(async move {
let world_time = player.world().level_time.lock().await.time_of_day; let world_time = player
.world()
.level_time
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.time_of_day;
let packet = pumpkin_protocol::java::client::play::CUpdateTime::new( let packet = pumpkin_protocol::java::client::play::CUpdateTime::new(
world_time, world_time, true, world_time, world_time, true,
); );
@ -495,7 +432,7 @@ pub fn ffi_native_bridge_reset_player_weather_impl(request: Uuid) -> Option<()>
with_player(Some(&request), |player| { with_player(Some(&request), |player| {
let player = player.clone(); let player = player.clone();
ctx.runtime.spawn(async move { ctx.runtime.spawn(async move {
let is_raining = player.world().is_raining().await; let is_raining = player.world().is_raining();
let event = if is_raining { let event = if is_raining {
pumpkin_protocol::java::client::play::GameEvent::BeginRaining pumpkin_protocol::java::client::play::GameEvent::BeginRaining
} else { } else {
@ -544,20 +481,14 @@ pub fn ffi_native_bridge_get_compass_target_impl(
} }
pub fn ffi_native_bridge_set_respawn_point_impl(request: SetRespawnPointRequest) -> Option<()> { pub fn ffi_native_bridge_set_respawn_point_impl(request: SetRespawnPointRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
let pos = request.position?; let pos = request.position?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let block_pos = let block_pos =
pumpkin_util::math::position::BlockPos::new(pos.x as i32, pos.y as i32, pos.z as i32); pumpkin_util::math::position::BlockPos::new(pos.x as i32, pos.y as i32, pos.z as i32);
let yaw = request.yaw; let yaw = request.yaw;
let force = request.force; let force = request.force;
let player = player.clone();
ctx.runtime.spawn(async move {
let dim = player.world().dimension.clone(); let dim = player.world().dimension.clone();
player player.set_respawn_point(dim, block_pos, yaw, 0.0, force);
.set_respawn_point(dim, block_pos, yaw, 0.0, force)
.await;
});
}) })
} }
@ -613,9 +544,7 @@ pub fn ffi_native_bridge_get_respawn_point_impl(
} }
pub fn ffi_native_bridge_stop_sound_impl(request: StopSoundRequest) -> Option<()> { pub fn ffi_native_bridge_stop_sound_impl(request: StopSoundRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let player = player.clone();
let sound = if request.sound.is_empty() { let sound = if request.sound.is_empty() {
None None
} else { } else {
@ -626,9 +555,7 @@ pub fn ffi_native_bridge_stop_sound_impl(request: StopSoundRequest) -> Option<()
} else { } else {
pumpkin_data::sound::SoundCategory::from_name(&request.category.to_lowercase()) pumpkin_data::sound::SoundCategory::from_name(&request.category.to_lowercase())
}; };
ctx.runtime.spawn(async move { player.stop_sound(sound, category);
player.stop_sound(sound, category).await;
});
}) })
} }
@ -718,14 +645,10 @@ pub fn ffi_native_bridge_send_game_event_impl(request: SendGameEventRequest) ->
} }
pub fn ffi_native_bridge_set_cooldown_impl(request: SetCooldownRequest) -> Option<()> { pub fn ffi_native_bridge_set_cooldown_impl(request: SetCooldownRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let player = player.clone();
let group = request.item_group; let group = request.item_group;
let duration = request.duration_ticks; let duration = request.duration_ticks;
ctx.runtime.spawn(async move { player.start_cooldown(group, duration);
player.start_cooldown(group, duration).await;
});
}) })
} }
@ -758,23 +681,13 @@ pub fn ffi_native_bridge_get_cooldown_impl(
} }
pub fn ffi_native_bridge_open_ender_chest_impl(request: Uuid) -> Option<()> { pub fn ffi_native_bridge_open_ender_chest_impl(request: Uuid) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(Some(&request), |player| { with_player(Some(&request), |player| {
let player = player.clone(); player.open_ender_chest();
ctx.runtime.spawn(async move {
player.open_ender_chest().await;
});
}) })
} }
pub fn ffi_native_bridge_update_inventory_impl(request: Uuid) -> Option<()> { pub fn ffi_native_bridge_update_inventory_impl(request: Uuid) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(Some(&request), |player| { with_player(Some(&request), |player| {
let player = player.clone(); player.on_screen_handler_opened(&player.player_screen_handler);
ctx.runtime.spawn(async move {
player
.on_screen_handler_opened(player.player_screen_handler.clone())
.await;
});
}) })
} }

View File

@ -3,7 +3,7 @@ use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack as PumpkinItemStack; use pumpkin_data::item_stack::ItemStack as PumpkinItemStack;
use crate::{ use crate::{
java::native_callbacks::{CALLBACK_CONTEXT, utils::with_player}, java::native_callbacks::utils::with_player,
proto::patchbukkit::{ proto::patchbukkit::{
common::Uuid, common::Uuid,
itemstack::{ itemstack::{
@ -98,15 +98,16 @@ pub fn ffi_native_bridge_get_player_inventory_impl(
pub fn ffi_native_bridge_set_player_inventory_slot_impl( pub fn ffi_native_bridge_set_player_inventory_slot_impl(
request: SetPlayerInventorySlotRequest, request: SetPlayerInventorySlotRequest,
) -> Option<()> { ) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
let slot = request.slot as usize; let slot = request.slot as usize;
let pumpkin_item = proto_item_to_pumpkin(request.item.as_ref()); let pumpkin_item = proto_item_to_pumpkin(request.item.as_ref());
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let player = player.clone();
ctx.runtime.spawn(async move {
if slot < 36 { if slot < 36 {
let mut main_guard = player.inventory.main_inventory.write().await; let mut main_guard = player
.inventory
.main_inventory
.write()
.unwrap_or_else(std::sync::PoisonError::into_inner);
main_guard[slot] = pumpkin_item; main_guard[slot] = pumpkin_item;
} else { } else {
let eq_slot = match slot { let eq_slot = match slot {
@ -118,11 +119,14 @@ pub fn ffi_native_bridge_set_player_inventory_slot_impl(
_ => None, _ => None,
}; };
if let Some(eq_slot) = eq_slot { if let Some(eq_slot) = eq_slot {
let mut eq_guard = player.inventory.entity_equipment.lock().await; let mut eq_guard = player
.inventory
.entity_equipment
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
eq_guard.put(&eq_slot, pumpkin_item); eq_guard.put(&eq_slot, pumpkin_item);
} }
} }
});
}) })
} }
@ -139,58 +143,78 @@ pub fn ffi_native_bridge_set_player_selected_slot_impl(
pub fn ffi_native_bridge_set_player_equipment_impl( pub fn ffi_native_bridge_set_player_equipment_impl(
request: SetPlayerEquipmentRequest, request: SetPlayerEquipmentRequest,
) -> Option<()> { ) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
let pumpkin_item = proto_item_to_pumpkin(request.item.as_ref()); let pumpkin_item = proto_item_to_pumpkin(request.item.as_ref());
let slot_type = request.slot_type; let slot_type = request.slot_type;
with_player(request.uuid.as_ref(), |player| { with_player(request.uuid.as_ref(), |player| {
let player = player.clone();
ctx.runtime.spawn(async move {
match slot_type { match slot_type {
0 => { 0 => {
// Main Hand // Main Hand
player.inventory.set_held_item(pumpkin_item).await; player.inventory.set_held_item(pumpkin_item);
} }
1 => { 1 => {
// Off Hand // Off Hand
let mut eq = player.inventory.entity_equipment.lock().await; let mut eq = player
.inventory
.entity_equipment
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
eq.put(&EquipmentSlot::OFF_HAND, pumpkin_item); eq.put(&EquipmentSlot::OFF_HAND, pumpkin_item);
} }
2 => { 2 => {
// Feet // Feet
let mut eq = player.inventory.entity_equipment.lock().await; let mut eq = player
.inventory
.entity_equipment
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
eq.put(&EquipmentSlot::FEET, pumpkin_item); eq.put(&EquipmentSlot::FEET, pumpkin_item);
} }
3 => { 3 => {
// Legs // Legs
let mut eq = player.inventory.entity_equipment.lock().await; let mut eq = player
.inventory
.entity_equipment
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
eq.put(&EquipmentSlot::LEGS, pumpkin_item); eq.put(&EquipmentSlot::LEGS, pumpkin_item);
} }
4 => { 4 => {
// Chest // Chest
let mut eq = player.inventory.entity_equipment.lock().await; let mut eq = player
.inventory
.entity_equipment
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
eq.put(&EquipmentSlot::CHEST, pumpkin_item); eq.put(&EquipmentSlot::CHEST, pumpkin_item);
} }
5 => { 5 => {
// Head // Head
let mut eq = player.inventory.entity_equipment.lock().await; let mut eq = player
.inventory
.entity_equipment
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
eq.put(&EquipmentSlot::HEAD, pumpkin_item); eq.put(&EquipmentSlot::HEAD, pumpkin_item);
} }
_ => {} _ => {}
} }
});
}) })
} }
pub fn ffi_native_bridge_clear_player_inventory_impl(request: Uuid) -> Option<()> { pub fn ffi_native_bridge_clear_player_inventory_impl(request: Uuid) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
with_player(Some(&request), |player| { with_player(Some(&request), |player| {
let player = player.clone(); let mut main_guard = player
ctx.runtime.spawn(async move { .inventory
let mut main_guard = player.inventory.main_inventory.write().await; .main_inventory
.write()
.unwrap_or_else(std::sync::PoisonError::into_inner);
main_guard.fill_with(|| PumpkinItemStack::EMPTY.clone()); main_guard.fill_with(|| PumpkinItemStack::EMPTY.clone());
let mut eq_guard = player.inventory.entity_equipment.lock().await; let mut eq_guard = player
.inventory
.entity_equipment
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
eq_guard.clear(); eq_guard.clear();
});
}) })
} }

View File

@ -8,14 +8,10 @@ pub fn ffi_native_bridge_send_message_impl(request: SendMessageRequest) -> Optio
let ctx = CALLBACK_CONTEXT.get()?; let ctx = CALLBACK_CONTEXT.get()?;
let player_uuid = uuid::Uuid::parse_str(&request.uuid?.value).unwrap(); let player_uuid = uuid::Uuid::parse_str(&request.uuid?.value).unwrap();
ctx.runtime.spawn(async move {
let player = ctx.plugin_context.server.get_player_by_uuid(player_uuid); let player = ctx.plugin_context.server.get_player_by_uuid(player_uuid);
if let Some(player) = player { if let Some(player) = player {
player player.send_system_message(&TextComponent::from_legacy_string(&request.message));
.send_system_message(&TextComponent::from_legacy_string(&request.message))
.await;
} }
});
Some(()) Some(())
} }

View File

@ -196,9 +196,7 @@ pub fn ffi_native_bridge_broadcast_message_impl(request: BroadcastMessageRequest
let server = ctx.plugin_context.server.clone(); let server = ctx.plugin_context.server.clone();
let text = TextComponent::text(request.message); let text = TextComponent::text(request.message);
let sender = TextComponent::text("Server"); let sender = TextComponent::text("Server");
ctx.runtime.spawn(async move { server.broadcast_message(&text, &sender, 0, None);
server.broadcast_message(&text, &sender, 0, None).await;
});
Some(()) Some(())
} }
@ -229,8 +227,11 @@ pub fn ffi_native_bridge_set_whitelist_player_impl(
let target_name = request.name; let target_name = request.name;
let server = ctx.plugin_context.server.clone(); let server = ctx.plugin_context.server.clone();
ctx.runtime.spawn(async move { let mut config = server
let mut config = server.data.whitelist_config.write().await; .data
.whitelist_config
.write()
.unwrap_or_else(std::sync::PoisonError::into_inner);
if request.whitelisted { if request.whitelisted {
if !config.whitelist.iter().any(|e| e.uuid == target_uuid) { if !config.whitelist.iter().any(|e| e.uuid == target_uuid) {
config config
@ -243,7 +244,6 @@ pub fn ffi_native_bridge_set_whitelist_player_impl(
} else { } else {
config.whitelist.retain(|e| e.uuid != target_uuid); config.whitelist.retain(|e| e.uuid != target_uuid);
} }
});
Some(()) Some(())
} }
@ -280,8 +280,11 @@ pub fn ffi_native_bridge_set_operator_impl(request: SetOperatorRequest) -> Optio
}; };
let server = ctx.plugin_context.server.clone(); let server = ctx.plugin_context.server.clone();
ctx.runtime.spawn(async move { let mut config = server
let mut config = server.data.operator_config.write().await; .data
.operator_config
.write()
.unwrap_or_else(std::sync::PoisonError::into_inner);
if request.is_op { if request.is_op {
if let Some(op) = config.ops.iter_mut().find(|e| e.uuid == target_uuid) { if let Some(op) = config.ops.iter_mut().find(|e| e.uuid == target_uuid) {
op.level = level; op.level = level;
@ -296,7 +299,6 @@ pub fn ffi_native_bridge_set_operator_impl(request: SetOperatorRequest) -> Optio
} else { } else {
config.ops.retain(|e| e.uuid != target_uuid); config.ops.retain(|e| e.uuid != target_uuid);
} }
});
Some(()) Some(())
} }
@ -343,11 +345,14 @@ pub fn ffi_native_bridge_set_ban_entry_impl(request: SetBanEntryRequest) -> Opti
let ctx = CALLBACK_CONTEXT.get()?; let ctx = CALLBACK_CONTEXT.get()?;
let server = ctx.plugin_context.server.clone(); let server = ctx.plugin_context.server.clone();
ctx.runtime.spawn(async move {
if let Some(entry) = request.entry { if let Some(entry) = request.entry {
if request.ban_type == "IP" { if request.ban_type == "IP" {
if let Ok(ip) = entry.target.parse::<std::net::IpAddr>() { if let Ok(ip) = entry.target.parse::<std::net::IpAddr>() {
let mut list = server.data.banned_ip_list.write().await; let mut list = server
.data
.banned_ip_list
.write()
.unwrap_or_else(std::sync::PoisonError::into_inner);
if request.remove { if request.remove {
list.banned_ips.retain(|e| e.ip != ip); list.banned_ips.retain(|e| e.ip != ip);
} else { } else {
@ -368,7 +373,11 @@ pub fn ffi_native_bridge_set_ban_entry_impl(request: SetBanEntryRequest) -> Opti
} }
} }
} else { } else {
let mut list = server.data.banned_player_list.write().await; let mut list = server
.data
.banned_player_list
.write()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let target_name = entry.target.clone(); let target_name = entry.target.clone();
if request.remove { if request.remove {
list.banned_players list.banned_players
@ -381,20 +390,18 @@ pub fn ffi_native_bridge_set_ban_entry_impl(request: SetBanEntryRequest) -> Opti
} else { } else {
None None
}; };
list.banned_players.push( list.banned_players
pumpkin::data::banlist_serializer::BannedPlayerEntry { .push(pumpkin::data::banlist_serializer::BannedPlayerEntry {
uuid: uuid::Uuid::nil(), uuid: uuid::Uuid::nil(),
name: target_name, name: target_name,
created: time::OffsetDateTime::now_utc(), created: time::OffsetDateTime::now_utc(),
source: entry.source, source: entry.source,
expires, expires,
reason: entry.reason, reason: entry.reason,
},
);
}
}
}
}); });
}
}
}
Some(()) Some(())
} }

View File

@ -71,18 +71,14 @@ pub fn ffi_native_bridge_player_play_sound_impl(request: PlayerPlaySoundRequest)
let position = request.location?.position?; let position = request.location?.position?;
let position: Vector3<f64> = Vector3::new(position.x, position.y, position.z); let position: Vector3<f64> = Vector3::new(position.x, position.y, position.z);
ctx.runtime.spawn(async move { player.play_sound(
player
.play_sound(
pumpkin_sound as u16, pumpkin_sound as u16,
category, category,
&position, &position,
request.volume, request.volume,
request.pitch, request.pitch,
seed, seed,
) );
.await;
});
Some(()) Some(())
} }

View File

@ -109,11 +109,7 @@ pub fn ffi_native_bridge_set_block_data_impl(request: SetBlockDataRequest) -> Op
} else { } else {
pumpkin::world::BlockFlags::NOTIFY_LISTENERS pumpkin::world::BlockFlags::NOTIFY_LISTENERS
}; };
tokio::task::block_in_place(|| { world.set_block_state(&pos, state_id, flags);
ctx.runtime.block_on(async {
world.set_block_state(&pos, state_id, flags).await;
})
});
Some(()) Some(())
} }
@ -178,8 +174,11 @@ pub fn ffi_native_bridge_set_world_border_impl(request: SetWorldBorderRequest) -
.cloned() .cloned()
.or_else(|| worlds.first().cloned())?; .or_else(|| worlds.first().cloned())?;
ctx.runtime.spawn(async move { {
let mut wb = world.worldborder.lock().await; let mut wb = world
.worldborder
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
wb.center_x = border_data.center_x; wb.center_x = border_data.center_x;
wb.center_z = border_data.center_z; wb.center_z = border_data.center_z;
wb.old_diameter = border_data.size; wb.old_diameter = border_data.size;
@ -190,7 +189,7 @@ pub fn ffi_native_bridge_set_world_border_impl(request: SetWorldBorderRequest) -
wb.damage_per_block = border_data.damage_per_block as f32; wb.damage_per_block = border_data.damage_per_block as f32;
wb.buffer = border_data.damage_buffer as f32; wb.buffer = border_data.damage_buffer as f32;
wb.portal_teleport_boundary = border_data.max_center_coordinate; wb.portal_teleport_boundary = border_data.max_center_coordinate;
}); }
Some(()) Some(())
} }
@ -480,7 +479,7 @@ pub fn ffi_native_bridge_spawn_world_entity_impl(
_ => &pumpkin_data::entity::EntityType::PIG, _ => &pumpkin_data::entity::EntityType::PIG,
}; };
let entity = pumpkin::entity::r#type::from_type(entity_type, pos, &w, new_uuid); let entity = pumpkin::entity::r#type::from_type(entity_type, pos, &w, new_uuid);
w.spawn_entity(entity).await; w.spawn_entity(entity);
}); });
Some(SpawnWorldEntityResponse { Some(SpawnWorldEntityResponse {
@ -513,10 +512,7 @@ pub fn ffi_native_bridge_create_world_explosion_impl(
pumpkin::world::ExplosionInteraction::None pumpkin::world::ExplosionInteraction::None
}; };
let w = world.clone(); world.explode(pos, power, interaction);
ctx.runtime.spawn(async move {
w.explode(pos, power, interaction).await;
});
Some(()) Some(())
} }