diff --git a/java/patchbukkit/src/main/java/org/patchbukkit/bridge/NativePatchBukkit.java b/java/patchbukkit/src/main/java/org/patchbukkit/bridge/NativePatchBukkit.java index 107cbd7..66e5919 100644 --- a/java/patchbukkit/src/main/java/org/patchbukkit/bridge/NativePatchBukkit.java +++ b/java/patchbukkit/src/main/java/org/patchbukkit/bridge/NativePatchBukkit.java @@ -14,7 +14,6 @@ public class NativePatchBukkit { private static final Linker LINKER = Linker.nativeLinker(); - private static MethodHandle sendMessageNative; private static MethodHandle callEventNative; private static MethodHandle getLocationNative; private static MethodHandle getWorldNative; @@ -182,7 +181,6 @@ public class NativePatchBukkit { * Called from Rust during initialization to register native function pointers. */ public static void initCallbacks( - long sendMessageAddr, long callEventAddr, long getLocationAddr, long freeStringAddr, @@ -191,12 +189,6 @@ public class NativePatchBukkit { long playerEntityPlaySoundAddr, long playerPlaySoundAddr ) { - // void rust_send_message(const char* uuid, const char* message) - sendMessageNative = LINKER.downcallHandle( - MemorySegment.ofAddress(sendMessageAddr), - FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS) - ); - // bool rust_call_event(const char* event_type, const char* event_data_json) // Returns true if Pumpkin handled it, false if unknown event type callEventNative = LINKER.downcallHandle( @@ -268,19 +260,6 @@ public class NativePatchBukkit { ); } - /** - * Send a message to a player by UUID. - */ - public static void sendMessage(UUID uuid, String message) { - try (Arena arena = Arena.ofConfined()) { - MemorySegment uuidStr = arena.allocateFrom(uuid.toString()); - MemorySegment msgStr = arena.allocateFrom(message); - sendMessageNative.invokeExact(uuidStr, msgStr); - } catch (Throwable t) { - throw new RuntimeException("Failed to call native sendMessage", t); - } - } - /** * Get a player's location by UUID. * diff --git a/java/patchbukkit/src/main/java/org/patchbukkit/entity/PatchBukkitPlayer.java b/java/patchbukkit/src/main/java/org/patchbukkit/entity/PatchBukkitPlayer.java index 292f22d..8a080d1 100644 --- a/java/patchbukkit/src/main/java/org/patchbukkit/entity/PatchBukkitPlayer.java +++ b/java/patchbukkit/src/main/java/org/patchbukkit/entity/PatchBukkitPlayer.java @@ -80,6 +80,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.util.TriState; import net.md_5.bungee.api.chat.BaseComponent; import patchbukkit.bridge.NativeBridgeFfi; +import patchbukkit.common.SendMessageRequest; import patchbukkit.common.SetAbilitiesRequest; @SuppressWarnings({ "deprecation", "removal" }) @@ -104,7 +105,8 @@ public class PatchBukkitPlayer sender = this.getUniqueId(); } - NativePatchBukkit.sendMessage(uuid, message); + var request = SendMessageRequest.newBuilder().setMessage(message).setUuid(BridgeUtils.convertUuid(sender)).build(); + NativeBridgeFfi.sendMessage(request); } @Override diff --git a/proto/patchbukkit/bridge/native.proto b/proto/patchbukkit/bridge/native.proto index 734bfe2..2750804 100644 --- a/proto/patchbukkit/bridge/native.proto +++ b/proto/patchbukkit/bridge/native.proto @@ -5,10 +5,12 @@ import "google/protobuf/empty.proto"; import "google/protobuf/wrappers.proto"; import "patchbukkit/common/abilities.proto"; import "patchbukkit/common/events.proto"; +import "patchbukkit/common/message.proto"; import "patchbukkit/common/types.proto"; service NativeBridge { rpc GetAbilities(patchbukkit.common.UUID) returns (patchbukkit.common.Abilities); rpc SetAbilities(patchbukkit.common.SetAbilitiesRequest) returns (google.protobuf.BoolValue); rpc RegisterEvent(patchbukkit.common.RegisterEventRequest) returns (google.protobuf.Empty); + rpc SendMessage(patchbukkit.common.SendMessageRequest) returns (google.protobuf.Empty); } diff --git a/proto/patchbukkit/common/message.proto b/proto/patchbukkit/common/message.proto new file mode 100644 index 0000000..c5b8e1f --- /dev/null +++ b/proto/patchbukkit/common/message.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package patchbukkit.common; + +import "patchbukkit/common/types.proto"; + +option java_multiple_files = true; +option java_package = "patchbukkit.common"; + +message SendMessageRequest { + patchbukkit.common.UUID uuid = 1; + string message = 2; +} diff --git a/rust/src/java/native_callbacks/message.rs b/rust/src/java/native_callbacks/message.rs index 18e6275..2a119f9 100644 --- a/rust/src/java/native_callbacks/message.rs +++ b/rust/src/java/native_callbacks/message.rs @@ -2,22 +2,23 @@ use std::ffi::c_char; use pumpkin_util::text::TextComponent; -use crate::java::native_callbacks::{CALLBACK_CONTEXT, utils::get_string}; +use crate::{ + java::native_callbacks::{CALLBACK_CONTEXT, utils::get_string}, + proto::patchbukkit::common::SendMessageRequest, +}; -pub extern "C" fn rust_send_message(uuid_ptr: *const c_char, message_ptr: *const c_char) { - let uuid_str = get_string(uuid_ptr); - let message = get_string(message_ptr); +pub fn ffi_native_bridge_send_message_impl(request: SendMessageRequest) -> Option<()> { + let ctx = CALLBACK_CONTEXT.get()?; + let player_uuid = uuid::Uuid::parse_str(&request.uuid?.value).unwrap(); - if let Some(ctx) = CALLBACK_CONTEXT.get() { - let uuid = uuid::Uuid::parse_str(&uuid_str).unwrap(); + ctx.runtime.spawn(async move { + let player = ctx.plugin_context.server.get_player_by_uuid(player_uuid); + if let Some(player) = player { + player + .send_system_message(&TextComponent::from_legacy_string(&request.message)) + .await; + } + }); - ctx.runtime.spawn(async move { - let player = ctx.plugin_context.server.get_player_by_uuid(uuid); - if let Some(player) = player { - player - .send_system_message(&TextComponent::from_legacy_string(&message)) - .await; - } - }); - } + Some(()) } diff --git a/rust/src/java/native_callbacks/mod.rs b/rust/src/java/native_callbacks/mod.rs index 7d6fbdd..10e2621 100644 --- a/rust/src/java/native_callbacks/mod.rs +++ b/rust/src/java/native_callbacks/mod.rs @@ -14,12 +14,24 @@ pub mod events; pub use events::*; pub mod location; +pub use location::*; + pub mod memory; +pub use memory::*; + pub mod message; +pub use message::*; + pub mod registry; +pub use registry::*; + pub mod sound; -pub mod utils; +pub use sound::*; + pub mod world; +pub use world::*; + +pub mod utils; static CALLBACK_CONTEXT: OnceLock = OnceLock::new(); @@ -67,7 +79,6 @@ pub extern "C" fn rust_free_bytes(ptr: *mut u8, len: u32) { } pub fn initialize_callbacks(jvm: &Jvm) -> Result<()> { - let send_message_addr = message::rust_send_message as *const () as i64; let call_event_addr = events::rust_call_event as *const () as i64; let get_location_addr = location::rust_get_location as *const () as i64; let free_string_addr = memory::rust_free_string as *const () as i64; @@ -81,7 +92,6 @@ pub fn initialize_callbacks(jvm: &Jvm) -> Result<()> { "org.patchbukkit.bridge.NativePatchBukkit", "initCallbacks", &[ - InvocationArg::try_from(send_message_addr)?.into_primitive()?, InvocationArg::try_from(call_event_addr)?.into_primitive()?, InvocationArg::try_from(get_location_addr)?.into_primitive()?, InvocationArg::try_from(free_string_addr)?.into_primitive()?,