Refactor get location
This commit is contained in:
parent
605858e14f
commit
4829d59c1e
@ -14,7 +14,6 @@ public class NativePatchBukkit {
|
||||
|
||||
private static final Linker LINKER = Linker.nativeLinker();
|
||||
|
||||
private static MethodHandle getLocationNative;
|
||||
private static MethodHandle getWorldNative;
|
||||
private static MethodHandle freeStringNative;
|
||||
private static MethodHandle getRegistryDataNative;
|
||||
@ -180,22 +179,12 @@ public class NativePatchBukkit {
|
||||
* Called from Rust during initialization to register native function pointers.
|
||||
*/
|
||||
public static void initCallbacks(
|
||||
long getLocationAddr,
|
||||
long freeStringAddr,
|
||||
long getWorldAddr,
|
||||
long getRegistryDataAddr,
|
||||
long playerEntityPlaySoundAddr,
|
||||
long playerPlaySoundAddr
|
||||
) {
|
||||
// bool rust_get_location(const char* uuid, Vec3FFI* out)
|
||||
getLocationNative = LINKER.downcallHandle(
|
||||
MemorySegment.ofAddress(getLocationAddr),
|
||||
FunctionDescriptor.of(
|
||||
ValueLayout.JAVA_BOOLEAN, // return type
|
||||
ValueLayout.ADDRESS, // uuid string
|
||||
ValueLayout.ADDRESS // out pointer to Vec3FFI
|
||||
)
|
||||
);
|
||||
|
||||
// const char* rust_get_world(const char* uuid)
|
||||
getWorldNative = LINKER.downcallHandle(
|
||||
@ -246,36 +235,6 @@ public class NativePatchBukkit {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a player's location by UUID.
|
||||
*
|
||||
* @param uuid The player's UUID
|
||||
* @return The player's position, or null if player not found
|
||||
*/
|
||||
public static Vec3 getLocation(UUID uuid) {
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment uuidStr = arena.allocateFrom(uuid.toString());
|
||||
MemorySegment outStruct = arena.allocate(VEC3_LAYOUT);
|
||||
|
||||
boolean success = (boolean) getLocationNative.invokeExact(
|
||||
uuidStr,
|
||||
outStruct
|
||||
);
|
||||
|
||||
if (!success) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Vec3(
|
||||
(double) VEC3_X.get(outStruct, 0L),
|
||||
(double) VEC3_Y.get(outStruct, 0L),
|
||||
(double) VEC3_Z.get(outStruct, 0L)
|
||||
);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Failed to call native getLocation", t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a string allocated by the Rust side.
|
||||
*/
|
||||
|
||||
@ -37,6 +37,7 @@ import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.patchbukkit.bridge.BridgeUtils;
|
||||
import org.patchbukkit.bridge.NativePatchBukkit;
|
||||
import org.patchbukkit.world.PatchBukkitWorld;
|
||||
|
||||
@ -47,6 +48,7 @@ import io.papermc.paper.entity.TeleportFlag;
|
||||
import io.papermc.paper.threadedregions.scheduler.EntityScheduler;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.util.TriState;
|
||||
import patchbukkit.bridge.NativeBridgeFfi;
|
||||
|
||||
public class PatchBukkitEntity implements Entity {
|
||||
|
||||
@ -262,8 +264,10 @@ public class PatchBukkitEntity implements Entity {
|
||||
|
||||
@Override
|
||||
public @NotNull Location getLocation() {
|
||||
var loc = NativePatchBukkit.getLocation(this.uuid);
|
||||
return new Location(this.getWorld(), loc.x(), loc.y(), loc.z());
|
||||
var location = NativeBridgeFfi.getLocation(BridgeUtils.convertUuid(this.uuid));
|
||||
var world = PatchBukkitWorld.getOrCreate(BridgeUtils.convertUuid(location.getWorld().getUuid()));
|
||||
var position = location.getPosition();
|
||||
return new Location(world, position.getX(), position.getY(), position.getZ(), location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -11,7 +11,11 @@ import "patchbukkit/message.proto";
|
||||
service NativeBridge {
|
||||
rpc GetAbilities(patchbukkit.common.UUID) returns (patchbukkit.abilities.Abilities);
|
||||
rpc SetAbilities(patchbukkit.abilities.SetAbilitiesRequest) returns (patchbukkit.abilities.SetAbilitiesResponse);
|
||||
|
||||
rpc RegisterEvent(patchbukkit.events.RegisterEventRequest) returns (google.protobuf.Empty);
|
||||
rpc CallEvent(patchbukkit.events.CallEventRequest) returns (patchbukkit.events.CallEventResponse);
|
||||
|
||||
rpc SendMessage(patchbukkit.message.SendMessageRequest) returns (google.protobuf.Empty);
|
||||
|
||||
rpc GetLocation(patchbukkit.common.UUID) returns (patchbukkit.common.Location);
|
||||
}
|
||||
|
||||
@ -8,3 +8,20 @@ option java_package = "patchbukkit.common";
|
||||
message UUID {
|
||||
string value = 1;
|
||||
}
|
||||
|
||||
message Vec3 {
|
||||
double x = 1;
|
||||
double y = 2;
|
||||
double z = 3;
|
||||
}
|
||||
|
||||
message World {
|
||||
UUID uuid = 1;
|
||||
}
|
||||
|
||||
message Location {
|
||||
World world = 1;
|
||||
Vec3 position = 2;
|
||||
float yaw = 3;
|
||||
float pitch = 4;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ use crate::proto::patchbukkit::{
|
||||
|
||||
pub fn ffi_native_bridge_get_abilities_impl(request: Uuid) -> Option<Abilities> {
|
||||
let ctx = CALLBACK_CONTEXT.get()?;
|
||||
let player_uuid = uuid::Uuid::parse_str(&request.value).unwrap();
|
||||
let player_uuid = uuid::Uuid::parse_str(&request.value).ok()?;
|
||||
let mut abilities = Abilities::default();
|
||||
let player = ctx.plugin_context.server.get_player_by_uuid(player_uuid)?;
|
||||
let pumpkin_abilities = tokio::task::block_in_place(|| {
|
||||
|
||||
@ -2,7 +2,10 @@ use std::ffi::c_char;
|
||||
|
||||
use pumpkin::command::args::entities::{EntitySelectorType, TargetSelector};
|
||||
|
||||
use crate::java::native_callbacks::{CALLBACK_CONTEXT, utils::get_string};
|
||||
use crate::{
|
||||
java::native_callbacks::{CALLBACK_CONTEXT, utils::get_string},
|
||||
proto::patchbukkit::common::{Location, Uuid, Vec3, World},
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Vec3FFI {
|
||||
@ -11,28 +14,41 @@ pub struct Vec3FFI {
|
||||
pub z: f64,
|
||||
}
|
||||
|
||||
pub extern "C" fn rust_get_location(uuid_ptr: *const c_char, out: *mut Vec3FFI) -> bool {
|
||||
let uuid_str = get_string(uuid_ptr);
|
||||
if let Some(ctx) = CALLBACK_CONTEXT.get() {
|
||||
let uuid = uuid::Uuid::parse_str(&uuid_str).unwrap();
|
||||
let entity = ctx
|
||||
.plugin_context
|
||||
.server
|
||||
.select_entities(&TargetSelector::new(EntitySelectorType::Uuid(uuid)), None);
|
||||
if entity.len() == 1 {
|
||||
let entity = entity.first().unwrap().get_entity();
|
||||
let position =
|
||||
tokio::task::block_in_place(|| ctx.runtime.block_on(async { entity.pos.load() }));
|
||||
pub fn ffi_native_bridge_get_location_impl(entity_uuid: Uuid) -> Option<Location> {
|
||||
let ctx = CALLBACK_CONTEXT.get()?;
|
||||
let uuid = uuid::Uuid::parse_str(&entity_uuid.value).ok()?;
|
||||
|
||||
unsafe {
|
||||
(*out).x = position.x;
|
||||
(*out).y = position.y;
|
||||
(*out).z = position.z;
|
||||
}
|
||||
let entity = ctx
|
||||
.plugin_context
|
||||
.server
|
||||
.select_entities(&TargetSelector::new(EntitySelectorType::Uuid(uuid)), None);
|
||||
|
||||
return true;
|
||||
}
|
||||
if entity.len() == 1 {
|
||||
let entity = entity.first().unwrap().get_entity();
|
||||
let position = entity.pos.load();
|
||||
let world = entity.world.load().uuid;
|
||||
let yaw = entity.yaw.load();
|
||||
let pitch = entity.pitch.load();
|
||||
|
||||
let mut response_position = Vec3::default();
|
||||
response_position.x = position.x;
|
||||
response_position.y = position.y;
|
||||
response_position.z = position.z;
|
||||
|
||||
let mut world_uuid = Uuid::default();
|
||||
world_uuid.value = world.to_string();
|
||||
|
||||
let mut response_world = World::default();
|
||||
response_world.uuid = Some(world_uuid);
|
||||
|
||||
let mut location = Location::default();
|
||||
location.pitch = pitch;
|
||||
location.position = Some(response_position);
|
||||
location.world = Some(response_world);
|
||||
location.yaw = yaw;
|
||||
|
||||
return Some(location);
|
||||
}
|
||||
|
||||
false
|
||||
None
|
||||
}
|
||||
|
||||
@ -79,7 +79,6 @@ pub extern "C" fn rust_free_bytes(ptr: *mut u8, len: u32) {
|
||||
}
|
||||
|
||||
pub fn initialize_callbacks(jvm: &Jvm) -> Result<()> {
|
||||
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 get_world_addr = world::rust_get_world as *const () as i64;
|
||||
let rust_get_registry_data_addr = registry::rust_get_registry_data as *const () as i64;
|
||||
@ -91,7 +90,6 @@ pub fn initialize_callbacks(jvm: &Jvm) -> Result<()> {
|
||||
"org.patchbukkit.bridge.NativePatchBukkit",
|
||||
"initCallbacks",
|
||||
&[
|
||||
InvocationArg::try_from(get_location_addr)?.into_primitive()?,
|
||||
InvocationArg::try_from(free_string_addr)?.into_primitive()?,
|
||||
InvocationArg::try_from(get_world_addr)?.into_primitive()?,
|
||||
InvocationArg::try_from(rust_get_registry_data_addr)?.into_primitive()?,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user