Get sendMessage working
This commit is contained in:
parent
d51f952a2f
commit
4816935568
@ -1,6 +1,8 @@
|
|||||||
// No longer used currently, keeping around for reference in the short term
|
// No longer used currently, keeping around for reference in the short term
|
||||||
package org.patchbukkit;
|
package org.patchbukkit;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.astonbitecode.j4rs.api.invocation.NativeCallbackToRustChannelSupport;
|
import org.astonbitecode.j4rs.api.invocation.NativeCallbackToRustChannelSupport;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@ -37,4 +39,13 @@ public class NativeCallbacks extends NativeCallbackToRustChannelSupport {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendMessage(@NotNull UUID uuid, String message) {
|
||||||
|
NativeCallbacks.getInstance().doCallback(
|
||||||
|
new CallbackValue(
|
||||||
|
"SEND_MESSAGE",
|
||||||
|
new Object[] { uuid.toString(), message }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,27 +103,23 @@ public class PatchBukkitEntity implements Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@NotNull String message) {
|
public void sendMessage(String message) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'sendMessage'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@NotNull String... messages) {
|
public void sendMessage(String... messages) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'sendMessage'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@Nullable UUID sender, @NotNull String message) {
|
public void sendMessage(UUID sender, String message) {
|
||||||
// TODO Auto-generated method stub
|
this.sendMessage(message); // Most entities don't know about senders
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'sendMessage'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@Nullable UUID sender, @NotNull String... messages) {
|
public void sendMessage(UUID sender, String... messages) {
|
||||||
// TODO Auto-generated method stub
|
this.sendMessage(messages); // Most entities don't know about senders
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'sendMessage'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -60,11 +60,13 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.annotations.Range;
|
import org.jetbrains.annotations.Range;
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
import org.jetbrains.annotations.UnmodifiableView;
|
import org.jetbrains.annotations.UnmodifiableView;
|
||||||
|
import org.patchbukkit.NativeCallbacks;
|
||||||
import org.patchbukkit.PatchBukkitServer;
|
import org.patchbukkit.PatchBukkitServer;
|
||||||
|
|
||||||
import com.destroystokyo.paper.ClientOption;
|
import com.destroystokyo.paper.ClientOption;
|
||||||
import com.destroystokyo.paper.Title;
|
import com.destroystokyo.paper.Title;
|
||||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
import io.papermc.paper.connection.PlayerGameConnection;
|
import io.papermc.paper.connection.PlayerGameConnection;
|
||||||
import io.papermc.paper.entity.LookAnchor;
|
import io.papermc.paper.entity.LookAnchor;
|
||||||
@ -84,6 +86,44 @@ public class PatchBukkitPlayer
|
|||||||
super(uuid, name);
|
super(uuid, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRawMessage(String message) {
|
||||||
|
this.sendRawMessage(null, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRawMessage(UUID sender, String message) {
|
||||||
|
if (sender == null) {
|
||||||
|
sender = this.getUniqueId();
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeCallbacks.getInstance().sendMessage(sender, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
this.sendRawMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(String... messages) {
|
||||||
|
for (String message : messages) {
|
||||||
|
this.sendMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(UUID sender, String message) {
|
||||||
|
this.sendRawMessage(sender, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(UUID sender, String... messages) {
|
||||||
|
for (String message : messages) {
|
||||||
|
this.sendMessage(sender, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Player.Spigot spigot() {
|
public Player.Spigot spigot() {
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'spigot'");
|
throw new UnsupportedOperationException("Unimplemented method 'spigot'");
|
||||||
@ -119,12 +159,6 @@ public class PatchBukkitPlayer
|
|||||||
throw new UnsupportedOperationException("Unimplemented method 'abandonConversation'");
|
throw new UnsupportedOperationException("Unimplemented method 'abandonConversation'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRawMessage(@Nullable UUID sender, @NotNull String message) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'sendRawMessage'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOnline() {
|
public boolean isOnline() {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
@ -517,12 +551,6 @@ public class PatchBukkitPlayer
|
|||||||
throw new UnsupportedOperationException("Unimplemented method 'transfer'");
|
throw new UnsupportedOperationException("Unimplemented method 'transfer'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRawMessage(String message) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'sendRawMessage'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void kickPlayer(@org.jspecify.annotations.Nullable String message) {
|
public void kickPlayer(@org.jspecify.annotations.Nullable String message) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|||||||
1
rust/Cargo.lock
generated
1
rust/Cargo.lock
generated
@ -1701,6 +1701,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde-saphyr",
|
"serde-saphyr",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"uuid",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -25,6 +25,7 @@ serde-saphyr = "0.0.16"
|
|||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
uuid = "1.20.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
j4rs = { version = "0.24", artifact = "cdylib", lib = true }
|
j4rs = { version = "0.24", artifact = "cdylib", lib = true }
|
||||||
|
|||||||
@ -23,6 +23,7 @@ pub enum JvmCommand {
|
|||||||
Initialize {
|
Initialize {
|
||||||
j4rs_path: PathBuf,
|
j4rs_path: PathBuf,
|
||||||
respond_to: oneshot::Sender<Result<()>>,
|
respond_to: oneshot::Sender<Result<()>>,
|
||||||
|
context: Arc<Context>,
|
||||||
},
|
},
|
||||||
JavaCallback {
|
JavaCallback {
|
||||||
instance: Instance,
|
instance: Instance,
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
use std::{path::PathBuf, sync::Arc};
|
use std::{path::PathBuf, str::FromStr, sync::Arc};
|
||||||
|
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use j4rs::{Instance, InvocationArg, Jvm, JvmBuilder};
|
use j4rs::{Instance, InvocationArg, Jvm, JvmBuilder};
|
||||||
use pumpkin::{net::bedrock::play, server::Server};
|
use pumpkin::{net::bedrock::play, plugin::Context, server::Server};
|
||||||
|
use pumpkin_util::text::TextComponent;
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -20,6 +21,7 @@ pub struct JvmWorker {
|
|||||||
pub plugin_manager: PluginManager,
|
pub plugin_manager: PluginManager,
|
||||||
pub event_manager: EventManager,
|
pub event_manager: EventManager,
|
||||||
jvm: Option<j4rs::Jvm>,
|
jvm: Option<j4rs::Jvm>,
|
||||||
|
context: Option<Arc<Context>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JvmWorker {
|
impl JvmWorker {
|
||||||
@ -33,18 +35,21 @@ impl JvmWorker {
|
|||||||
plugin_manager: PluginManager::new(),
|
plugin_manager: PluginManager::new(),
|
||||||
event_manager: EventManager::new(),
|
event_manager: EventManager::new(),
|
||||||
jvm: None,
|
jvm: None,
|
||||||
|
context: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attach_thread(mut self) {
|
pub async fn attach_thread(mut self) {
|
||||||
log::info!("JVM worker thread started");
|
log::info!("JVM worker thread started");
|
||||||
|
|
||||||
while let Some(command) = self.command_rx.blocking_recv() {
|
while let Some(command) = self.command_rx.recv().await {
|
||||||
match command {
|
match command {
|
||||||
JvmCommand::Initialize {
|
JvmCommand::Initialize {
|
||||||
j4rs_path,
|
j4rs_path,
|
||||||
respond_to,
|
respond_to,
|
||||||
|
context,
|
||||||
} => {
|
} => {
|
||||||
|
self.context = Some(context);
|
||||||
let result = self.initialize_jvm(&j4rs_path);
|
let result = self.initialize_jvm(&j4rs_path);
|
||||||
let _ = respond_to.send(result);
|
let _ = respond_to.send(result);
|
||||||
}
|
}
|
||||||
@ -52,7 +57,7 @@ impl JvmWorker {
|
|||||||
instance,
|
instance,
|
||||||
respond_to,
|
respond_to,
|
||||||
} => {
|
} => {
|
||||||
let result = self.process_java_callback(instance);
|
let result = self.process_java_callback(instance).await;
|
||||||
let _ = respond_to.send(result);
|
let _ = respond_to.send(result);
|
||||||
}
|
}
|
||||||
JvmCommand::LoadPlugin {
|
JvmCommand::LoadPlugin {
|
||||||
@ -223,7 +228,7 @@ impl JvmWorker {
|
|||||||
log::info!("JVM worker thread exited");
|
log::info!("JVM worker thread exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_java_callback(&mut self, instance: Instance) -> anyhow::Result<()> {
|
async fn process_java_callback(&mut self, instance: Instance) -> anyhow::Result<()> {
|
||||||
let jvm = match self.jvm {
|
let jvm = match self.jvm {
|
||||||
Some(ref jvm) => jvm,
|
Some(ref jvm) => jvm,
|
||||||
None => bail!("JVM not initialized"),
|
None => bail!("JVM not initialized"),
|
||||||
@ -256,6 +261,29 @@ impl JvmWorker {
|
|||||||
None => todo!(),
|
None => todo!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
"SEND_MESSAGE" => {
|
||||||
|
let uuid: String = jvm.to_rust(jvm.cast(
|
||||||
|
&jvm.invoke(&instance, "getArg", &[&InvocationArg::try_from(0_i32)?])?,
|
||||||
|
"java.lang.String",
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
let message: String = jvm.to_rust(jvm.cast(
|
||||||
|
&jvm.invoke(&instance, "getArg", &[&InvocationArg::try_from(1_i32)?])?,
|
||||||
|
"java.lang.String",
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
if let Some(player) = self
|
||||||
|
.context
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.server
|
||||||
|
.get_player_by_uuid(uuid::Uuid::from_str(&uuid).unwrap())
|
||||||
|
{
|
||||||
|
player
|
||||||
|
.send_system_message(&TextComponent::text(message))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => log::warn!("Received unknown callback: {:?}", callback_name),
|
_ => log::warn!("Received unknown callback: {:?}", callback_name),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,8 +330,10 @@ impl JvmWorker {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = receiver.await {
|
match receiver.await {
|
||||||
log::error!("Callback failed: {}", e);
|
Ok(Ok(_)) => (),
|
||||||
|
Ok(Err(e)) => log::error!("{}", e),
|
||||||
|
Err(e) => log::error!("Callback failed: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@ -14,7 +14,10 @@ use java::{
|
|||||||
jar::discover_jar_files,
|
jar::discover_jar_files,
|
||||||
resources::{cleanup_stale_files, sync_embedded_resources},
|
resources::{cleanup_stale_files, sync_embedded_resources},
|
||||||
};
|
};
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{
|
||||||
|
mpsc::{self, Receiver, Sender},
|
||||||
|
oneshot,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
events::register_handlers,
|
events::register_handlers,
|
||||||
@ -108,6 +111,7 @@ async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc<Context>) ->
|
|||||||
.send(JvmCommand::Initialize {
|
.send(JvmCommand::Initialize {
|
||||||
j4rs_path: dirs.j4rs,
|
j4rs_path: dirs.j4rs,
|
||||||
respond_to: tx,
|
respond_to: tx,
|
||||||
|
context: server.clone(),
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("Failed to send command to initialize J4RS: {}", e))?;
|
.map_err(|e| format!("Failed to send command to initialize J4RS: {}", e))?;
|
||||||
@ -197,10 +201,16 @@ impl PatchBukkitPlugin {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let (tx, rx) = mpsc::channel(100);
|
let (tx, rx) = mpsc::channel(100);
|
||||||
let command_tx = tx.clone();
|
let command_tx = tx.clone();
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
pub async fn jvm_thread_task(command_tx: Sender<JvmCommand>, rx: Receiver<JvmCommand>) {
|
||||||
|
JvmWorker::new(command_tx, rx).attach_thread().await;
|
||||||
|
}
|
||||||
|
|
||||||
std::thread::Builder::new()
|
std::thread::Builder::new()
|
||||||
.name("patchbukkit-jvm-worker".to_string())
|
.name("patchbukkit-jvm-worker".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
JvmWorker::new(command_tx.clone(), rx).attach_thread();
|
jvm_thread_task(command_tx.clone(), rx);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
PatchBukkitPlugin { command_tx: tx }
|
PatchBukkitPlugin { command_tx: tx }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user