Update send message

This commit is contained in:
Bjorn Beishline 2026-02-03 16:07:58 -07:00
parent d382421557
commit dfbdab7e95
6 changed files with 47 additions and 40 deletions

View File

@ -14,7 +14,6 @@ public class NativePatchBukkit {
private static final Linker LINKER = Linker.nativeLinker(); private static final Linker LINKER = Linker.nativeLinker();
private static MethodHandle sendMessageNative;
private static MethodHandle callEventNative; private static MethodHandle callEventNative;
private static MethodHandle getLocationNative; private static MethodHandle getLocationNative;
private static MethodHandle getWorldNative; private static MethodHandle getWorldNative;
@ -182,7 +181,6 @@ public class NativePatchBukkit {
* Called from Rust during initialization to register native function pointers. * Called from Rust during initialization to register native function pointers.
*/ */
public static void initCallbacks( public static void initCallbacks(
long sendMessageAddr,
long callEventAddr, long callEventAddr,
long getLocationAddr, long getLocationAddr,
long freeStringAddr, long freeStringAddr,
@ -191,12 +189,6 @@ public class NativePatchBukkit {
long playerEntityPlaySoundAddr, long playerEntityPlaySoundAddr,
long playerPlaySoundAddr 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) // bool rust_call_event(const char* event_type, const char* event_data_json)
// Returns true if Pumpkin handled it, false if unknown event type // Returns true if Pumpkin handled it, false if unknown event type
callEventNative = LINKER.downcallHandle( 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. * Get a player's location by UUID.
* *

View File

@ -80,6 +80,7 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.util.TriState; import net.kyori.adventure.util.TriState;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import patchbukkit.bridge.NativeBridgeFfi; import patchbukkit.bridge.NativeBridgeFfi;
import patchbukkit.common.SendMessageRequest;
import patchbukkit.common.SetAbilitiesRequest; import patchbukkit.common.SetAbilitiesRequest;
@SuppressWarnings({ "deprecation", "removal" }) @SuppressWarnings({ "deprecation", "removal" })
@ -104,7 +105,8 @@ public class PatchBukkitPlayer
sender = this.getUniqueId(); sender = this.getUniqueId();
} }
NativePatchBukkit.sendMessage(uuid, message); var request = SendMessageRequest.newBuilder().setMessage(message).setUuid(BridgeUtils.convertUuid(sender)).build();
NativeBridgeFfi.sendMessage(request);
} }
@Override @Override

View File

@ -5,10 +5,12 @@ import "google/protobuf/empty.proto";
import "google/protobuf/wrappers.proto"; import "google/protobuf/wrappers.proto";
import "patchbukkit/common/abilities.proto"; import "patchbukkit/common/abilities.proto";
import "patchbukkit/common/events.proto"; import "patchbukkit/common/events.proto";
import "patchbukkit/common/message.proto";
import "patchbukkit/common/types.proto"; import "patchbukkit/common/types.proto";
service NativeBridge { service NativeBridge {
rpc GetAbilities(patchbukkit.common.UUID) returns (patchbukkit.common.Abilities); rpc GetAbilities(patchbukkit.common.UUID) returns (patchbukkit.common.Abilities);
rpc SetAbilities(patchbukkit.common.SetAbilitiesRequest) returns (google.protobuf.BoolValue); rpc SetAbilities(patchbukkit.common.SetAbilitiesRequest) returns (google.protobuf.BoolValue);
rpc RegisterEvent(patchbukkit.common.RegisterEventRequest) returns (google.protobuf.Empty); rpc RegisterEvent(patchbukkit.common.RegisterEventRequest) returns (google.protobuf.Empty);
rpc SendMessage(patchbukkit.common.SendMessageRequest) returns (google.protobuf.Empty);
} }

View File

@ -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;
}

View File

@ -2,22 +2,23 @@ use std::ffi::c_char;
use pumpkin_util::text::TextComponent; 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) { pub fn ffi_native_bridge_send_message_impl(request: SendMessageRequest) -> Option<()> {
let uuid_str = get_string(uuid_ptr); let ctx = CALLBACK_CONTEXT.get()?;
let message = get_string(message_ptr); let player_uuid = uuid::Uuid::parse_str(&request.uuid?.value).unwrap();
if let Some(ctx) = CALLBACK_CONTEXT.get() { ctx.runtime.spawn(async move {
let uuid = uuid::Uuid::parse_str(&uuid_str).unwrap(); 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 { Some(())
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;
}
});
}
} }

View File

@ -14,12 +14,24 @@ pub mod events;
pub use events::*; pub use events::*;
pub mod location; pub mod location;
pub use location::*;
pub mod memory; pub mod memory;
pub use memory::*;
pub mod message; pub mod message;
pub use message::*;
pub mod registry; pub mod registry;
pub use registry::*;
pub mod sound; pub mod sound;
pub mod utils; pub use sound::*;
pub mod world; pub mod world;
pub use world::*;
pub mod utils;
static CALLBACK_CONTEXT: OnceLock<CallbackContext> = OnceLock::new(); static CALLBACK_CONTEXT: OnceLock<CallbackContext> = 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<()> { 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 call_event_addr = events::rust_call_event as *const () as i64;
let get_location_addr = location::rust_get_location 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; 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", "org.patchbukkit.bridge.NativePatchBukkit",
"initCallbacks", "initCallbacks",
&[ &[
InvocationArg::try_from(send_message_addr)?.into_primitive()?,
InvocationArg::try_from(call_event_addr)?.into_primitive()?, InvocationArg::try_from(call_event_addr)?.into_primitive()?,
InvocationArg::try_from(get_location_addr)?.into_primitive()?, InvocationArg::try_from(get_location_addr)?.into_primitive()?,
InvocationArg::try_from(free_string_addr)?.into_primitive()?, InvocationArg::try_from(free_string_addr)?.into_primitive()?,