From deb1710c3ef5f3fa55618e861ad8aced83d80ac5 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Sat, 31 Jan 2026 00:34:39 +0100 Subject: [PATCH] try to add tab completion still does not work, but also includes some fixes --- .../org/patchbukkit/PatchBukkitServer.java | 18 +- .../PatchBukkitConsoleCommandSender.java | 8 +- .../scheduler/PatchBukkitScheduler.java | 246 ++++++++++++++++++ rust/src/config/spigot.rs | 2 + rust/src/plugin/manager.rs | 54 +++- 5 files changed, 305 insertions(+), 23 deletions(-) create mode 100644 java/patchbukkit/src/main/java/org/patchbukkit/scheduler/PatchBukkitScheduler.java diff --git a/java/patchbukkit/src/main/java/org/patchbukkit/PatchBukkitServer.java b/java/patchbukkit/src/main/java/org/patchbukkit/PatchBukkitServer.java index 07988be..1351356 100644 --- a/java/patchbukkit/src/main/java/org/patchbukkit/PatchBukkitServer.java +++ b/java/patchbukkit/src/main/java/org/patchbukkit/PatchBukkitServer.java @@ -87,6 +87,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.patchbukkit.command.PatchBukkitCommandMap; import org.patchbukkit.command.PatchBukkitConsoleCommandSender; +import org.patchbukkit.scheduler.PatchBukkitScheduler; @SuppressWarnings("removal") public class PatchBukkitServer implements Server { @@ -95,6 +96,8 @@ public class PatchBukkitServer implements Server { io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); private final String bukkitVersion = Versioning.getBukkitVersion(); private final CommandMap commandMap = new PatchBukkitCommandMap(); + private final BukkitScheduler scheduler = new PatchBukkitScheduler(); + private final Map onlinePlayers = new java.util.concurrent.ConcurrentHashMap<>(); private final Map onlinePlayersByName = new java.util.concurrent.ConcurrentHashMap<>(); @@ -162,10 +165,7 @@ public class PatchBukkitServer implements Server { @Override public @NotNull String getVersion() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException( - "Unimplemented method 'getVersion'" - ); + return "1.21.11"; } @Override @@ -462,10 +462,7 @@ public class PatchBukkitServer implements Server { @Override public @NotNull BukkitScheduler getScheduler() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException( - "Unimplemented method 'getScheduler'" - ); + return this.scheduler; } @Override @@ -1578,10 +1575,7 @@ public class PatchBukkitServer implements Server { @Override public boolean suggestPlayerNamesWhenNullTabCompletions() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException( - "Unimplemented method 'suggestPlayerNamesWhenNullTabCompletions'" - ); + return true; } @Override diff --git a/java/patchbukkit/src/main/java/org/patchbukkit/command/PatchBukkitConsoleCommandSender.java b/java/patchbukkit/src/main/java/org/patchbukkit/command/PatchBukkitConsoleCommandSender.java index d09808e..9117b05 100644 --- a/java/patchbukkit/src/main/java/org/patchbukkit/command/PatchBukkitConsoleCommandSender.java +++ b/java/patchbukkit/src/main/java/org/patchbukkit/command/PatchBukkitConsoleCommandSender.java @@ -3,6 +3,7 @@ package org.patchbukkit.command; import java.util.Set; import java.util.UUID; +import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.conversations.Conversation; @@ -14,6 +15,7 @@ import org.bukkit.plugin.Plugin; import org.checkerframework.checker.units.qual.m; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.patchbukkit.PatchBukkitServer; import net.kyori.adventure.text.Component; @@ -43,8 +45,7 @@ public class PatchBukkitConsoleCommandSender implements ConsoleCommandSender { @Override public @NotNull Server getServer() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getServer'"); + return Bukkit.getServer(); } @Override @@ -132,8 +133,7 @@ public class PatchBukkitConsoleCommandSender implements ConsoleCommandSender { @Override public boolean isOp() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'isOp'"); + return true; } @Override diff --git a/java/patchbukkit/src/main/java/org/patchbukkit/scheduler/PatchBukkitScheduler.java b/java/patchbukkit/src/main/java/org/patchbukkit/scheduler/PatchBukkitScheduler.java new file mode 100644 index 0000000..847e5b5 --- /dev/null +++ b/java/patchbukkit/src/main/java/org/patchbukkit/scheduler/PatchBukkitScheduler.java @@ -0,0 +1,246 @@ +package org.patchbukkit.scheduler; + +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; +import java.util.concurrent.Future; +import java.util.function.Consumer; + +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.scheduler.BukkitWorker; +import org.jetbrains.annotations.NotNull; + +public class PatchBukkitScheduler implements BukkitScheduler { + + @Override + public int scheduleSyncDelayedTask(@NotNull Plugin plugin, @NotNull Runnable task, long delay) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleSyncDelayedTask'"); + } + + @Override + public int scheduleSyncDelayedTask(@NotNull Plugin plugin, @NotNull BukkitRunnable task, long delay) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleSyncDelayedTask'"); + } + + @Override + public int scheduleSyncDelayedTask(@NotNull Plugin plugin, @NotNull Runnable task) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleSyncDelayedTask'"); + } + + @Override + public int scheduleSyncDelayedTask(@NotNull Plugin plugin, @NotNull BukkitRunnable task) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleSyncDelayedTask'"); + } + + @Override + public int scheduleSyncRepeatingTask(@NotNull Plugin plugin, @NotNull Runnable task, long delay, long period) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleSyncRepeatingTask'"); + } + + @Override + public int scheduleSyncRepeatingTask(@NotNull Plugin plugin, @NotNull BukkitRunnable task, long delay, + long period) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleSyncRepeatingTask'"); + } + + @Override + public int scheduleAsyncDelayedTask(@NotNull Plugin plugin, @NotNull Runnable task, long delay) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleAsyncDelayedTask'"); + } + + @Override + public int scheduleAsyncDelayedTask(@NotNull Plugin plugin, @NotNull Runnable task) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleAsyncDelayedTask'"); + } + + @Override + public int scheduleAsyncRepeatingTask(@NotNull Plugin plugin, @NotNull Runnable task, long delay, long period) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'scheduleAsyncRepeatingTask'"); + } + + @Override + public @NotNull Future callSyncMethod(@NotNull Plugin plugin, @NotNull Callable task) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'callSyncMethod'"); + } + + @Override + public void cancelTask(int taskId) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'cancelTask'"); + } + + @Override + public void cancelTasks(@NotNull Plugin plugin) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'cancelTasks'"); + } + + @Override + public boolean isCurrentlyRunning(int taskId) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'isCurrentlyRunning'"); + } + + @Override + public boolean isQueued(int taskId) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'isQueued'"); + } + + @Override + public @NotNull List getActiveWorkers() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getActiveWorkers'"); + } + + @Override + public @NotNull List getPendingTasks() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getPendingTasks'"); + } + + @Override + public @NotNull BukkitTask runTask(@NotNull Plugin plugin, @NotNull Runnable task) throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTask'"); + } + + @Override + public void runTask(@NotNull Plugin plugin, @NotNull Consumer task) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTask'"); + } + + @Override + public @NotNull BukkitTask runTask(@NotNull Plugin plugin, @NotNull BukkitRunnable task) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTask'"); + } + + @Override + public @NotNull BukkitTask runTaskAsynchronously(@NotNull Plugin plugin, @NotNull Runnable task) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskAsynchronously'"); + } + + @Override + public void runTaskAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskAsynchronously'"); + } + + @Override + public @NotNull BukkitTask runTaskAsynchronously(@NotNull Plugin plugin, @NotNull BukkitRunnable task) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskAsynchronously'"); + } + + @Override + public @NotNull BukkitTask runTaskLater(@NotNull Plugin plugin, @NotNull Runnable task, long delay) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskLater'"); + } + + @Override + public void runTaskLater(@NotNull Plugin plugin, @NotNull Consumer task, long delay) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskLater'"); + } + + @Override + public @NotNull BukkitTask runTaskLater(@NotNull Plugin plugin, @NotNull BukkitRunnable task, long delay) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskLater'"); + } + + @Override + public @NotNull BukkitTask runTaskLaterAsynchronously(@NotNull Plugin plugin, @NotNull Runnable task, long delay) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskLaterAsynchronously'"); + } + + @Override + public void runTaskLaterAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task, + long delay) throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskLaterAsynchronously'"); + } + + @Override + public @NotNull BukkitTask runTaskLaterAsynchronously(@NotNull Plugin plugin, @NotNull BukkitRunnable task, + long delay) throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskLaterAsynchronously'"); + } + + @Override + public @NotNull BukkitTask runTaskTimer(@NotNull Plugin plugin, @NotNull Runnable task, long delay, long period) + throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskTimer'"); + } + + @Override + public void runTaskTimer(@NotNull Plugin plugin, @NotNull Consumer task, long delay, + long period) throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskTimer'"); + } + + @Override + public @NotNull BukkitTask runTaskTimer(@NotNull Plugin plugin, @NotNull BukkitRunnable task, long delay, + long period) throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskTimer'"); + } + + @Override + public @NotNull BukkitTask runTaskTimerAsynchronously(@NotNull Plugin plugin, @NotNull Runnable task, long delay, + long period) throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskTimerAsynchronously'"); + } + + @Override + public void runTaskTimerAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task, + long delay, long period) throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskTimerAsynchronously'"); + } + + @Override + public @NotNull BukkitTask runTaskTimerAsynchronously(@NotNull Plugin plugin, @NotNull BukkitRunnable task, + long delay, long period) throws IllegalArgumentException { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'runTaskTimerAsynchronously'"); + } + + @Override + public @NotNull Executor getMainThreadExecutor(@NotNull Plugin plugin) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getMainThreadExecutor'"); + } + +} diff --git a/rust/src/config/spigot.rs b/rust/src/config/spigot.rs index 259ad10..3e18f5d 100644 --- a/rust/src/config/spigot.rs +++ b/rust/src/config/spigot.rs @@ -8,8 +8,10 @@ pub const SPIGOT_PLUGIN_CONFIG: &str = "plugin.yml"; #[derive(Debug, Deserialize, Default, Clone, PartialEq)] #[serde(rename_all = "UPPERCASE")] pub enum LoadOrder { + #[serde(alias = "startup", alias = "Startup")] Startup, #[default] + #[serde(alias = "postworld", alias = "Postworld")] Postworld, } diff --git a/rust/src/plugin/manager.rs b/rust/src/plugin/manager.rs index 56acfc5..2b4d2d0 100644 --- a/rust/src/plugin/manager.rs +++ b/rust/src/plugin/manager.rs @@ -6,7 +6,15 @@ use std::{ use anyhow::Result; use j4rs::{Instance, InvocationArg, Jvm}; -use pumpkin::{command::tree::CommandTree, plugin::Context, server::Server}; +use pumpkin::{ + command::{ + tree::{ + CommandTree, + builder::{argument, literal}, + }, + }, + plugin::Context, +}; use pumpkin_util::permission::{Permission, PermissionDefault}; use tokio::{runtime::Handle, sync::mpsc}; @@ -333,18 +341,50 @@ impl PluginManager { ], )?; } - let node = + let j_sender = jvm + .invoke_static( + "org.bukkit.Bukkit", + "getConsoleSender", + InvocationArg::empty(), + ) + .map_err(|e| e.to_string()) + .unwrap(); + + // Make the tab working, at least the first thingy + let dispatch_result = jvm + .invoke( + &command_map, + "tabComplete", + &[ + InvocationArg::from(j_sender), + InvocationArg::try_from(format!("{} ", cmd_name)).unwrap(), + ], + ) + .unwrap(); + + let tab_list: Vec = jvm.to_rust(dispatch_result).unwrap(); + + let mut node = CommandTree::new([cmd_name], cmd_data.description.clone().unwrap_or_default()) .execute(JavaCommandExecutor { cmd_name: cmd_name.clone(), command_tx: command_tx.clone(), command: j_plugin_cmd.clone(), }); - let permission = if let Some(perm) = cmd_data.permission.clone() { - perm - } else { - format!("patchbukkit:{}", cmd_name) // TODO - }; + for tab in tab_list { + node = node.then(literal(tab).execute(JavaCommandExecutor { + cmd_name: cmd_name.clone(), + command_tx: command_tx.clone(), + command: j_plugin_cmd.clone(), + })); + } + // TODO + // let permission = if let Some(perm) = cmd_data.permission.clone() { + // perm + // } else { + // format!("patchbukkit:{}", cmd_name) // TODO + // }; + let permission = format!("patchbukkit:{}", cmd_name); futures::executor::block_on(async { server