From 2392494a2bdd217f0e2a55b83505880c5e996221 Mon Sep 17 00:00:00 2001 From: NullPepper <97275132+jlxnb@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:31:52 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=88=9B=E5=BB=BAEventListener=E5=9F=BA?= =?UTF-8?q?=E7=B1=BB=20=E4=BC=98=E5=8C=96=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 3 + .../dev/neovoxel/neobot/bot/BotListener.java | 75 ++++++------------- .../neobot/game/GameEventListener.java | 46 +----------- .../neovoxel/neobot/misc/EventListener.java | 51 +++++++++++++ 4 files changed, 79 insertions(+), 96 deletions(-) create mode 100644 common/src/main/java/dev/neovoxel/neobot/misc/EventListener.java diff --git a/build.gradle.kts b/build.gradle.kts index 4191cbd..9d20ff7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,6 +32,9 @@ subprojects { compileOnly("org.slf4j:slf4j-api:2.0.17") compileOnly("org.graalvm.js:js:22.0.0.2") + // plugins + compileOnly("org.pf4j:pf4j:3.6.0") + // storage compileOnly("dev.neovoxel.nsapi:NeoStorageAPI:1.1.0") compileOnly("com.zaxxer:HikariCP:4.0.3") diff --git a/common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java b/common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java index 614e6b2..eecd324 100644 --- a/common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java +++ b/common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java @@ -14,6 +14,7 @@ import dev.neovoxel.nbapi.listener.NBotListener; import dev.neovoxel.neobot.NeoBot; import dev.neovoxel.neobot.bot.types.NGroupMessageEvent; +import dev.neovoxel.neobot.misc.EventListener; import org.graalvm.polyglot.HostAccess; import org.graalvm.polyglot.Value; import org.json.JSONArray; @@ -23,39 +24,24 @@ import java.util.List; import java.util.Map; -public class BotListener implements NBotListener { - private final NeoBot plugin; - - private final Map map = new LinkedHashMap<>(); +public class BotListener extends EventListener implements NBotListener { public BotListener(NeoBot plugin) { - this.plugin = plugin; + super(plugin); } @HostAccess.Export public void sendGroupMessage(long groupId, String message) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SendGroupMessage(groupId, new JSONArray(message))); } }); } - public void clearUuidContext(String uuid) { - List toRemove = new ArrayList<>(); - for (Map.Entry entry : map.entrySet()) { - if (entry.getKey().getContext().getBindings("js").getMember("__uuid__").asString().equals(uuid)) { - toRemove.add(entry.getKey()); - } - } - for (Value value : toRemove) { - map.remove(value); - } - } - @HostAccess.Export public void sendPrivateMessage(long userId, String message) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SendPrivateMessage(userId, new JSONArray(message))); } @@ -64,7 +50,7 @@ public void sendPrivateMessage(long userId, String message) { @HostAccess.Export public void renameGroupMember(long groupId, long userId, String name) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupCard(groupId, userId, name)); } @@ -73,7 +59,7 @@ public void renameGroupMember(long groupId, long userId, String name) { @HostAccess.Export public void muteGroupMember(long groupId, long userId, int duration) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupBan(groupId, userId, duration)); } @@ -82,7 +68,7 @@ public void muteGroupMember(long groupId, long userId, int duration) { @HostAccess.Export public void muteAllGroupMember(long groupId) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupWholeBan(groupId, true)); } @@ -91,7 +77,7 @@ public void muteAllGroupMember(long groupId) { @HostAccess.Export public void unMuteAllGroupMember(long groupId) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupWholeBan(groupId, false)); } @@ -100,7 +86,7 @@ public void unMuteAllGroupMember(long groupId) { @HostAccess.Export public void kickGroupMember(long groupId, long userId) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupKick(groupId, userId)); } @@ -109,7 +95,7 @@ public void kickGroupMember(long groupId, long userId) { @HostAccess.Export public void approveGroupRequest(String flag, String type) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupAddRequest(flag, GroupRequestType.from(type))); } @@ -118,7 +104,7 @@ public void approveGroupRequest(String flag, String type) { @HostAccess.Export public void rejectGroupRequest(String flag, String type) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupAddRequest(flag, GroupRequestType.from(type), false)); } @@ -127,7 +113,7 @@ public void rejectGroupRequest(String flag, String type) { @HostAccess.Export public void approveFriendRequest(String flag) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetFriendAddRequest(flag)); } @@ -136,7 +122,7 @@ public void approveFriendRequest(String flag) { @HostAccess.Export public void rejectFriendRequest(String flag) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetFriendAddRequest(flag, false)); } @@ -145,7 +131,7 @@ public void rejectFriendRequest(String flag) { @HostAccess.Export public void setGroupSpecialTitle(long groupId, long userId, String title, long duration) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupSpecialTitle(groupId, userId, title, duration)); } @@ -154,7 +140,7 @@ public void setGroupSpecialTitle(long groupId, long userId, String title, long d @HostAccess.Export public void setGroupWholeBan(long groupId, boolean enable) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupWholeBan(groupId, enable)); } @@ -163,7 +149,7 @@ public void setGroupWholeBan(long groupId, boolean enable) { @HostAccess.Export public void recallMessage(long messageId) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new DeleteMessage(messageId)); } @@ -173,7 +159,7 @@ public void recallMessage(long messageId) { @HostAccess.Export public void getGroupMemberInfo(long groupId, long userId, Value method) { if (method.canExecute()) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new GetGroupMemberInfo(groupId, userId), method::execute); } else { @@ -186,7 +172,7 @@ public void getGroupMemberInfo(long groupId, long userId, Value method) { @HostAccess.Export public void getGroupMemberList(long groupId, Value method) { if (method.canExecute()) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new GetGroupMemberList(groupId), method::execute); } else method.execute(new ArrayList<>()); @@ -197,7 +183,7 @@ public void getGroupMemberList(long groupId, Value method) { @HostAccess.Export public void getFriendList(Value method) { if (method.canExecute()) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new GetFriendList(), method::execute); } else method.execute(new ArrayList<>()); @@ -208,7 +194,7 @@ public void getFriendList(Value method) { @HostAccess.Export public void getGroupList(Value method) { if (method.canExecute()) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new GetGroupList(), method::execute); } else method.execute(new ArrayList<>()); @@ -219,30 +205,13 @@ public void getGroupList(Value method) { @HostAccess.Export public void getGroupInfo(long groupId, Value method) { if (method.canExecute()) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new GetGroupInfo(groupId), method::execute); } else method.execute(new ArrayList<>()); }); } } - - @HostAccess.Export - public void register(String eventName, Value method) { - if (method.canExecute()) map.put(method, eventName); - } - - public void reset() { - map.clear(); - } - - private void fireEvent(String eventName, NEvent event) { - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().equals(eventName)) { - entry.getKey().execute(event); - } - } - } @NBotEventHandler private void onGroupMessage(GroupMessageEvent event) { diff --git a/common/src/main/java/dev/neovoxel/neobot/game/GameEventListener.java b/common/src/main/java/dev/neovoxel/neobot/game/GameEventListener.java index 5788ce4..d55a635 100644 --- a/common/src/main/java/dev/neovoxel/neobot/game/GameEventListener.java +++ b/common/src/main/java/dev/neovoxel/neobot/game/GameEventListener.java @@ -4,51 +4,11 @@ import dev.neovoxel.neobot.game.event.ChatEvent; import dev.neovoxel.neobot.game.event.LoginEvent; import dev.neovoxel.neobot.adapter.Player; -import org.graalvm.polyglot.HostAccess; -import org.graalvm.polyglot.Value; - -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; - -public class GameEventListener { - - private final NeoBot plugin; - - private final Map map = new IdentityHashMap<>(); +import dev.neovoxel.neobot.misc.EventListener; +public class GameEventListener extends EventListener { public GameEventListener(NeoBot plugin) { - this.plugin = plugin; - } - - public void reset() { - map.clear(); - } - - @HostAccess.Export - public void register(String eventName, Value method) { - if (method.canExecute()) map.put(method, eventName); - } - - public void clearUuidContext(String uuid) { - List toRemove = new ArrayList<>(); - for (Map.Entry entry : map.entrySet()) { - if (entry.getKey().getContext().getBindings("js").getMember("__uuid__").asString().equals(uuid)) { - toRemove.add(entry.getKey()); - } - } - for (Value value : toRemove) { - map.remove(value); - } - } - - private void fireEvent(String eventName, Object... args) { - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().equals(eventName)) { - entry.getKey().execute(args); - } - } + super(plugin); } public void onLogin(LoginEvent event) { diff --git a/common/src/main/java/dev/neovoxel/neobot/misc/EventListener.java b/common/src/main/java/dev/neovoxel/neobot/misc/EventListener.java new file mode 100644 index 0000000..a9dc765 --- /dev/null +++ b/common/src/main/java/dev/neovoxel/neobot/misc/EventListener.java @@ -0,0 +1,51 @@ +package dev.neovoxel.neobot.misc; + +import dev.neovoxel.nbapi.event.NEvent; +import dev.neovoxel.neobot.NeoBot; +import lombok.Getter; +import org.graalvm.polyglot.HostAccess; +import org.graalvm.polyglot.Value; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class EventListener { + @Getter + private final NeoBot plugin; + + private final Map map = new LinkedHashMap<>(); + + public EventListener(NeoBot plugin) { + this.plugin = plugin; + } + @HostAccess.Export + public void register(String eventName, Value method) { + if (method.canExecute()) map.put(method, eventName); + } + + public void reset() { + map.clear(); + } + + protected void fireEvent(String eventName, Object... args) { + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().equals(eventName)) { + entry.getKey().execute(args); + } + } + } + + public void clearUuidContext(String uuid) { + List toRemove = new ArrayList<>(); + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey().getContext().getBindings("js").getMember("__uuid__").asString().equals(uuid)) { + toRemove.add(entry.getKey()); + } + } + for (Value value : toRemove) { + map.remove(value); + } + } +} From 1284a52023f4f27de38c4dcb124a4b43b6fd8440 Mon Sep 17 00:00:00 2001 From: NullPepper <97275132+jlxnb@users.noreply.github.com> Date: Fri, 2 Jan 2026 19:54:26 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat:=E6=8F=92=E4=BB=B6=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/neovoxel/neobot/NeoBotBukkit.java | 27 +++++++++++++ .../extension/BukkitExtensionsManager.java | 10 +++++ .../main/java/dev/neovoxel/neobot/NeoBot.java | 10 ++++- .../neobot/extension/ExtensionsManager.java | 40 +++++++++++++++++++ .../neobot/extension/ListenerProvider.java | 8 ++++ .../neobot/extension/PluginsProvider.java | 12 ++++++ .../neovoxel/neobot/misc/EventListener.java | 1 - .../dev/neovoxel/neobot/NeoBotVelocity.java | 31 +++++++++++++- .../extension/VelocityExtensionsManager.java | 10 +++++ 9 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 bukkit/src/main/java/dev/neovoxel/neobot/extension/BukkitExtensionsManager.java create mode 100644 common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java create mode 100644 common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java create mode 100644 common/src/main/java/dev/neovoxel/neobot/extension/PluginsProvider.java create mode 100644 velocity/src/main/java/dev/neovoxel/neobot/extension/VelocityExtensionsManager.java diff --git a/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java b/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java index 2c891de..98c4e28 100644 --- a/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java +++ b/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java @@ -11,6 +11,8 @@ import dev.neovoxel.neobot.config.ScriptConfig; import dev.neovoxel.neobot.event.BukkitEventManager; import dev.neovoxel.neobot.game.GameEventListener; +import dev.neovoxel.neobot.misc.EventListener; +import dev.neovoxel.neobot.extension.BukkitExtensionsManager; import dev.neovoxel.neobot.scheduler.ScheduledTask; import dev.neovoxel.neobot.script.ScriptProvider; import dev.neovoxel.neobot.script.ScriptScheduler; @@ -35,6 +37,10 @@ public class NeoBotBukkit extends JavaPlugin implements NeoBot { @Setter private ScriptProvider scriptProvider; + @Getter + @Setter + private BukkitExtensionsManager pluginsManager; + @Getter(onMethod_ = {@HostAccess.Export}) @Setter private StorageProvider storageProvider; @@ -68,12 +74,33 @@ public NeoLogger getNeoLogger() { return new BukkitLogger(getLogger()); } + @Override + public void initPluginsManager() { + pluginsManager = new BukkitExtensionsManager(); + } + @Override public void setGameEventListener(GameEventListener listener) { Bukkit.getPluginManager().registerEvents(new BukkitEventManager(this), this); this.gameEventListener = listener; } + @Override + public List getListeners(){ + return pluginsManager.getListenerList(); + } + + @Override + public void loadPlugins(NeoBot plugin) { + pluginsManager.loadExtensions(plugin); + } + + @Override + public void unloadPlugins() { + pluginsManager.unloadExtensions(); + } + + @Override public ScheduledTask submit(Runnable task) { return new BukkitScheduledTask(Bukkit.getScheduler().runTask(this, task)); diff --git a/bukkit/src/main/java/dev/neovoxel/neobot/extension/BukkitExtensionsManager.java b/bukkit/src/main/java/dev/neovoxel/neobot/extension/BukkitExtensionsManager.java new file mode 100644 index 0000000..6980b1d --- /dev/null +++ b/bukkit/src/main/java/dev/neovoxel/neobot/extension/BukkitExtensionsManager.java @@ -0,0 +1,10 @@ +package dev.neovoxel.neobot.extension; + +import dev.neovoxel.neobot.NeoBot; + +public class BukkitExtensionsManager extends ExtensionsManager { + @Override + public void loadExtensions(NeoBot plugin) { + super.loadExtensions(plugin); + } +} diff --git a/common/src/main/java/dev/neovoxel/neobot/NeoBot.java b/common/src/main/java/dev/neovoxel/neobot/NeoBot.java index e69ef8b..4e03ea8 100644 --- a/common/src/main/java/dev/neovoxel/neobot/NeoBot.java +++ b/common/src/main/java/dev/neovoxel/neobot/NeoBot.java @@ -9,6 +9,7 @@ import dev.neovoxel.neobot.game.GameEventListener; import dev.neovoxel.neobot.game.GameProvider; import dev.neovoxel.neobot.library.LibraryProvider; +import dev.neovoxel.neobot.extension.PluginsProvider; import dev.neovoxel.neobot.scheduler.SchedulerProvider; import dev.neovoxel.neobot.script.ScriptProvider; import dev.neovoxel.neobot.script.ScriptScheduler; @@ -17,7 +18,7 @@ import java.io.File; -public interface NeoBot extends ConfigProvider, GameProvider, LibraryProvider, SchedulerProvider { +public interface NeoBot extends PluginsProvider, ConfigProvider, GameProvider, LibraryProvider, SchedulerProvider { default void enable() { try { getNeoLogger().info("Loading libraries..."); @@ -35,6 +36,9 @@ default void enable() { BotProvider botProvider = new BotProvider(this); setBotProvider(botProvider); getBotProvider().loadBot(this); + getNeoLogger().info("Loading plugins..."); + initPluginsManager(); + loadPlugins(this); getNeoLogger().info("Loading script system..."); submitAsync(() -> { try { @@ -61,6 +65,8 @@ default void disable() { getScriptProvider().unloadScript(); getBotProvider().getBotListener().reset(); getGameEventListener().reset(); + getNeoLogger().info("Unloading all plugins..."); + unloadPlugins(); getNeoLogger().info("Cancelling all the tasks..."); cancelAllTasks(); getScriptScheduler().clear(); @@ -101,6 +107,8 @@ default void reload(CommandSender sender) { File getDataFolder(); + void initPluginsManager(); + void setGameEventListener(GameEventListener listener); GameEventListener getGameEventListener(); diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java new file mode 100644 index 0000000..76b9cbb --- /dev/null +++ b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java @@ -0,0 +1,40 @@ +package dev.neovoxel.neobot.extension; + +import dev.neovoxel.neobot.NeoBot; +import dev.neovoxel.neobot.misc.EventListener; +import lombok.Getter; +import org.pf4j.DefaultPluginManager; +import org.pf4j.PluginManager; + + +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class ExtensionsManager { + PluginManager pluginManager; + @Getter + List listenerList = new ArrayList<>(); + public void loadExtensions(NeoBot plugin){ + // 初始化插件管理器 + PluginManager pluginManager = new DefaultPluginManager(Paths.get(plugin.getDataFolder().getAbsolutePath(),"plugins")); + pluginManager.loadPlugins(); + + // 启动插件 + pluginManager.startPlugins(); + + // 获取所有实现了 ListenerProvider 的扩展 + List extensions = pluginManager.getExtensions(ListenerProvider.class); + for (ListenerProvider ext : extensions) { + listenerList.add(ext.getListener()); + } + } + + public void unloadExtensions(){ + for(EventListener listener : listenerList){ + listener.reset(); + } + pluginManager.stopPlugins(); + } + +} diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java b/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java new file mode 100644 index 0000000..dd028da --- /dev/null +++ b/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java @@ -0,0 +1,8 @@ +package dev.neovoxel.neobot.extension; + +import dev.neovoxel.neobot.misc.EventListener; +import org.pf4j.ExtensionPoint; + +public interface ListenerProvider extends ExtensionPoint { + EventListener getListener(); +} diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/PluginsProvider.java b/common/src/main/java/dev/neovoxel/neobot/extension/PluginsProvider.java new file mode 100644 index 0000000..c277e9b --- /dev/null +++ b/common/src/main/java/dev/neovoxel/neobot/extension/PluginsProvider.java @@ -0,0 +1,12 @@ +package dev.neovoxel.neobot.extension; + +import dev.neovoxel.neobot.NeoBot; +import dev.neovoxel.neobot.misc.EventListener; + +import java.util.List; + +public interface PluginsProvider { + List getListeners(); + void loadPlugins(NeoBot plugin); + void unloadPlugins(); +} diff --git a/common/src/main/java/dev/neovoxel/neobot/misc/EventListener.java b/common/src/main/java/dev/neovoxel/neobot/misc/EventListener.java index a9dc765..ce95ab0 100644 --- a/common/src/main/java/dev/neovoxel/neobot/misc/EventListener.java +++ b/common/src/main/java/dev/neovoxel/neobot/misc/EventListener.java @@ -1,6 +1,5 @@ package dev.neovoxel.neobot.misc; -import dev.neovoxel.nbapi.event.NEvent; import dev.neovoxel.neobot.NeoBot; import lombok.Getter; import org.graalvm.polyglot.HostAccess; diff --git a/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java b/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java index 0bcd1f4..a5ae3e0 100644 --- a/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java +++ b/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java @@ -16,13 +16,14 @@ import dev.neovoxel.neobot.event.VelocityEventManager; import dev.neovoxel.neobot.game.GameEventListener; import dev.neovoxel.neobot.loader.VelocityLibraryLoader; +import dev.neovoxel.neobot.misc.EventListener; +import dev.neovoxel.neobot.extension.VelocityExtensionsManager; import dev.neovoxel.neobot.scheduler.ScheduledTask; import dev.neovoxel.neobot.script.ScriptProvider; import dev.neovoxel.neobot.script.ScriptScheduler; import dev.neovoxel.neobot.storage.StorageProvider; import lombok.Getter; import lombok.Setter; -import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.graalvm.polyglot.HostAccess; import org.slf4j.Logger; @@ -30,6 +31,7 @@ import java.io.File; import java.nio.file.Path; import java.time.Duration; +import java.util.List; @Plugin(id = "neobot", name = "NeoBot", version = "0.1", authors = {"NeoVoxelDev Team"}, description = "A bot plugin that connects Minecraft with QQ, Kook, Discord, etc.") public class NeoBotVelocity implements NeoBot { @@ -46,6 +48,9 @@ public class NeoBotVelocity implements NeoBot { @Setter private BotProvider botProvider; + @Getter + private VelocityExtensionsManager pluginsManager; + @Getter @Setter private ScriptProvider scriptProvider; @@ -102,6 +107,30 @@ public File getDataFolder() { return dataDirectory.toFile(); } + @Override + public void initPluginsManager() { + pluginsManager = new VelocityExtensionsManager(); + } + + @Override + public List getListeners(){ + return pluginsManager.getListenerList(); + } + + @Override + public void loadPlugins(NeoBot plugin) { + pluginsManager.loadExtensions(plugin); + } + + @Override + public void unloadPlugins() { + pluginsManager.unloadExtensions(); + } + + void initPluginsProvider(){ + pluginsManager = new VelocityExtensionsManager(); + } + @Override public void setGameEventListener(GameEventListener listener) { proxyServer.getEventManager().register(this, new VelocityEventManager(this)); diff --git a/velocity/src/main/java/dev/neovoxel/neobot/extension/VelocityExtensionsManager.java b/velocity/src/main/java/dev/neovoxel/neobot/extension/VelocityExtensionsManager.java new file mode 100644 index 0000000..78385c7 --- /dev/null +++ b/velocity/src/main/java/dev/neovoxel/neobot/extension/VelocityExtensionsManager.java @@ -0,0 +1,10 @@ +package dev.neovoxel.neobot.extension; + +import dev.neovoxel.neobot.NeoBot; + +public class VelocityExtensionsManager extends ExtensionsManager { + @Override + public void loadExtensions(NeoBot plugin) { + super.loadExtensions(plugin); + } +} From e60e851ade49f9d8c285d6a22ce17d3cc28685c7 Mon Sep 17 00:00:00 2001 From: NullPepper <97275132+jlxnb@users.noreply.github.com> Date: Sat, 3 Jan 2026 10:07:49 +0800 Subject: [PATCH 3/6] done --- build.gradle.kts | 2 +- .../dev/neovoxel/neobot/NeoBotBukkit.java | 9 +++---- .../main/java/dev/neovoxel/neobot/NeoBot.java | 17 ++++++++----- .../neobot/extension/ExtensionsManager.java | 24 ++++++++++++++----- .../neobot/extension/ExtensionsProvider.java | 12 ++++++++++ .../neobot/extension/ListenerProvider.java | 4 +++- .../neobot/extension/PluginsProvider.java | 12 ---------- .../neobot/script/ScriptProvider.java | 5 ++++ .../dev/neovoxel/neobot/NeoBotVelocity.java | 10 ++++---- 9 files changed, 60 insertions(+), 35 deletions(-) create mode 100644 common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsProvider.java delete mode 100644 common/src/main/java/dev/neovoxel/neobot/extension/PluginsProvider.java diff --git a/build.gradle.kts b/build.gradle.kts index 9d20ff7..7a22b31 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,7 @@ subprojects { compileOnly("org.graalvm.js:js:22.0.0.2") // plugins - compileOnly("org.pf4j:pf4j:3.6.0") + implementation("org.pf4j:pf4j:3.6.0") // storage compileOnly("dev.neovoxel.nsapi:NeoStorageAPI:1.1.0") diff --git a/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java b/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java index 98c4e28..2c48b65 100644 --- a/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java +++ b/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; @Getter public class NeoBotBukkit extends JavaPlugin implements NeoBot { @@ -86,17 +87,17 @@ public void setGameEventListener(GameEventListener listener) { } @Override - public List getListeners(){ - return pluginsManager.getListenerList(); + public Map getListenerMap(){ + return pluginsManager.getListenerMap(); } @Override - public void loadPlugins(NeoBot plugin) { + public void loadExtensions(NeoBot plugin) { pluginsManager.loadExtensions(plugin); } @Override - public void unloadPlugins() { + public void unloadExtensions() { pluginsManager.unloadExtensions(); } diff --git a/common/src/main/java/dev/neovoxel/neobot/NeoBot.java b/common/src/main/java/dev/neovoxel/neobot/NeoBot.java index 4e03ea8..854606b 100644 --- a/common/src/main/java/dev/neovoxel/neobot/NeoBot.java +++ b/common/src/main/java/dev/neovoxel/neobot/NeoBot.java @@ -9,7 +9,7 @@ import dev.neovoxel.neobot.game.GameEventListener; import dev.neovoxel.neobot.game.GameProvider; import dev.neovoxel.neobot.library.LibraryProvider; -import dev.neovoxel.neobot.extension.PluginsProvider; +import dev.neovoxel.neobot.extension.ExtensionsProvider; import dev.neovoxel.neobot.scheduler.SchedulerProvider; import dev.neovoxel.neobot.script.ScriptProvider; import dev.neovoxel.neobot.script.ScriptScheduler; @@ -18,7 +18,7 @@ import java.io.File; -public interface NeoBot extends PluginsProvider, ConfigProvider, GameProvider, LibraryProvider, SchedulerProvider { +public interface NeoBot extends ExtensionsProvider, ConfigProvider, GameProvider, LibraryProvider, SchedulerProvider { default void enable() { try { getNeoLogger().info("Loading libraries..."); @@ -36,9 +36,9 @@ default void enable() { BotProvider botProvider = new BotProvider(this); setBotProvider(botProvider); getBotProvider().loadBot(this); - getNeoLogger().info("Loading plugins..."); + getNeoLogger().info("Loading extensions..."); initPluginsManager(); - loadPlugins(this); + loadExtensions(this); getNeoLogger().info("Loading script system..."); submitAsync(() -> { try { @@ -65,8 +65,8 @@ default void disable() { getScriptProvider().unloadScript(); getBotProvider().getBotListener().reset(); getGameEventListener().reset(); - getNeoLogger().info("Unloading all plugins..."); - unloadPlugins(); + getNeoLogger().info("Unloading all extensions..."); + unloadExtensions(); getNeoLogger().info("Cancelling all the tasks..."); cancelAllTasks(); getScriptScheduler().clear(); @@ -91,6 +91,11 @@ default void reload(CommandSender sender) { getGameEventListener().reset(); getNeoLogger().info("Reloading scripts..."); getScriptProvider().unloadScript(); + + getNeoLogger().info("Reloading extensions..."); + initPluginsManager(); + loadExtensions(this); + getScriptProvider().loadScript(this); getGameEventListener().onPluginReloaded(); } catch (Throwable e) { diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java index 76b9cbb..d09db70 100644 --- a/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java +++ b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java @@ -7,17 +7,29 @@ import org.pf4j.PluginManager; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class ExtensionsManager { PluginManager pluginManager; @Getter - List listenerList = new ArrayList<>(); + Map listenerMap = new HashMap<>(); public void loadExtensions(NeoBot plugin){ // 初始化插件管理器 - PluginManager pluginManager = new DefaultPluginManager(Paths.get(plugin.getDataFolder().getAbsolutePath(),"plugins")); + Path path = Paths.get(plugin.getDataFolder().getAbsolutePath(),"extensions"); + try { + if (!Files.exists(path)) { + Files.createDirectory(path); + } + }catch(IOException e){ + plugin.getNeoLogger().error("创建目录失败: " + e.getMessage()); + } + PluginManager pluginManager = new DefaultPluginManager(path); pluginManager.loadPlugins(); // 启动插件 @@ -26,13 +38,13 @@ public void loadExtensions(NeoBot plugin){ // 获取所有实现了 ListenerProvider 的扩展 List extensions = pluginManager.getExtensions(ListenerProvider.class); for (ListenerProvider ext : extensions) { - listenerList.add(ext.getListener()); + listenerMap.put(ext.getExtensionName(),ext.getListener(plugin)); } } public void unloadExtensions(){ - for(EventListener listener : listenerList){ - listener.reset(); + for(Map.Entry entry : listenerMap.entrySet()){ + entry.getValue().reset(); } pluginManager.stopPlugins(); } diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsProvider.java b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsProvider.java new file mode 100644 index 0000000..331301b --- /dev/null +++ b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsProvider.java @@ -0,0 +1,12 @@ +package dev.neovoxel.neobot.extension; + +import dev.neovoxel.neobot.NeoBot; +import dev.neovoxel.neobot.misc.EventListener; + +import java.util.Map; + +public interface ExtensionsProvider { + Map getListenerMap(); + void loadExtensions(NeoBot plugin); + void unloadExtensions(); +} diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java b/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java index dd028da..30d2a98 100644 --- a/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java +++ b/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java @@ -1,8 +1,10 @@ package dev.neovoxel.neobot.extension; +import dev.neovoxel.neobot.NeoBot; import dev.neovoxel.neobot.misc.EventListener; import org.pf4j.ExtensionPoint; public interface ListenerProvider extends ExtensionPoint { - EventListener getListener(); + EventListener getListener(NeoBot plugin); + String getExtensionName(); } diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/PluginsProvider.java b/common/src/main/java/dev/neovoxel/neobot/extension/PluginsProvider.java deleted file mode 100644 index c277e9b..0000000 --- a/common/src/main/java/dev/neovoxel/neobot/extension/PluginsProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.neovoxel.neobot.extension; - -import dev.neovoxel.neobot.NeoBot; -import dev.neovoxel.neobot.misc.EventListener; - -import java.util.List; - -public interface PluginsProvider { - List getListeners(); - void loadPlugins(NeoBot plugin); - void unloadPlugins(); -} diff --git a/common/src/main/java/dev/neovoxel/neobot/script/ScriptProvider.java b/common/src/main/java/dev/neovoxel/neobot/script/ScriptProvider.java index ebfeb68..60d6e8c 100644 --- a/common/src/main/java/dev/neovoxel/neobot/script/ScriptProvider.java +++ b/common/src/main/java/dev/neovoxel/neobot/script/ScriptProvider.java @@ -2,6 +2,7 @@ import dev.neovoxel.jarflow.JarFlow; import dev.neovoxel.neobot.NeoBot; +import dev.neovoxel.neobot.misc.EventListener; import dev.neovoxel.neobot.util.ValueWithScript; import dev.neovoxel.neobot.util.http.HttpBuilder; import dev.neovoxel.neobot.util.ws.ExternalWSUtil; @@ -242,6 +243,10 @@ public void loadScript(NeoBot plugin, Script script) throws Throwable { context.getBindings("js").putMember("qq", plugin.getBotProvider().getBotListener()); context.getBindings("js").putMember("plugin", plugin); context.getBindings("js").putMember("gameEvent", plugin.getGameEventListener()); + for(Map.Entry entry : plugin.getListenerMap().entrySet()){ + context.getBindings("js").putMember(entry.getKey(), entry.getValue()); +// System.out.println(entry.getKey()); + } context.getBindings("js").putMember("gameCommand", plugin.getCommandProvider()); context.getBindings("js").putMember("messageConfig", plugin.getMessageConfig()); context.getBindings("js").putMember("generalConfig", plugin.getScriptConfig()); diff --git a/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java b/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java index a5ae3e0..37e4ad8 100644 --- a/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java +++ b/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java @@ -31,7 +31,7 @@ import java.io.File; import java.nio.file.Path; import java.time.Duration; -import java.util.List; +import java.util.Map; @Plugin(id = "neobot", name = "NeoBot", version = "0.1", authors = {"NeoVoxelDev Team"}, description = "A bot plugin that connects Minecraft with QQ, Kook, Discord, etc.") public class NeoBotVelocity implements NeoBot { @@ -113,17 +113,17 @@ public void initPluginsManager() { } @Override - public List getListeners(){ - return pluginsManager.getListenerList(); + public Map getListenerMap(){ + return pluginsManager.getListenerMap(); } @Override - public void loadPlugins(NeoBot plugin) { + public void loadExtensions(NeoBot plugin) { pluginsManager.loadExtensions(plugin); } @Override - public void unloadPlugins() { + public void unloadExtensions() { pluginsManager.unloadExtensions(); } From 3cb0a70ce67b94ceb324e7c95081b3004e4b6306 Mon Sep 17 00:00:00 2001 From: Aurelian2842 Date: Sat, 3 Jan 2026 15:25:13 +0800 Subject: [PATCH 4/6] fix: merge mistakes --- common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java b/common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java index 9e82e87..af03f29 100644 --- a/common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java +++ b/common/src/main/java/dev/neovoxel/neobot/bot/BotListener.java @@ -94,7 +94,7 @@ public void kickGroupMember(long groupId, long userId) { @HostAccess.Export public void approveGroupRequest(String flag, String type) { - plugin.getBotProvider().getBot().forEach(client -> { + getPlugin().getBotProvider().getBot().forEach(client -> { if (client.isConnected()) { client.action(new SetGroupAddRequest(flag, GroupRequestType.from(type))); } From 02a83b5f99c3307266b09e601f316c3410bbfd0c Mon Sep 17 00:00:00 2001 From: NullPepper <97275132+jlxnb@users.noreply.github.com> Date: Sat, 3 Jan 2026 23:56:35 +0800 Subject: [PATCH 5/6] fix --- common/src/main/java/dev/neovoxel/neobot/NeoBot.java | 1 + .../java/dev/neovoxel/neobot/extension/ExtensionsManager.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/dev/neovoxel/neobot/NeoBot.java b/common/src/main/java/dev/neovoxel/neobot/NeoBot.java index 854606b..584258a 100644 --- a/common/src/main/java/dev/neovoxel/neobot/NeoBot.java +++ b/common/src/main/java/dev/neovoxel/neobot/NeoBot.java @@ -93,6 +93,7 @@ default void reload(CommandSender sender) { getScriptProvider().unloadScript(); getNeoLogger().info("Reloading extensions..."); + unloadExtensions(); initPluginsManager(); loadExtensions(this); diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java index d09db70..5b254e9 100644 --- a/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java +++ b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java @@ -29,7 +29,7 @@ public void loadExtensions(NeoBot plugin){ }catch(IOException e){ plugin.getNeoLogger().error("创建目录失败: " + e.getMessage()); } - PluginManager pluginManager = new DefaultPluginManager(path); + pluginManager = new DefaultPluginManager(path); pluginManager.loadPlugins(); // 启动插件 From 08236d4ca68c345c6a4cdf7451c5aa588d8ff7c0 Mon Sep 17 00:00:00 2001 From: NullPepper <97275132+jlxnb@users.noreply.github.com> Date: Fri, 16 Jan 2026 18:40:27 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E5=96=84=E5=90=8E=E5=B7=A5=E4=BD=9C.jpg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/neovoxel/neobot/NeoBotBukkit.java | 13 ++++++------- .../main/java/dev/neovoxel/neobot/NeoBot.java | 6 +++--- .../neobot/extension/ExtensionsManager.java | 19 ++++++++++++++++++- .../neobot/extension/ListenerProvider.java | 4 +++- .../dev/neovoxel/neobot/NeoBotVelocity.java | 3 +-- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java b/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java index 2c48b65..b0e7914 100644 --- a/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java +++ b/bukkit/src/main/java/dev/neovoxel/neobot/NeoBotBukkit.java @@ -40,7 +40,7 @@ public class NeoBotBukkit extends JavaPlugin implements NeoBot { @Getter @Setter - private BukkitExtensionsManager pluginsManager; + private BukkitExtensionsManager extensionsManager; @Getter(onMethod_ = {@HostAccess.Export}) @Setter @@ -75,9 +75,8 @@ public NeoLogger getNeoLogger() { return new BukkitLogger(getLogger()); } - @Override - public void initPluginsManager() { - pluginsManager = new BukkitExtensionsManager(); + public void initExtensionsManager() { + extensionsManager = new BukkitExtensionsManager(); } @Override @@ -88,17 +87,17 @@ public void setGameEventListener(GameEventListener listener) { @Override public Map getListenerMap(){ - return pluginsManager.getListenerMap(); + return extensionsManager.getListenerMap(); } @Override public void loadExtensions(NeoBot plugin) { - pluginsManager.loadExtensions(plugin); + extensionsManager.loadExtensions(plugin); } @Override public void unloadExtensions() { - pluginsManager.unloadExtensions(); + extensionsManager.unloadExtensions(); } diff --git a/common/src/main/java/dev/neovoxel/neobot/NeoBot.java b/common/src/main/java/dev/neovoxel/neobot/NeoBot.java index 584258a..9e44774 100644 --- a/common/src/main/java/dev/neovoxel/neobot/NeoBot.java +++ b/common/src/main/java/dev/neovoxel/neobot/NeoBot.java @@ -37,7 +37,7 @@ default void enable() { setBotProvider(botProvider); getBotProvider().loadBot(this); getNeoLogger().info("Loading extensions..."); - initPluginsManager(); + this.initExtensionsManager(); loadExtensions(this); getNeoLogger().info("Loading script system..."); submitAsync(() -> { @@ -94,7 +94,7 @@ default void reload(CommandSender sender) { getNeoLogger().info("Reloading extensions..."); unloadExtensions(); - initPluginsManager(); + this.initExtensionsManager(); loadExtensions(this); getScriptProvider().loadScript(this); @@ -113,7 +113,7 @@ default void reload(CommandSender sender) { File getDataFolder(); - void initPluginsManager(); + void initExtensionsManager(); void setGameEventListener(GameEventListener listener); diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java index 5b254e9..d9e04a3 100644 --- a/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java +++ b/common/src/main/java/dev/neovoxel/neobot/extension/ExtensionsManager.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; public class ExtensionsManager { PluginManager pluginManager; @@ -38,7 +39,23 @@ public void loadExtensions(NeoBot plugin){ // 获取所有实现了 ListenerProvider 的扩展 List extensions = pluginManager.getExtensions(ListenerProvider.class); for (ListenerProvider ext : extensions) { - listenerMap.put(ext.getExtensionName(),ext.getListener(plugin)); + org.pf4j.PluginWrapper wrapper = pluginManager.whichPlugin(ext.getClass()); + if (wrapper == null){ + continue; + } + org.pf4j.PluginDescriptor descriptor = wrapper.getDescriptor(); + String pluginId = descriptor.getPluginId(); + String version = descriptor.getVersion(); + String provider = descriptor.getProvider(); + if(!Objects.equals(ext.getRequiredPlatform(), "Common") && !Objects.equals(ext.getRequiredPlatform(), plugin.getPlatform())){ + plugin.getNeoLogger().warn(String.format("扩展[%s]要求在[%s]上加载! 当前环境[%s]已自动跳过.", + pluginId, ext.getRequiredPlatform(), plugin.getPlatform())); + continue; + } + plugin.getNeoLogger().info(String.format("加载扩展: %s | 版本: %s | 作者:%s ", + pluginId, version, provider)); + + listenerMap.put(pluginId,ext.getListener(plugin)); } } diff --git a/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java b/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java index 30d2a98..43017c4 100644 --- a/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java +++ b/common/src/main/java/dev/neovoxel/neobot/extension/ListenerProvider.java @@ -6,5 +6,7 @@ public interface ListenerProvider extends ExtensionPoint { EventListener getListener(NeoBot plugin); - String getExtensionName(); + default String getRequiredPlatform() { + return "Common"; + } } diff --git a/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java b/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java index 37e4ad8..39f92c5 100644 --- a/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java +++ b/velocity/src/main/java/dev/neovoxel/neobot/NeoBotVelocity.java @@ -107,8 +107,7 @@ public File getDataFolder() { return dataDirectory.toFile(); } - @Override - public void initPluginsManager() { + public void initExtensionsManager() { pluginsManager = new VelocityExtensionsManager(); }