mirror of
https://github.com/songoda/SongodaCore.git
synced 2025-02-25 07:51:20 +01:00
use core as a service, keep active as long as other registered plugins are active
This commit is contained in:
parent
6a60930a01
commit
782233cbde
15
pom.xml
15
pom.xml
@ -23,6 +23,15 @@
|
||||
<id>private</id>
|
||||
<url>http://repo.songoda.com/artifactory/private/</url>
|
||||
</repository>
|
||||
<!-- sk89q-repo and spigot-repo are required for worldguard -->
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sk89q-repo</id>
|
||||
<url>https://maven.sk89q.com/repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@ -71,5 +80,11 @@
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.23.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldguard</groupId>
|
||||
<artifactId>worldguard-bukkit</artifactId>
|
||||
<version>7.0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -18,7 +18,7 @@ public class PluginInfo {
|
||||
private String marketplaceLink;
|
||||
private JSONObject json;
|
||||
|
||||
public PluginInfo(JavaPlugin javaPlugin, int songodaId) {
|
||||
protected PluginInfo(JavaPlugin javaPlugin, int songodaId) {
|
||||
this.javaPlugin = javaPlugin;
|
||||
this.songodaId = songodaId;
|
||||
}
|
||||
|
@ -1,15 +1,7 @@
|
||||
package com.songoda.core;
|
||||
|
||||
import com.songoda.core.command.CommandManager;
|
||||
import com.songoda.core.listeners.LoginListener;
|
||||
import com.songoda.core.library.commands.CommandManager;
|
||||
import com.songoda.core.modules.Module;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@ -17,32 +9,114 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
public class SongodaCore {
|
||||
|
||||
private static String prefix = "[SongodaCore]";
|
||||
private final static String prefix = "[SongodaCore]";
|
||||
|
||||
private static int updaterVersion = 1;
|
||||
private final static int updaterVersion = 1;
|
||||
|
||||
private static Set<PluginInfo> registeredPlugins = new HashSet<>();
|
||||
private final static Set<PluginInfo> registeredPlugins = new HashSet<>();
|
||||
|
||||
private static SongodaCore INSTANCE;
|
||||
|
||||
private static JavaPlugin hijackedPlugin;
|
||||
private static SongodaCore INSTANCE = null;
|
||||
private JavaPlugin piggybackedPlugin;
|
||||
private final CommandManager commandManager;
|
||||
private final EventListener loginListener = new EventListener();
|
||||
private final HashMap<UUID, Long> lastCheck = new HashMap();
|
||||
|
||||
public static void registerPlugin(JavaPlugin plugin, int pluginID) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public SongodaCore(JavaPlugin javaPlugin) {
|
||||
hijackedPlugin = javaPlugin;
|
||||
Bukkit.getPluginManager().registerEvents(new LoginListener(this), hijackedPlugin);
|
||||
if(INSTANCE == null) {
|
||||
// First: are there any other instances of SongodaCore active?
|
||||
for (Class<?> clazz : Bukkit.getServicesManager().getKnownServices()) {
|
||||
if(clazz.getSimpleName().equals("SongodaCore")) {
|
||||
try {
|
||||
// use the active service
|
||||
clazz.getMethod("registerPlugin", JavaPlugin.class, int.class).invoke(null, plugin, pluginID);
|
||||
return;
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
|
||||
|
||||
new CommandManager(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
// register ourselves as the SongodaCore service!
|
||||
INSTANCE = new SongodaCore(plugin);
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
|
||||
}
|
||||
INSTANCE.hook(new PluginInfo(plugin, pluginID));
|
||||
}
|
||||
|
||||
public SongodaCore(JavaPlugin javaPlugin) {
|
||||
piggybackedPlugin = javaPlugin;
|
||||
commandManager = new CommandManager(javaPlugin);
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);
|
||||
commandManager.addCommand(new SongodaCoreCommand(this))
|
||||
.addSubCommand(new SongodaCoreDiagCommand(this));
|
||||
Bukkit.getPluginManager().registerEvents(loginListener, javaPlugin);
|
||||
}
|
||||
|
||||
private class EventListener implements Listener {
|
||||
@EventHandler
|
||||
void onLogin(PlayerLoginEvent event) {
|
||||
// don't spam players with update checks
|
||||
final Player player = event.getPlayer();
|
||||
long now = System.currentTimeMillis();
|
||||
Long last = lastCheck.get(player.getUniqueId());
|
||||
if(last != null && now - 10000 < last) return;
|
||||
lastCheck.put(player.getUniqueId(), now);
|
||||
// is this player good to revieve update notices?
|
||||
if (!event.getPlayer().isOp() && !player.hasPermission("songoda.updatecheck")) return;
|
||||
// check for updates! ;)
|
||||
for (PluginInfo plugin : getPlugins()) {
|
||||
if (plugin.getNotification() != null && plugin.getJavaPlugin().isEnabled())
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin.getJavaPlugin(), () ->
|
||||
player.sendMessage("[" + plugin.getJavaPlugin().getName() + "] " + plugin.getNotification()), 10L);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
void onDisable(PluginDisableEvent event) {
|
||||
// don't track disabled plugins
|
||||
PluginInfo pi = registeredPlugins.stream().filter(p -> event.getPlugin() == p.getJavaPlugin()).findFirst().orElse(null);
|
||||
if(pi != null) {
|
||||
registeredPlugins.remove(pi);
|
||||
}
|
||||
if(event.getPlugin() == piggybackedPlugin) {
|
||||
System.out.println(prefix + " Is being disabled!!!");
|
||||
// uh-oh! Abandon ship!!
|
||||
Bukkit.getServicesManager().unregisterAll(piggybackedPlugin);
|
||||
// can we move somewhere else?
|
||||
if((pi = registeredPlugins.stream().findFirst().orElse(null)) != null) {
|
||||
System.out.println(prefix + " Moving to " + pi.getJavaPlugin().getName());
|
||||
// move ourselves to this plugin
|
||||
piggybackedPlugin = pi.getJavaPlugin();
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, piggybackedPlugin, ServicePriority.Normal);
|
||||
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hook(PluginInfo plugin) {
|
||||
System.out.println(getPrefix() + "Hooked " + plugin.getJavaPlugin().getName() + ".");
|
||||
registeredPlugins.add(plugin);
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin.getJavaPlugin(), () -> update(plugin), 20L);
|
||||
}
|
||||
|
||||
private void update(PluginInfo plugin) {
|
||||
@ -81,30 +155,6 @@ public class SongodaCore {
|
||||
}
|
||||
}
|
||||
|
||||
public static PluginInfo load(PluginInfo plugin) {
|
||||
boolean found = false;
|
||||
for (Class<?> clazz : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
clazz.getMethod("hook", PluginInfo.class).invoke(null, plugin);
|
||||
found = true;
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (INSTANCE == null) INSTANCE = new SongodaCore(plugin.getJavaPlugin());
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, hijackedPlugin, ServicePriority.Normal);
|
||||
hook(plugin);
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public static void hook(PluginInfo plugin) {
|
||||
System.out.println(getPrefix() + "Hooked " + plugin.getJavaPlugin().getName() + ".");
|
||||
getInstance().update(plugin);
|
||||
registeredPlugins.add(plugin);
|
||||
}
|
||||
|
||||
public List<PluginInfo> getPlugins() {
|
||||
return new ArrayList<>(registeredPlugins);
|
||||
}
|
||||
@ -118,7 +168,7 @@ public class SongodaCore {
|
||||
}
|
||||
|
||||
public static JavaPlugin getHijackedPlugin() {
|
||||
return hijackedPlugin;
|
||||
return INSTANCE == null ? null : INSTANCE.piggybackedPlugin;
|
||||
}
|
||||
|
||||
public static SongodaCore getInstance() {
|
||||
|
46
src/main/java/com/songoda/core/SongodaCoreCommand.java
Normal file
46
src/main/java/com/songoda/core/SongodaCoreCommand.java
Normal file
@ -0,0 +1,46 @@
|
||||
package com.songoda.core;
|
||||
|
||||
import com.songoda.core.library.commands.AbstractCommand;
|
||||
import java.util.List;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
class SongodaCoreCommand extends AbstractCommand {
|
||||
|
||||
final SongodaCore instance;
|
||||
protected SongodaCoreCommand(SongodaCore instance) {
|
||||
super(false, "songoda");
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
if(sender instanceof Player) {
|
||||
new SongodaCoreOverviewGUI(instance, (Player) sender);
|
||||
} else {
|
||||
sender.sendMessage("/songoda diag");
|
||||
}
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "songoda.admin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/songoda";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Displays this interface.";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
package com.songoda.core.command.commands;
|
||||
package com.songoda.core;
|
||||
|
||||
import com.songoda.core.PluginInfo;
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.core.command.AbstractCommand;
|
||||
import com.songoda.core.library.commands.AbstractCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@ -11,8 +9,9 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandDiag extends AbstractCommand {
|
||||
public class SongodaCoreDiagCommand extends AbstractCommand {
|
||||
|
||||
final SongodaCore instance;
|
||||
private final String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
private final String version = name.substring(name.lastIndexOf('.') + 1);
|
||||
|
||||
@ -22,8 +21,9 @@ public class CommandDiag extends AbstractCommand {
|
||||
private Field tpsField;
|
||||
|
||||
|
||||
public CommandDiag(AbstractCommand parent) {
|
||||
super(parent, false, "diag");
|
||||
protected SongodaCoreDiagCommand(SongodaCore instance) {
|
||||
super(false, "diag");
|
||||
this.instance = instance;
|
||||
|
||||
try {
|
||||
serverInstance = getNMSClass("MinecraftServer").getMethod("getServer").invoke(null);
|
||||
@ -36,7 +36,7 @@ public class CommandDiag extends AbstractCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(SongodaCore instance, CommandSender sender, String... args) {
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("Songoda Diagnostics Information");
|
||||
@ -64,7 +64,7 @@ public class CommandDiag extends AbstractCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(SongodaCore instance, CommandSender sender, String... args) {
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1,18 +1,16 @@
|
||||
package com.songoda.core.gui;
|
||||
package com.songoda.core;
|
||||
|
||||
import com.songoda.core.PluginInfo;
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.core.utils.gui.AbstractGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GUIOverview extends AbstractGUI {
|
||||
class SongodaCoreOverviewGUI extends AbstractGUI {
|
||||
|
||||
private final SongodaCore update;
|
||||
|
||||
public GUIOverview(SongodaCore update, Player player) {
|
||||
protected SongodaCoreOverviewGUI(SongodaCore update, Player player) {
|
||||
super(player);
|
||||
this.update = update;
|
||||
|
@ -1,71 +0,0 @@
|
||||
package com.songoda.core.command;
|
||||
|
||||
import com.songoda.core.SongodaCore;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractCommand {
|
||||
|
||||
private final boolean noConsole;
|
||||
private AbstractCommand parent = null;
|
||||
private boolean hasArgs = false;
|
||||
private String command;
|
||||
|
||||
private List<String> subCommand = new ArrayList<>();
|
||||
|
||||
protected AbstractCommand(AbstractCommand parent, boolean noConsole, String... command) {
|
||||
if (parent != null) {
|
||||
this.subCommand = Arrays.asList(command);
|
||||
} else {
|
||||
this.command = Arrays.asList(command).get(0);
|
||||
}
|
||||
this.parent = parent;
|
||||
this.noConsole = noConsole;
|
||||
}
|
||||
|
||||
protected AbstractCommand(boolean noConsole, boolean hasArgs, String... command) {
|
||||
this.command = Arrays.asList(command).get(0);
|
||||
|
||||
this.hasArgs = hasArgs;
|
||||
this.noConsole = noConsole;
|
||||
}
|
||||
|
||||
public AbstractCommand getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public List<String> getSubCommand() {
|
||||
return subCommand;
|
||||
}
|
||||
|
||||
public void addSubCommand(String command) {
|
||||
subCommand.add(command);
|
||||
}
|
||||
|
||||
protected abstract ReturnType runCommand(SongodaCore instance, CommandSender sender, String... args);
|
||||
|
||||
protected abstract List<String> onTab(SongodaCore instance, CommandSender sender, String... args);
|
||||
|
||||
public abstract String getPermissionNode();
|
||||
|
||||
public abstract String getSyntax();
|
||||
|
||||
public abstract String getDescription();
|
||||
|
||||
public boolean hasArgs() {
|
||||
return hasArgs;
|
||||
}
|
||||
|
||||
public boolean isNoConsole() {
|
||||
return noConsole;
|
||||
}
|
||||
|
||||
public enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
package com.songoda.core.command;
|
||||
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.core.command.commands.CommandDiag;
|
||||
import com.songoda.core.command.commands.CommandSongoda;
|
||||
import com.songoda.core.utils.Methods;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandManager implements CommandExecutor {
|
||||
|
||||
private SongodaCore instance;
|
||||
private TabManager tabManager;
|
||||
|
||||
private List<AbstractCommand> commands = new ArrayList<>();
|
||||
|
||||
public CommandManager(SongodaCore instance) {
|
||||
this.instance = instance;
|
||||
this.tabManager = new TabManager(this);
|
||||
|
||||
registerCommandDynamically("songoda", this, tabManager);
|
||||
|
||||
AbstractCommand commandSongoda = addCommand(new CommandSongoda());
|
||||
addCommand(new CommandDiag(commandSongoda));
|
||||
}
|
||||
|
||||
private AbstractCommand addCommand(AbstractCommand abstractCommand) {
|
||||
commands.add(abstractCommand);
|
||||
return abstractCommand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
|
||||
for (AbstractCommand abstractCommand : commands) {
|
||||
if (abstractCommand.getCommand() != null && abstractCommand.getCommand().equalsIgnoreCase(command.getName().toLowerCase())) {
|
||||
if (strings.length == 0 || abstractCommand.hasArgs()) {
|
||||
processRequirements(abstractCommand, commandSender, strings);
|
||||
return true;
|
||||
}
|
||||
} else if (strings.length != 0 && abstractCommand.getParent() != null && abstractCommand.getParent().getCommand().equalsIgnoreCase(command.getName())) {
|
||||
String cmd = strings[0];
|
||||
String cmd2 = strings.length >= 2 ? String.join(" ", strings[0], strings[1]) : null;
|
||||
for (String cmds : abstractCommand.getSubCommand()) {
|
||||
if (cmd.equalsIgnoreCase(cmds) || (cmd2 != null && cmd2.equalsIgnoreCase(cmds))) {
|
||||
processRequirements(abstractCommand, commandSender, strings);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
commandSender.sendMessage(instance.getPrefix() + Methods.formatText("&7The command you entered does not exist or is spelt incorrectly."));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void processRequirements(AbstractCommand command, CommandSender sender, String[] strings) {
|
||||
if (!(sender instanceof Player) && command.isNoConsole()) {
|
||||
sender.sendMessage("You must be a player to use this command.");
|
||||
return;
|
||||
}
|
||||
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
|
||||
AbstractCommand.ReturnType returnType = command.runCommand(instance, sender, strings);
|
||||
if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) {
|
||||
sender.sendMessage(instance.getPrefix() + Methods.formatText("&cInvalid Syntax!"));
|
||||
sender.sendMessage(instance.getPrefix() + Methods.formatText("&7The valid syntax is: &6" + command.getSyntax() + "&7."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(instance.getPrefix() + "You do not have permission to run this command.");
|
||||
}
|
||||
|
||||
public List<AbstractCommand> getCommands() {
|
||||
return Collections.unmodifiableList(commands);
|
||||
}
|
||||
|
||||
public static void registerCommandDynamically(String command, CommandExecutor executor, TabManager tabManager) {
|
||||
try {
|
||||
// Retrieve the SimpleCommandMap from the server
|
||||
Class<?> classCraftServer = Bukkit.getServer().getClass();
|
||||
Field fieldCommandMap = classCraftServer.getDeclaredField("commandMap");
|
||||
fieldCommandMap.setAccessible(true);
|
||||
SimpleCommandMap commandMap = (SimpleCommandMap) fieldCommandMap.get(Bukkit.getServer());
|
||||
|
||||
// Construct a new Command object
|
||||
Constructor<PluginCommand> constructorPluginCommand = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
|
||||
constructorPluginCommand.setAccessible(true);
|
||||
PluginCommand commandObject = constructorPluginCommand.newInstance(command, SongodaCore.getHijackedPlugin());
|
||||
commandObject.setExecutor(executor);
|
||||
|
||||
// Set tab complete
|
||||
commandObject.setTabCompleter(tabManager);
|
||||
|
||||
// Register the command
|
||||
Field fieldKnownCommands = SimpleCommandMap.class.getDeclaredField("knownCommands");
|
||||
fieldKnownCommands.setAccessible(true);
|
||||
Map<String, Command> knownCommands = (Map<String, Command>) fieldKnownCommands.get(commandMap);
|
||||
knownCommands.put(command, commandObject);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.songoda.core.command;
|
||||
|
||||
import com.songoda.core.SongodaCore;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TabManager implements TabCompleter {
|
||||
|
||||
private final CommandManager commandManager;
|
||||
|
||||
TabManager(CommandManager commandManager) {
|
||||
this.commandManager = commandManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] strings) {
|
||||
for (AbstractCommand abstractCommand : commandManager.getCommands()) {
|
||||
if (abstractCommand.getCommand() != null && abstractCommand.getCommand().equalsIgnoreCase(command.getName()) && !abstractCommand.hasArgs()) {
|
||||
if (strings.length == 1) {
|
||||
List<String> subs = new ArrayList<>();
|
||||
for (AbstractCommand ac : commandManager.getCommands()) {
|
||||
if (ac.getSubCommand() == null) continue;
|
||||
subs.addAll(ac.getSubCommand());
|
||||
}
|
||||
subs.removeIf(s -> !s.toLowerCase().startsWith(strings[0].toLowerCase()));
|
||||
return subs;
|
||||
}
|
||||
} else if (strings.length != 0
|
||||
&& abstractCommand.getCommand() != null
|
||||
&& abstractCommand.getCommand().equalsIgnoreCase(command.getName().toLowerCase())) {
|
||||
String cmd = strings[0];
|
||||
String cmd2 = strings.length >= 2 ? String.join(" ", strings[0], strings[1]) : null;
|
||||
if (abstractCommand.hasArgs()) {
|
||||
return onCommand(abstractCommand, strings, sender);
|
||||
} else {
|
||||
for (String cmds : abstractCommand.getSubCommand()) {
|
||||
if (cmd.equalsIgnoreCase(cmds) || (cmd2 != null && cmd2.equalsIgnoreCase(cmds))) {
|
||||
return onCommand(abstractCommand, strings, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private List<String> onCommand(AbstractCommand abstractCommand, String[] strings, CommandSender sender) {
|
||||
List<String> list = abstractCommand.onTab(SongodaCore.getInstance(), sender, strings);
|
||||
String str = strings[strings.length - 1];
|
||||
if (list != null && str != null && str.length() >= 1) {
|
||||
try {
|
||||
list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase()));
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package com.songoda.core.command.commands;
|
||||
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.core.command.AbstractCommand;
|
||||
import com.songoda.core.gui.GUIOverview;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommandSongoda extends AbstractCommand {
|
||||
|
||||
public CommandSongoda() {
|
||||
super(true, false, "songoda");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(SongodaCore instance, CommandSender sender, String... args) {
|
||||
new GUIOverview(instance, (Player) sender);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(SongodaCore instance, CommandSender sender, String... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "songoda.admin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/songoda";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Displays this interface.";
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package com.songoda.core.library.commands;
|
||||
|
||||
import com.songoda.core.utils.Methods;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -13,8 +15,12 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
@ -205,4 +211,31 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void registerCommandDynamically(Plugin plugin, String command, CommandExecutor executor, TabCompleter tabManager) {
|
||||
try {
|
||||
// Retrieve the SimpleCommandMap from the server
|
||||
Class<?> classCraftServer = Bukkit.getServer().getClass();
|
||||
Field fieldCommandMap = classCraftServer.getDeclaredField("commandMap");
|
||||
fieldCommandMap.setAccessible(true);
|
||||
SimpleCommandMap commandMap = (SimpleCommandMap) fieldCommandMap.get(Bukkit.getServer());
|
||||
|
||||
// Construct a new Command object
|
||||
Constructor<PluginCommand> constructorPluginCommand = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
|
||||
constructorPluginCommand.setAccessible(true);
|
||||
PluginCommand commandObject = constructorPluginCommand.newInstance(command, plugin);
|
||||
commandObject.setExecutor(executor);
|
||||
|
||||
// Set tab complete
|
||||
commandObject.setTabCompleter(tabManager);
|
||||
|
||||
// Register the command
|
||||
Field fieldKnownCommands = SimpleCommandMap.class.getDeclaredField("knownCommands");
|
||||
fieldKnownCommands.setAccessible(true);
|
||||
Map<String, Command> knownCommands = (Map<String, Command>) fieldKnownCommands.get(commandMap);
|
||||
knownCommands.put(command, commandObject);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user