Get sound working
This commit is contained in:
parent
185822a5fe
commit
4b5f07b37c
@ -19,7 +19,8 @@ public class NativePatchBukkit {
|
||||
private static MethodHandle getWorldNative;
|
||||
private static MethodHandle freeStringNative;
|
||||
private static MethodHandle getRegistryDataNative;
|
||||
private static MethodHandle entityPlaySoundNative;
|
||||
private static MethodHandle playerEntityPlaySoundNative;
|
||||
private static MethodHandle playerPlaySoundNative;
|
||||
|
||||
// Struct layout matching Rust's #[repr(C)] AbilitiesFFI
|
||||
private static final StructLayout ABILITIES_LAYOUT =
|
||||
@ -188,7 +189,8 @@ public class NativePatchBukkit {
|
||||
long freeStringAddr,
|
||||
long getWorldAddr,
|
||||
long getRegistryDataAddr,
|
||||
long entityPlaySoundAddr
|
||||
long playerEntityPlaySoundAddr,
|
||||
long playerPlaySoundAddr
|
||||
) {
|
||||
// void rust_send_message(const char* uuid, const char* message)
|
||||
sendMessageNative = LINKER.downcallHandle(
|
||||
@ -250,10 +252,10 @@ public class NativePatchBukkit {
|
||||
FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS)
|
||||
);
|
||||
|
||||
// void rust_entity_play_sound(const char* player_uuid, const char* sound_name,
|
||||
// void rust_player_entity_play_sound(const char* player_uuid, const char* sound_name,
|
||||
// const char* sound_category, const char* entity_uuid, float volume, float pitch)
|
||||
entityPlaySoundNative = LINKER.downcallHandle(
|
||||
MemorySegment.ofAddress(entityPlaySoundAddr),
|
||||
playerEntityPlaySoundNative = LINKER.downcallHandle(
|
||||
MemorySegment.ofAddress(playerEntityPlaySoundAddr),
|
||||
FunctionDescriptor.ofVoid(
|
||||
ValueLayout.ADDRESS, // player_uuid
|
||||
ValueLayout.ADDRESS, // sound_name
|
||||
@ -263,6 +265,22 @@ public class NativePatchBukkit {
|
||||
ValueLayout.JAVA_FLOAT // pitch
|
||||
)
|
||||
);
|
||||
|
||||
// void rust_player_play_sound(const char* player_uuid, const char* sound_name,
|
||||
// const char* sound_category, double x, double y, double z, float volume, float pitch)
|
||||
playerPlaySoundNative = LINKER.downcallHandle(
|
||||
MemorySegment.ofAddress(playerPlaySoundAddr),
|
||||
FunctionDescriptor.ofVoid(
|
||||
ValueLayout.ADDRESS, // player_uuid
|
||||
ValueLayout.ADDRESS, // sound_name
|
||||
ValueLayout.ADDRESS, // sound_category
|
||||
ValueLayout.JAVA_DOUBLE, // x
|
||||
ValueLayout.JAVA_DOUBLE, // y
|
||||
ValueLayout.JAVA_DOUBLE, // z
|
||||
ValueLayout.JAVA_FLOAT, // volume
|
||||
ValueLayout.JAVA_FLOAT // pitch
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -457,7 +475,7 @@ public class NativePatchBukkit {
|
||||
* @param volume Volume (1.0 = normal)
|
||||
* @param pitch Pitch (1.0 = normal)
|
||||
*/
|
||||
public static void entityPlaySound(
|
||||
public static void playerEntityPlaySound(
|
||||
UUID playerUuid,
|
||||
String soundName,
|
||||
String soundCategory,
|
||||
@ -471,7 +489,7 @@ public class NativePatchBukkit {
|
||||
MemorySegment soundCategoryStr = arena.allocateFrom(soundCategory);
|
||||
MemorySegment entityUuidStr = arena.allocateFrom(entityUuid.toString());
|
||||
|
||||
entityPlaySoundNative.invokeExact(
|
||||
playerEntityPlaySoundNative.invokeExact(
|
||||
playerUuidStr,
|
||||
soundNameStr,
|
||||
soundCategoryStr,
|
||||
@ -483,4 +501,46 @@ public class NativePatchBukkit {
|
||||
throw new RuntimeException("Failed to call native entityPlaySound", t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Play a sound effect at a location, heard by a specific player.
|
||||
*
|
||||
* @param playerUuid The player who will hear the sound
|
||||
* @param soundName Sound identifier (e.g. "block.note_block.chime")
|
||||
* @param soundCategory Category name (e.g. "master", "music", "blocks")
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @param volume Volume (1.0 = normal)
|
||||
* @param pitch Pitch (1.0 = normal)
|
||||
*/
|
||||
public static void playerPlaySound(
|
||||
UUID playerUuid,
|
||||
String soundName,
|
||||
String soundCategory,
|
||||
double x,
|
||||
double y,
|
||||
double z,
|
||||
float volume,
|
||||
float pitch
|
||||
) {
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment playerUuidStr = arena.allocateFrom(playerUuid.toString());
|
||||
MemorySegment soundNameStr = arena.allocateFrom(soundName);
|
||||
MemorySegment soundCategoryStr = arena.allocateFrom(soundCategory);
|
||||
|
||||
playerPlaySoundNative.invokeExact(
|
||||
playerUuidStr,
|
||||
soundNameStr,
|
||||
soundCategoryStr,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
volume,
|
||||
pitch
|
||||
);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Failed to call native playerPlaySound", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,6 +62,7 @@ import org.jetbrains.annotations.Unmodifiable;
|
||||
import org.jetbrains.annotations.UnmodifiableView;
|
||||
import org.patchbukkit.PatchBukkitServer;
|
||||
import org.patchbukkit.bridge.NativePatchBukkit;
|
||||
import org.patchbukkit.registry.PatchBukkitSound;
|
||||
|
||||
import com.destroystokyo.paper.ClientOption;
|
||||
import com.destroystokyo.paper.Title;
|
||||
@ -685,14 +686,13 @@ public class PatchBukkitPlayer
|
||||
|
||||
@Override
|
||||
public void playSound(Location location, Sound sound, SoundCategory category, float volume, float pitch) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'playSound'");
|
||||
var patchBukkitSound = (PatchBukkitSound) sound;
|
||||
NativePatchBukkit.playerPlaySound(this.uuid, patchBukkitSound.getOriginalName(), category.name(), location.x(), location.y(), location.z(), volume, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(Location location, String sound, SoundCategory category, float volume, float pitch) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'playSound'");
|
||||
NativePatchBukkit.playerPlaySound(this.uuid, sound, category.name(), location.x(), location.y(), location.z(), volume, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -711,13 +711,13 @@ public class PatchBukkitPlayer
|
||||
|
||||
@Override
|
||||
public void playSound(Entity entity, Sound sound, SoundCategory category, float volume, float pitch) {
|
||||
NativePatchBukkit.entityPlaySound(this.uuid, sound.toString(), category.name(), entity.getUniqueId(), volume, pitch);
|
||||
var patchBukkitSound = (PatchBukkitSound) sound;
|
||||
NativePatchBukkit.playerEntityPlaySound(this.uuid, patchBukkitSound.getOriginalName(), category.name(), entity.getUniqueId(), volume, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(Entity entity, String sound, SoundCategory category, float volume, float pitch) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'playSound'");
|
||||
NativePatchBukkit.playerEntityPlaySound(this.uuid, sound, category.name(), entity.getUniqueId(), volume, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -9,15 +9,21 @@ public class PatchBukkitSound implements Sound {
|
||||
private final NamespacedKey namespacedKey;
|
||||
private final Key adventureKey;
|
||||
private final String enumName;
|
||||
private final String originalName;
|
||||
private final int protocolId;
|
||||
|
||||
public PatchBukkitSound(String soundName, int protocolId) {
|
||||
this.namespacedKey = new NamespacedKey(NamespacedKey.MINECRAFT, soundName);
|
||||
this.adventureKey = Key.key(Key.MINECRAFT_NAMESPACE, soundName);
|
||||
this.protocolId = protocolId;
|
||||
this.originalName = soundName;
|
||||
this.enumName = soundName.toUpperCase().replace('.', '_');
|
||||
}
|
||||
|
||||
public String getOriginalName() {
|
||||
return originalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
return namespacedKey;
|
||||
|
||||
@ -45,7 +45,9 @@ pub fn initialize_callbacks(jvm: &Jvm) -> Result<()> {
|
||||
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;
|
||||
let rust_entity_play_sound_addr = sound::rust_entity_play_sound as *const () as i64;
|
||||
let rust_player_entity_play_sound_addr =
|
||||
sound::rust_player_entity_play_sound as *const () as i64;
|
||||
let rust_player_play_sound_addr = sound::rust_player_play_sound as *const () as i64;
|
||||
|
||||
jvm.invoke_static(
|
||||
"org.patchbukkit.bridge.NativePatchBukkit",
|
||||
@ -59,7 +61,8 @@ pub fn initialize_callbacks(jvm: &Jvm) -> Result<()> {
|
||||
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()?,
|
||||
InvocationArg::try_from(rust_entity_play_sound_addr)?.into_primitive()?,
|
||||
InvocationArg::try_from(rust_player_entity_play_sound_addr)?.into_primitive()?,
|
||||
InvocationArg::try_from(rust_player_play_sound_addr)?.into_primitive()?,
|
||||
],
|
||||
)?;
|
||||
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
use std::ffi::{c_char, c_float};
|
||||
use std::ffi::{c_char, c_double, c_float};
|
||||
|
||||
use pumpkin::command::args::entities::{EntitySelectorType, TargetSelector};
|
||||
use pumpkin_data::sound::{Sound, SoundCategory};
|
||||
use pumpkin_protocol::{IdOr, java::client::play::CEntitySoundEffect};
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use rand::{RngExt, rng};
|
||||
|
||||
use crate::java::native_callbacks::{CALLBACK_CONTEXT, utils::get_string};
|
||||
|
||||
pub extern "C" fn rust_entity_play_sound(
|
||||
pub extern "C" fn rust_player_entity_play_sound(
|
||||
player_uuid_ptr: *const c_char,
|
||||
sound_name_ptr: *const c_char,
|
||||
sound_category_ptr: *const c_char,
|
||||
@ -65,3 +66,46 @@ pub extern "C" fn rust_entity_play_sound(
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub extern "C" fn rust_player_play_sound(
|
||||
player_uuid_ptr: *const c_char,
|
||||
sound_name_ptr: *const c_char,
|
||||
sound_category_ptr: *const c_char,
|
||||
x: c_double,
|
||||
y: c_double,
|
||||
z: c_double,
|
||||
volume: c_float,
|
||||
pitch: c_float,
|
||||
) {
|
||||
let player_uuid_str = get_string(player_uuid_ptr);
|
||||
let sound_name = get_string(sound_name_ptr);
|
||||
let sound_category = get_string(sound_category_ptr);
|
||||
|
||||
if let Some(ctx) = CALLBACK_CONTEXT.get() {
|
||||
let player_uuid = uuid::Uuid::parse_str(&player_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 {
|
||||
let sound = match Sound::from_name(&sound_name) {
|
||||
Some(sound) => sound,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let category = match SoundCategory::from_name(&sound_category.to_lowercase()) {
|
||||
Some(category) => category,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let seed = rng().random::<f64>();
|
||||
|
||||
let position: Vector3<f64> = Vector3::new(x, y, z);
|
||||
|
||||
player
|
||||
.play_sound(sound as u16, category, &position, volume, pitch, seed)
|
||||
.await;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use anyhow::Result;
|
||||
use rust_embed::Embed;
|
||||
|
||||
#[derive(Embed)]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user