Add WG Hooks, Change Economy to support easy static useage, Add playerutils, fix ServerVersion, simplify commandmanager registration, prep work for updater
This commit is contained in:
parent
206baa86a8
commit
6790f0680a
|
@ -7,7 +7,7 @@ import org.json.simple.JSONObject;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Plugin {
|
||||
public class PluginInfo {
|
||||
|
||||
private JavaPlugin javaPlugin;
|
||||
private int songodaId;
|
||||
|
@ -18,7 +18,7 @@ public class Plugin {
|
|||
private String marketplaceLink;
|
||||
private JSONObject json;
|
||||
|
||||
public Plugin(JavaPlugin javaPlugin, int songodaId) {
|
||||
public PluginInfo(JavaPlugin javaPlugin, int songodaId) {
|
||||
this.javaPlugin = javaPlugin;
|
||||
this.songodaId = songodaId;
|
||||
}
|
|
@ -25,14 +25,19 @@ public class SongodaCore {
|
|||
|
||||
private static String prefix = "[SongodaCore]";
|
||||
|
||||
private static int version = 1;
|
||||
private static int updaterVersion = 1;
|
||||
|
||||
private static Set<Plugin> registeredPlugins = new HashSet<>();
|
||||
private static Set<PluginInfo> registeredPlugins = new HashSet<>();
|
||||
|
||||
private static SongodaCore INSTANCE;
|
||||
|
||||
private static JavaPlugin hijackedPlugin;
|
||||
|
||||
public static void registerPlugin(JavaPlugin plugin, int pluginID) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public SongodaCore(JavaPlugin javaPlugin) {
|
||||
hijackedPlugin = javaPlugin;
|
||||
Bukkit.getPluginManager().registerEvents(new LoginListener(this), hijackedPlugin);
|
||||
|
@ -40,11 +45,11 @@ public class SongodaCore {
|
|||
new CommandManager(this);
|
||||
}
|
||||
|
||||
private void update(Plugin plugin) {
|
||||
private void update(PluginInfo plugin) {
|
||||
try {
|
||||
URL url = new URL("http://update.songoda.com/index.php?plugin=" + plugin.getSongodaId()
|
||||
+ "&version=" + plugin.getJavaPlugin().getDescription().getVersion()
|
||||
+ "&updaterVersion=" + version);
|
||||
+ "&updaterVersion=" + updaterVersion);
|
||||
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.setConnectTimeout(5000);
|
||||
InputStream is = urlConnection.getInputStream();
|
||||
|
@ -76,11 +81,11 @@ public class SongodaCore {
|
|||
}
|
||||
}
|
||||
|
||||
public static Plugin load(Plugin plugin) {
|
||||
public static PluginInfo load(PluginInfo plugin) {
|
||||
boolean found = false;
|
||||
for (Class<?> clazz : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
clazz.getMethod("hook", Plugin.class).invoke(null, plugin);
|
||||
clazz.getMethod("hook", PluginInfo.class).invoke(null, plugin);
|
||||
found = true;
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
|
||||
|
||||
|
@ -94,18 +99,18 @@ public class SongodaCore {
|
|||
return plugin;
|
||||
}
|
||||
|
||||
public static void hook(Plugin plugin) {
|
||||
public static void hook(PluginInfo plugin) {
|
||||
System.out.println(getPrefix() + "Hooked " + plugin.getJavaPlugin().getName() + ".");
|
||||
getInstance().update(plugin);
|
||||
registeredPlugins.add(plugin);
|
||||
}
|
||||
|
||||
public List<Plugin> getPlugins() {
|
||||
public List<PluginInfo> getPlugins() {
|
||||
return new ArrayList<>(registeredPlugins);
|
||||
}
|
||||
|
||||
public static int getVersion() {
|
||||
return version;
|
||||
return updaterVersion;
|
||||
}
|
||||
|
||||
public static String getPrefix() {
|
||||
|
|
|
@ -27,7 +27,7 @@ public class CommandManager implements CommandExecutor {
|
|||
this.instance = instance;
|
||||
this.tabManager = new TabManager(this);
|
||||
|
||||
registerCommandDynamically("songoda", this);
|
||||
registerCommandDynamically("songoda", this, tabManager);
|
||||
|
||||
AbstractCommand commandSongoda = addCommand(new CommandSongoda());
|
||||
addCommand(new CommandDiag(commandSongoda));
|
||||
|
@ -81,7 +81,7 @@ public class CommandManager implements CommandExecutor {
|
|||
return Collections.unmodifiableList(commands);
|
||||
}
|
||||
|
||||
private void registerCommandDynamically(String command, CommandExecutor executor) {
|
||||
public static void registerCommandDynamically(String command, CommandExecutor executor, TabManager tabManager) {
|
||||
try {
|
||||
// Retrieve the SimpleCommandMap from the server
|
||||
Class<?> classCraftServer = Bukkit.getServer().getClass();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.songoda.core.command.commands;
|
||||
|
||||
import com.songoda.core.Plugin;
|
||||
import com.songoda.core.PluginInfo;
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.core.command.AbstractCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -42,7 +42,7 @@ public class CommandDiag extends AbstractCommand {
|
|||
sender.sendMessage("Songoda Diagnostics Information");
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("Plugins:");
|
||||
for (Plugin plugin : instance.getPlugins()) {
|
||||
for (PluginInfo plugin : instance.getPlugins()) {
|
||||
sender.sendMessage(plugin.getJavaPlugin().getName()
|
||||
+ " (" + plugin.getJavaPlugin().getDescription().getVersion() + ")");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.songoda.core.gui;
|
||||
|
||||
import com.songoda.core.Plugin;
|
||||
import com.songoda.core.PluginInfo;
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.core.utils.gui.AbstractGUI;
|
||||
import org.bukkit.Material;
|
||||
|
@ -21,9 +21,9 @@ public class GUIOverview extends AbstractGUI {
|
|||
|
||||
@Override
|
||||
protected void constructGUI() {
|
||||
List<Plugin> plugins = update.getPlugins();
|
||||
List<PluginInfo> plugins = update.getPlugins();
|
||||
for (int i = 0; i < plugins.size(); i++) {
|
||||
Plugin plugin = plugins.get(i);
|
||||
PluginInfo plugin = plugins.get(i);
|
||||
|
||||
createButton(i + 9, Material.STONE, "&6" + plugin.getJavaPlugin().getName(),
|
||||
"&7Latest Version: " + plugin.getLatestVersion(),
|
||||
|
|
|
@ -1,51 +1,36 @@
|
|||
package com.songoda.core.library.commands;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
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<>();
|
||||
private final 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;
|
||||
protected AbstractCommand(boolean noConsole, String... command) {
|
||||
this.subCommand.addAll(Arrays.asList(command));
|
||||
this.noConsole = noConsole;
|
||||
}
|
||||
|
||||
protected AbstractCommand(boolean noConsole, boolean hasArgs, String... command) {
|
||||
this.command = Arrays.asList(command).get(0);
|
||||
this.subCommand.addAll(Arrays.asList(command));
|
||||
|
||||
this.hasArgs = hasArgs;
|
||||
this.noConsole = noConsole;
|
||||
}
|
||||
|
||||
public AbstractCommand getParent() {
|
||||
return parent;
|
||||
public final List<String> getCommands() {
|
||||
return Collections.unmodifiableList(subCommand);
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public List<String> getSubCommand() {
|
||||
return subCommand;
|
||||
}
|
||||
|
||||
public void addSubCommand(String command) {
|
||||
public final void addSubCommand(String command) {
|
||||
subCommand.add(command);
|
||||
}
|
||||
|
||||
|
@ -67,6 +52,6 @@ public abstract class AbstractCommand {
|
|||
return noConsole;
|
||||
}
|
||||
|
||||
public enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR}
|
||||
public static enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,34 +4,64 @@ import com.songoda.core.utils.Methods;
|
|||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CommandManager implements CommandExecutor {
|
||||
public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
private JavaPlugin plugin;
|
||||
private TabManager tabManager;
|
||||
private final JavaPlugin plugin;
|
||||
|
||||
private List<AbstractCommand> commands = new ArrayList<>();
|
||||
private final HashMap<String, SimpleNestedCommand> commands = new HashMap<>();
|
||||
private boolean allowLooseCommands = false;
|
||||
|
||||
public void load(JavaPlugin plugin) {
|
||||
public CommandManager(JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.tabManager = new TabManager(this);
|
||||
|
||||
|
||||
for (AbstractCommand abstractCommand : commands) {
|
||||
if (abstractCommand.getParent() != null) continue;
|
||||
plugin.getCommand(abstractCommand.getCommand()).setTabCompleter(tabManager);
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractCommand addCommand(AbstractCommand abstractCommand) {
|
||||
commands.add(abstractCommand);
|
||||
return abstractCommand;
|
||||
public Set<String> getCommands() {
|
||||
return Collections.unmodifiableSet(commands.keySet());
|
||||
}
|
||||
|
||||
public List<String> getSubCommands(String command) {
|
||||
SimpleNestedCommand nested = command == null ? null : commands.get(command.toLowerCase());
|
||||
return nested == null ? Collections.EMPTY_LIST : nested.children.keySet().stream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Set<AbstractCommand> getAllCommands() {
|
||||
HashSet<AbstractCommand> all = new HashSet();
|
||||
commands.values().stream()
|
||||
.filter(c -> c.parent != null && !all.contains(c.parent))
|
||||
.forEach(c -> {
|
||||
all.add(c.parent);
|
||||
c.children.values().stream()
|
||||
.filter(s -> !all.contains(s))
|
||||
.forEach(s -> all.add(s));
|
||||
});
|
||||
return all;
|
||||
}
|
||||
|
||||
public SimpleNestedCommand addCommand(AbstractCommand abstractCommand) {
|
||||
SimpleNestedCommand nested = new SimpleNestedCommand(abstractCommand);
|
||||
abstractCommand.getCommands().stream().forEach(cmd -> {
|
||||
commands.put(cmd.toLowerCase(), nested);
|
||||
PluginCommand pcmd = plugin.getCommand(cmd);
|
||||
if(pcmd != null) {
|
||||
pcmd.setExecutor(this);
|
||||
pcmd.setTabCompleter(this);
|
||||
} else {
|
||||
plugin.getLogger().warning("Failed to register command: /" + cmd);
|
||||
}
|
||||
});
|
||||
return nested;
|
||||
}
|
||||
|
||||
public CommandManager addCommands(AbstractCommand... abstractCommands) {
|
||||
|
@ -45,36 +75,77 @@ public class CommandManager implements CommandExecutor {
|
|||
return this;
|
||||
}
|
||||
|
||||
public CommandManager setUseClosestCommand(boolean bool) {
|
||||
allowLooseCommands = bool;
|
||||
return this;
|
||||
}
|
||||
|
||||
@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);
|
||||
public boolean onCommand(CommandSender commandSender, Command command, String label, String[] args) {
|
||||
// grab the specific command that's being called
|
||||
SimpleNestedCommand nested = commands.get(command.getName().toLowerCase());
|
||||
if(nested != null) {
|
||||
// check to see if we're trying to call a sub-command
|
||||
if(args.length != 0 && !nested.children.isEmpty()) {
|
||||
String subCmd = getSubCommand(nested, args);
|
||||
if(subCmd != null) {
|
||||
// we have a subcommand to use!
|
||||
AbstractCommand sub = nested.children.get(subCmd);
|
||||
// adjust the arguments to match - BREAKING!!
|
||||
int i = subCmd.indexOf(' ') == -1 ? 1 : 2;
|
||||
String[] newArgs = new String[args.length - i];
|
||||
System.arraycopy(args, i, newArgs, 0, newArgs.length);
|
||||
// now process the command
|
||||
processRequirements(sub, commandSender, newArgs);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we've gotten this far, then just use the command we have
|
||||
if(nested.parent != null) {
|
||||
processRequirements(nested.parent, commandSender, args);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
commandSender.sendMessage(Methods.formatText("&7The command you entered does not exist or is spelt incorrectly."));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void processRequirements(AbstractCommand command, CommandSender sender, String[] strings) {
|
||||
private String getSubCommand(SimpleNestedCommand nested, String[] args) {
|
||||
String cmd = args[0].toLowerCase();
|
||||
if(nested.children.containsKey(cmd))
|
||||
return cmd;
|
||||
String match = null;
|
||||
// support for two-argument subcommands
|
||||
if(args.length >= 2 && nested.children.keySet().stream().anyMatch(k -> k.indexOf(' ') != -1)) {
|
||||
cmd = String.join(" ", args[0], args[1]);
|
||||
if(nested.children.containsKey(cmd))
|
||||
return cmd;
|
||||
}
|
||||
// if we don't have a subcommand, should we search for one?
|
||||
if (allowLooseCommands) {
|
||||
// do a "closest match"
|
||||
int count = 0;
|
||||
for (String c : nested.children.keySet()) {
|
||||
if (c.startsWith(cmd)) {
|
||||
match = c;
|
||||
if (++count > 1) {
|
||||
// there can only be one!
|
||||
match = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
private void processRequirements(AbstractCommand command, CommandSender sender, String[] args) {
|
||||
if (!(sender instanceof Player) && command.isNoConsole()) {
|
||||
sender.sendMessage("&cYou must be a player to use this command...");
|
||||
return;
|
||||
}
|
||||
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
|
||||
AbstractCommand.ReturnType returnType = command.runCommand(sender, strings);
|
||||
AbstractCommand.ReturnType returnType = command.runCommand(sender, args);
|
||||
if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) {
|
||||
sender.sendMessage(Methods.formatText("&cInvalid Syntax!"));
|
||||
sender.sendMessage(Methods.formatText("&7The valid syntax is: &6" + command.getSyntax() + "&7."));
|
||||
|
@ -84,8 +155,54 @@ public class CommandManager implements CommandExecutor {
|
|||
sender.sendMessage(Methods.formatText("&cYou do not have permission to do that."));
|
||||
}
|
||||
|
||||
public List<AbstractCommand> getCommands() {
|
||||
return Collections.unmodifiableList(commands);
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
// grab the specific command that's being called
|
||||
SimpleNestedCommand nested = commands.get(command.getName().toLowerCase());
|
||||
if(nested != null) {
|
||||
if(args.length == 0) {
|
||||
return nested.parent != null ? nested.parent.onTab(sender, args) : null;
|
||||
}
|
||||
// check for each sub-command that they have access to
|
||||
final boolean op = sender.isOp();
|
||||
final boolean console = !(sender instanceof Player);
|
||||
if(args.length == 1) {
|
||||
// suggest sub-commands that this user has access to
|
||||
final String arg = args[0].toLowerCase();
|
||||
return nested.children.entrySet().stream()
|
||||
.filter(e -> !console || !e.getValue().isNoConsole())
|
||||
.filter(e -> e.getKey().startsWith(arg))
|
||||
.filter(e -> op || e.getValue().getPermissionNode() == null || sender.hasPermission(e.getValue().getPermissionNode()))
|
||||
.map(e -> e.getKey())
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
// more than one arg, let's check to see if we have a command here
|
||||
String subCmd = getSubCommand(nested, args);
|
||||
AbstractCommand sub;
|
||||
if(subCmd != null && (sub = nested.children.get(subCmd)) != null
|
||||
&& (!console || !sub.isNoConsole())
|
||||
&& (op || sub.getPermissionNode() == null || sender.hasPermission(sub.getPermissionNode()))) {
|
||||
// adjust the arguments to match - BREAKING!!
|
||||
int i = subCmd.indexOf(' ') == -1 ? 1 : 2;
|
||||
String[] newArgs = new String[args.length - i];
|
||||
System.arraycopy(args, i, newArgs, 0, newArgs.length);
|
||||
// we're good to go!
|
||||
return fetchList(sub, newArgs, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
private List<String> fetchList(AbstractCommand abstractCommand, String[] args, CommandSender sender) {
|
||||
List<String> list = abstractCommand.onTab(sender, args);
|
||||
String str = args[args.length - 1];
|
||||
if (list != null && str != null && str.length() >= 1) {
|
||||
try {
|
||||
list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase()));
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package com.songoda.core.library.commands;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SimpleNestedCommand {
|
||||
|
||||
final AbstractCommand parent;
|
||||
final HashMap<String, AbstractCommand> children = new HashMap();
|
||||
|
||||
protected SimpleNestedCommand(AbstractCommand parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public SimpleNestedCommand addSubCommand(AbstractCommand command) {
|
||||
command.getCommands().stream().forEach(cmd -> children.put(cmd.toLowerCase(), command));
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleNestedCommand addSubCommands(AbstractCommand... commands) {
|
||||
Stream.of(commands).forEach(command -> command.getCommands().stream().forEach(cmd -> children.put(cmd.toLowerCase(), command)));
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
package com.songoda.core.library.commands;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
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 (command.getPermission() != null && !sender.hasPermission(command.getPermission())) continue;
|
||||
if (abstractCommand.getCommand() != null && abstractCommand.getCommand().equalsIgnoreCase(command.getName()) && !abstractCommand.hasArgs()) {
|
||||
if (strings.length != 1) continue;
|
||||
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.getParent() != null && abstractCommand.getParent().getCommand().equalsIgnoreCase(command.getName())
|
||||
|| abstractCommand.hasArgs() && abstractCommand.getCommand().equalsIgnoreCase(command.getName())) {
|
||||
String[] args = abstractCommand.hasArgs() ? (String[]) ArrayUtils.add(strings, 0, command.getName()) : strings;
|
||||
String cmd = abstractCommand.hasArgs() ? command.getName() : args[0];
|
||||
String cmd2 = args.length >= 2 ? String.join(" ", args[0], args[1]) : null;
|
||||
if (!abstractCommand.hasArgs()) {
|
||||
for (String cmds : abstractCommand.getSubCommand()) {
|
||||
if (cmd.equalsIgnoreCase(cmds) || (cmd2 != null && cmd2.equalsIgnoreCase(cmds))) {
|
||||
return fetchList(abstractCommand, args, sender);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fetchList(abstractCommand, args, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private List<String> fetchList(AbstractCommand abstractCommand, String[] args, CommandSender sender) {
|
||||
List<String> list = abstractCommand.onTab(sender, args);
|
||||
String str = args[args.length - 1];
|
||||
if (list != null && str != null && str.length() >= 1) {
|
||||
try {
|
||||
list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase()));
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.songoda.core.library.compatibility;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public enum ServerProject {
|
||||
|
||||
CRAFTBUKKIT, SPIGOT, PAPER;
|
||||
private final static String serverPackage = Bukkit.getServer().getClass().getPackage().getName();
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.songoda.core.library;
|
||||
package com.songoda.core.library.compatibility;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -7,14 +7,18 @@ public enum ServerVersion {
|
|||
|
||||
UNKNOWN, V1_7, V1_8, V1_9, V1_10, V1_11, V1_12, V1_13, V1_14, V1_15, V1_16, V1_17, V1_18, V1_19, V1_20;
|
||||
|
||||
private final static String serverPackage = Bukkit.getServer().getClass().getPackage().getName().toUpperCase();
|
||||
private static ServerVersion serverVersion = UNKNOWN;
|
||||
|
||||
static {
|
||||
for (ServerVersion version : values())
|
||||
if (Bukkit.getServer().getClass().getPackage().getName().toUpperCase().endsWith(version.name()))
|
||||
if (serverPackage.startsWith(version.name()))
|
||||
serverVersion = version;
|
||||
}
|
||||
|
||||
public static String getServerVersionString() {
|
||||
return serverPackage;
|
||||
}
|
||||
|
||||
public static ServerVersion getServerVersion() {
|
||||
return serverVersion;
|
||||
}
|
||||
|
@ -30,4 +34,8 @@ public enum ServerVersion {
|
|||
public static boolean isServerVersionAtLeast(ServerVersion version) {
|
||||
return serverVersion.ordinal() >= version.ordinal();
|
||||
}
|
||||
|
||||
public static boolean isServerVersionBelow(ServerVersion version) {
|
||||
return serverVersion.ordinal() < version.ordinal();
|
||||
}
|
||||
}
|
|
@ -1,47 +1,172 @@
|
|||
package com.songoda.core.library.economy;
|
||||
|
||||
import com.songoda.core.library.economy.economies.Economy;
|
||||
import com.songoda.core.library.economy.economies.PlayerPointsEconomy;
|
||||
import com.songoda.core.library.economy.economies.ReserveEconomy;
|
||||
import com.songoda.core.library.economy.economies.VaultEconomy;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EconomyManager {
|
||||
|
||||
private static Set<Economy> registeredEconomies = new HashSet<>();
|
||||
private final static Map<EconomyType, Economy> registeredEconomies = new HashMap<>();
|
||||
private static Economy defaultEcon = null;
|
||||
|
||||
/**
|
||||
* Load all supported economy plugins. <br />
|
||||
* Note: This method should be called in your plugin's onEnable() section
|
||||
*/
|
||||
public static void load() {
|
||||
if (!registeredEconomies.isEmpty()) return;
|
||||
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
|
||||
if (pluginManager.isPluginEnabled("Vault"))
|
||||
registeredEconomies.add(new VaultEconomy());
|
||||
if (pluginManager.isPluginEnabled("Reserve"))
|
||||
registeredEconomies.add(new ReserveEconomy());
|
||||
if (pluginManager.isPluginEnabled("PlayerPoints"))
|
||||
registeredEconomies.add(new PlayerPointsEconomy());
|
||||
for(EconomyType type : EconomyType.values()) {
|
||||
if (pluginManager.isPluginEnabled(type.plugin)) {
|
||||
Economy econ = type.getInstance();
|
||||
registeredEconomies.put(type, econ);
|
||||
if(defaultEcon == null)
|
||||
defaultEcon = econ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default economy to a different plugin, if that plugin exists.
|
||||
* If the plugin is not loaded or supported, the previously defined default will be used. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
* @param name name of the plugin to use
|
||||
*/
|
||||
public static void setPreferredEconomy(String name) {
|
||||
Economy econ = getEconomy(name);
|
||||
if(econ != null)
|
||||
defaultEcon = econ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default economy to a different plugin, if that plugin exists.
|
||||
* If the plugin is not loaded or supported, the previously defined default will be used. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
* @param economy plugin to use
|
||||
*/
|
||||
public static void setPreferredEconomy(EconomyType economy) {
|
||||
Economy econ = getEconomy(economy);
|
||||
if(econ != null)
|
||||
defaultEcon = econ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to grab the handler for this specific economy plugin.
|
||||
* @param name plugin to use
|
||||
* @return returns null if plugin is not enabled
|
||||
*/
|
||||
public static Economy getEconomy(String name) {
|
||||
return registeredEconomies.stream().filter(economy -> economy.getName().equalsIgnoreCase(name.trim()))
|
||||
.findFirst().orElse(null);
|
||||
if(name == null) return null;
|
||||
final String plugin = name.trim();
|
||||
return registeredEconomies.get(registeredEconomies.keySet().stream()
|
||||
.filter(type -> type.plugin.equalsIgnoreCase(plugin))
|
||||
.findFirst().orElse(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to grab the handler for this specific economy plugin.
|
||||
* @param economy plugin to use
|
||||
* @return returns null if plugin is not enabled
|
||||
*/
|
||||
public static Economy getEconomy(EconomyType economy) {
|
||||
return registeredEconomies.get(economy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab the default economy plugin. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
* @return returns null if no plugin enabled
|
||||
*/
|
||||
public static Economy getEconomy() {
|
||||
return defaultEcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab a list of all supported economy plugins.
|
||||
* @return an immutable collection of the loaded economy handler instances
|
||||
*/
|
||||
public static Collection<Economy> getRegisteredEconomies() {
|
||||
return Collections.unmodifiableCollection(registeredEconomies.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a specific economy plugin is enabled.
|
||||
* @param name plugin to check
|
||||
* @return true if this economy plugin is supported and loaded
|
||||
*/
|
||||
public static boolean isEnabled(String name) {
|
||||
return getEconomy(name) != null;
|
||||
}
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return !registeredEconomies.isEmpty();
|
||||
/**
|
||||
* Check to see if a specific economy plugin is enabled.
|
||||
* @param economy plugin to check
|
||||
* @return true if this economy plugin is supported and loaded
|
||||
*/
|
||||
public static boolean isEnabled(EconomyType economy) {
|
||||
return registeredEconomies.containsKey(economy);
|
||||
}
|
||||
|
||||
public static Set<Economy> getRegisteredEconomies() {
|
||||
return Collections.unmodifiableSet(registeredEconomies);
|
||||
/**
|
||||
* Check to see if there is a default economy loaded. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
* @return returns false if there are no supported economy plugins
|
||||
*/
|
||||
public static boolean isEnabled() {
|
||||
return defaultEcon != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the economy plugin being used. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getName() {
|
||||
return defaultEcon != null ? defaultEcon.getName() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a player has at least some balance available. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
*
|
||||
* @param player player to check
|
||||
* @param cost minimum amount this player should have
|
||||
* @return true if this player can have this amount withdrawn
|
||||
*/
|
||||
public static boolean hasBalance(OfflinePlayer player, double cost) {
|
||||
return defaultEcon != null ? defaultEcon.hasBalance(player, cost) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to withdraw an amount from a player's balance. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
*
|
||||
* @param player player to check
|
||||
* @param cost amount to remove from this player
|
||||
* @return true if the total amount was withdrawn successfully
|
||||
*/
|
||||
public static boolean withdrawBalance(OfflinePlayer player, double cost) {
|
||||
return defaultEcon != null ? defaultEcon.withdrawBalance(player, cost) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to add an amount to a player's balance. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
*
|
||||
* @param player player to check
|
||||
* @param amount amount to add to this player
|
||||
* @return true if the total amount was added successfully
|
||||
*/
|
||||
public static boolean deposit(OfflinePlayer player, double amount) {
|
||||
return defaultEcon != null ? defaultEcon.deposit(player, amount) : false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.songoda.core.library.economy;
|
||||
|
||||
import com.songoda.core.library.economy.economies.*;
|
||||
import java.util.logging.Level;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public enum EconomyType {
|
||||
|
||||
VAULT("Vault", VaultEconomy.class),
|
||||
PLAYER_POINTS("Reserve", ReserveEconomy.class),
|
||||
RESERVE("PlayerPoints", PlayerPointsEconomy.class);
|
||||
|
||||
public final String plugin;
|
||||
protected final Class managerClass;
|
||||
|
||||
private EconomyType(String plugin, Class managerClass) {
|
||||
this.plugin = plugin;
|
||||
this.managerClass = managerClass;
|
||||
}
|
||||
|
||||
protected Economy getInstance() {
|
||||
try {
|
||||
return (Economy) managerClass.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Economy Manager for " + name(), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -4,11 +4,37 @@ import org.bukkit.OfflinePlayer;
|
|||
|
||||
public interface Economy {
|
||||
|
||||
/**
|
||||
* Get the name of the economy plugin being used
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Check to see if a player has at least some balance available
|
||||
*
|
||||
* @param player player to check
|
||||
* @param cost minimum amount this player should have
|
||||
* @return true if this player can have this amount withdrawn
|
||||
*/
|
||||
boolean hasBalance(OfflinePlayer player, double cost);
|
||||
|
||||
/**
|
||||
* Try to withdraw an amount from a player's balance
|
||||
*
|
||||
* @param player player to check
|
||||
* @param cost amount to remove from this player
|
||||
* @return true if the total amount was withdrawn successfully
|
||||
*/
|
||||
boolean withdrawBalance(OfflinePlayer player, double cost);
|
||||
|
||||
/**
|
||||
* Try to add an amount to a player's balance
|
||||
*
|
||||
* @param player player to check
|
||||
* @param amount amount to add to this player
|
||||
* @return true if the total amount was added successfully
|
||||
*/
|
||||
boolean deposit(OfflinePlayer player, double amount);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
/**
|
||||
* Hooks for adding a custom WorldGuard flag
|
||||
*
|
||||
* Note: Hooks must be added before WG loads!
|
||||
*/
|
||||
package com.songoda.core.library.hooks;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class WorldGuardHook {
|
||||
|
||||
static Boolean wgPlugin = null;
|
||||
static Object worldGuardPlugin;
|
||||
static boolean legacy = false;
|
||||
static boolean hooksInstalled = false;
|
||||
static Map<String, Object> flags = new HashMap();
|
||||
|
||||
/**
|
||||
* Attempt to register a worldGuard flag (ALLOW/DENY)
|
||||
* @param flag
|
||||
* @param state
|
||||
*/
|
||||
public static void addHook(String flag, boolean state) {
|
||||
if (wgPlugin == null && (wgPlugin = (worldGuardPlugin = Bukkit.getPluginManager().getPlugin("WorldGuard")) != null)) {
|
||||
try {
|
||||
// if this class exists, we're on an older version
|
||||
Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
|
||||
legacy = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
}
|
||||
}
|
||||
if (!wgPlugin) return;
|
||||
|
||||
if (legacy) {
|
||||
addLegacyHook(flag, state);
|
||||
return;
|
||||
}
|
||||
|
||||
StateFlag addFlag = new StateFlag(flag, state);
|
||||
try {
|
||||
WorldGuard.getInstance().getFlagRegistry().register(addFlag);
|
||||
flags.put(flag, addFlag);
|
||||
} catch (Exception ex) {
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add flag {0} to WorldGuard", addFlag.getName());
|
||||
Flag wgFlag = (StateFlag) WorldGuard.getInstance().getFlagRegistry().get(addFlag.getName());
|
||||
if (wgFlag == null) {
|
||||
wgPlugin = false;
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not hook WorldGuard");
|
||||
} else {
|
||||
flags.put(flag, wgFlag);
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Loaded existing {1} {0}", new Object[] {wgFlag.getName(), wgFlag.getClass().getSimpleName()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reflection to add hooks
|
||||
private static void addLegacyHook(String flag, boolean state) {
|
||||
try {
|
||||
// 6.0 has the same classpath for StateFlag as the current version does
|
||||
// does this flag exist already?
|
||||
Class defaultFlagClazz = Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
|
||||
Field flagField = defaultFlagClazz.getField("flagsList");
|
||||
Flag<?>[] flagsOld = (Flag<?>[]) flagField.get(null);
|
||||
Flag wgFlag = Stream.of(flagsOld)
|
||||
.filter(f -> ((Flag<?>)f).getName().equalsIgnoreCase(flag))
|
||||
.findFirst().orElse(null);
|
||||
if (wgFlag != null) {
|
||||
// we already have one
|
||||
flags.put(flag, wgFlag);
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Loaded existing {1} {0}", new Object[] {wgFlag.getName(), wgFlag.getClass().getSimpleName()});
|
||||
return;
|
||||
}
|
||||
|
||||
// if not, we need to add one
|
||||
wgFlag = new StateFlag(flag, state);
|
||||
|
||||
// we need to sneak our flag into the array
|
||||
// make a copy first
|
||||
Flag<?>[] flagsNew = new Flag<?>[flagsOld.length + 1];
|
||||
System.arraycopy(flagsOld, 0, flagsNew, 0, flagsOld.length);
|
||||
|
||||
// add ours
|
||||
flagsNew[flagsNew.length - 1] = wgFlag;
|
||||
|
||||
// and put the new list into place
|
||||
setStaticField(flagField, flagsNew);
|
||||
|
||||
// register this flag in the registry
|
||||
Object flagRegistry = getPrivateField(worldGuardPlugin.getClass(), worldGuardPlugin, "flagRegistry");
|
||||
Class simpleFlagRegistryClazz = Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
|
||||
Method registerSimpleFlagRegistry = simpleFlagRegistryClazz.getDeclaredMethod("register", Flag.class);
|
||||
registerSimpleFlagRegistry.invoke(flagRegistry, wgFlag);
|
||||
|
||||
// all good!
|
||||
flags.put(flag, wgFlag);
|
||||
} catch (Exception ex) {
|
||||
//Bukkit.getServer().getLogger().log(Level.WARNING, "Failed to set legacy WorldGuard Flags", ex);
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add flag {0} to WorldGuard", flag);
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not hook WorldGuard");
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getPrivateField(Class<?> c, Object handle, String fieldName) throws Exception {
|
||||
Field field = c.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field.get(handle);
|
||||
}
|
||||
|
||||
private static void setStaticField(Field field, Object value) throws Exception {
|
||||
field.setAccessible(true);
|
||||
Field modifier = Field.class.getDeclaredField("modifiers");
|
||||
modifier.setAccessible(true);
|
||||
modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
field.set(null, value);
|
||||
}
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return wgPlugin != null && wgPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks this location to see what this flag is set to
|
||||
* @param l location to check
|
||||
* @param flag ALLOW/DENY flag to check
|
||||
* @return flag state, or null if undefined
|
||||
*/
|
||||
public static Boolean getBooleanFlag(Location l, String flag) {
|
||||
if (wgPlugin == null || !wgPlugin) return null;
|
||||
Object flagObj = flags.get(flag);
|
||||
// There's a different way to get this in the old version
|
||||
if (legacy)
|
||||
return flagObj == null ? null : getBooleanFlagLegacy(l, flagObj);
|
||||
|
||||
// for convinience, we can load a flag if we don't know it
|
||||
if (flagObj == null && !legacy)
|
||||
flags.put(flag, flagObj = WorldGuard.getInstance().getFlagRegistry().get(flag));
|
||||
|
||||
// so, what's up?
|
||||
if (flagObj instanceof StateFlag) {
|
||||
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||
RegionQuery query = container.createQuery();
|
||||
com.sk89q.worldedit.util.Location loc = BukkitAdapter.adapt(l);
|
||||
return query.testState(loc, (RegionAssociable) null, (StateFlag) flagObj);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query all regions that are in or intersect this chunk
|
||||
* @param c chunk to check for regions in
|
||||
* @param flag ALLOW/DENY flag to check
|
||||
* @return flag state, or null if undefined
|
||||
*/
|
||||
public static Boolean getBooleanFlag(Chunk c, String flag) {
|
||||
if (wgPlugin == null || !wgPlugin) return null;
|
||||
Object flagObj = flags.get(flag);
|
||||
// There's a different way to get this in the old version
|
||||
if (legacy)
|
||||
return flagObj == null ? null : getBooleanFlagLegacy(c, flagObj);
|
||||
|
||||
// for convinience, we can load a flag if we don't know it
|
||||
if (flagObj == null)
|
||||
flags.put(flag, flagObj = WorldGuard.getInstance().getFlagRegistry().get(flag));
|
||||
|
||||
// so, what's up?
|
||||
if (flagObj instanceof StateFlag) {
|
||||
RegionManager worldManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(c.getWorld()));
|
||||
if (worldManager == null)
|
||||
return null;
|
||||
ProtectedCuboidRegion chunkRegion = new ProtectedCuboidRegion("__TEST__",
|
||||
BlockVector3.at(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
|
||||
BlockVector3.at((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
|
||||
ApplicableRegionSet set = worldManager.getApplicableRegions(chunkRegion);
|
||||
State result = set.queryState((RegionAssociable) null, (StateFlag) flagObj);
|
||||
if (result == null && set.size() == 0)
|
||||
return null;
|
||||
return result == State.ALLOW;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static Method legacy_getRegionManager = null;
|
||||
static Method legacy_getApplicableRegions_Region = null;
|
||||
static Method legacy_getApplicableRegions_Location = null;
|
||||
static Constructor legacy_newProtectedCuboidRegion;
|
||||
static Class legacy_blockVectorClazz;
|
||||
static Constructor legacy_newblockVector;
|
||||
|
||||
private static Boolean getBooleanFlagLegacy(Location l, Object flag) {
|
||||
try {
|
||||
// cache reflection methods
|
||||
if (legacy_getRegionManager == null) {
|
||||
legacy_getRegionManager = worldGuardPlugin.getClass()
|
||||
.getDeclaredMethod("getRegionManager", org.bukkit.World.class);
|
||||
legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions",
|
||||
Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion"));
|
||||
legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions",
|
||||
Location.class);
|
||||
legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector");
|
||||
legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class);
|
||||
legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion")
|
||||
.getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz);
|
||||
}
|
||||
|
||||
// grab the applicable manager for this world
|
||||
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, l.getWorld());
|
||||
if (worldManager == null)
|
||||
return null;
|
||||
|
||||
// now look for any intersecting regions
|
||||
ApplicableRegionSet set = (ApplicableRegionSet) legacy_getApplicableRegions_Region.invoke(worldManager, l);
|
||||
|
||||
// so what's the verdict?
|
||||
State result = set.queryState((RegionAssociable) null, (StateFlag) flag);
|
||||
if (result == null && set.size() == 0)
|
||||
return null;
|
||||
return result == State.ALLOW;
|
||||
|
||||
} catch (Exception ex) {
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Boolean getBooleanFlagLegacy(Chunk c, Object flag) {
|
||||
// ApplicableRegionSet and RegionManager have the same classpath as the current version
|
||||
// ProtectedCuboidRegion uses a different constructor, though
|
||||
try {
|
||||
// cache reflection methods
|
||||
if (legacy_getRegionManager == null) {
|
||||
legacy_getRegionManager = worldGuardPlugin.getClass()
|
||||
.getDeclaredMethod("getRegionManager", org.bukkit.World.class);
|
||||
legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions",
|
||||
Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion"));
|
||||
legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions",
|
||||
Location.class);
|
||||
legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector");
|
||||
legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class);
|
||||
legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion")
|
||||
.getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz);
|
||||
}
|
||||
|
||||
// grab the applicable manager for this world
|
||||
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, c.getWorld());
|
||||
if (worldManager == null)
|
||||
return null;
|
||||
|
||||
// Create a legacy ProtectedCuboidRegion
|
||||
Object chunkRegion = legacy_newProtectedCuboidRegion.newInstance("__TEST__",
|
||||
legacy_newblockVector.newInstance(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
|
||||
legacy_newblockVector.newInstance((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
|
||||
|
||||
// now look for any intersecting regions
|
||||
ApplicableRegionSet set = (ApplicableRegionSet) legacy_getApplicableRegions_Region.invoke(worldManager, chunkRegion);
|
||||
|
||||
// so what's the verdict?
|
||||
State result = set.queryState((RegionAssociable) null, (StateFlag) flag);
|
||||
if (result == null && set.size() == 0)
|
||||
return null;
|
||||
return result == State.ALLOW;
|
||||
|
||||
} catch (Exception ex) {
|
||||
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package com.songoda.core.listeners;
|
||||
|
||||
import com.songoda.core.Plugin;
|
||||
import com.songoda.core.PluginInfo;
|
||||
import com.songoda.core.SongodaCore;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
@ -18,7 +18,7 @@ public class LoginListener implements Listener {
|
|||
@EventHandler
|
||||
public void onLogin(PlayerLoginEvent event) {
|
||||
if (!event.getPlayer().isOp()) return;
|
||||
for (Plugin plugin : instance.getPlugins()) {
|
||||
for (PluginInfo plugin : instance.getPlugins()) {
|
||||
if (plugin.getNotification() != null)
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin.getJavaPlugin(), () ->
|
||||
event.getPlayer().sendMessage("[" + plugin.getJavaPlugin().getName() + "] " + plugin.getNotification()), 10L);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.songoda.core.modules;
|
||||
|
||||
import com.songoda.core.Plugin;
|
||||
import com.songoda.core.PluginInfo;
|
||||
|
||||
public interface Module {
|
||||
|
||||
void run(Plugin plugin);
|
||||
void run(PluginInfo plugin);
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.songoda.core.modules.common;
|
|||
|
||||
import com.songoda.core.library.locale.Locale;
|
||||
import com.songoda.core.modules.Module;
|
||||
import com.songoda.core.Plugin;
|
||||
import com.songoda.core.PluginInfo;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
|
@ -13,7 +13,7 @@ import java.net.URL;
|
|||
public class LocaleModule implements Module {
|
||||
|
||||
@Override
|
||||
public void run(Plugin plugin) {
|
||||
public void run(PluginInfo plugin) {
|
||||
JSONObject json = plugin.getJson();
|
||||
try {
|
||||
JSONArray files = (JSONArray) json.get("neededFiles");
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
package com.songoda.core.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PlayerUtils {
|
||||
|
||||
static Random random = new Random();
|
||||
|
||||
/**
|
||||
* Get a list of all of the players that this player can "see"
|
||||
*
|
||||
* @param player player to check against, or null for all players
|
||||
* @param startingWith optional query to test: only players whose game names
|
||||
* start with this
|
||||
* @return list of player names that are "visible" to the player
|
||||
*/
|
||||
public static List<String> getVisiblePlayerNames(Player player, String startingWith) {
|
||||
final String startsWith = startingWith == null || startingWith.isEmpty() ? null : startingWith.toLowerCase();
|
||||
return Bukkit.getOnlinePlayers().stream()
|
||||
.filter(p -> p != player)
|
||||
.filter(p -> startsWith == null || p.getName().toLowerCase().startsWith(startsWith))
|
||||
.filter(p -> player == null || (player.canSee(p) && p.getMetadata("vanished").isEmpty()))
|
||||
.map(Player::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all of the players that this player can "see"
|
||||
*
|
||||
* @param player player to check against, or null for all players
|
||||
* @param startingWith optional query to test: only players whose game names
|
||||
* start with this
|
||||
* @return list of players that are "visible" to the player
|
||||
*/
|
||||
public static List<Player> getVisiblePlayers(Player player, String startingWith) {
|
||||
final String startsWith = startingWith == null || startingWith.isEmpty() ? null : startingWith.toLowerCase();
|
||||
return Bukkit.getOnlinePlayers().stream()
|
||||
.filter(p -> p != player)
|
||||
.filter(p -> startsWith == null || p.getName().toLowerCase().startsWith(startsWith))
|
||||
.filter(p -> player == null || (player.canSee(p) && p.getMetadata("vanished").isEmpty()))
|
||||
.map(p -> (Player) p)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for and grab the closest match for a provided player name. <br />
|
||||
* Uses player display names if there is not an exact match.
|
||||
*
|
||||
* @param player player to search for
|
||||
* @return Player that closest matches the input name, or null if none found
|
||||
*/
|
||||
public static Player findPlayer(String player) {
|
||||
Player found = Bukkit.getServer().getPlayer(player);
|
||||
if (found == null) {
|
||||
final String searchName = player.replaceAll("[^a-zA-Z]", "").toLowerCase();
|
||||
int d = 999;
|
||||
for (Player p2 : Bukkit.getOnlinePlayers()) {
|
||||
final String test = p2.getDisplayName().replaceAll("[^a-zA-Z]", "");
|
||||
if (test.toLowerCase().startsWith(searchName)) {
|
||||
int d2 = test.length() - searchName.length();
|
||||
if (d2 < d) {
|
||||
found = p2;
|
||||
d = d2;
|
||||
} else if (d2 == d) {
|
||||
found = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public static Player getRandomPlayer() {
|
||||
final Collection<? extends Player> all = Bukkit.getOnlinePlayers();
|
||||
final Iterator<? extends Player> alli = all.iterator();
|
||||
int pick = random.nextInt(all.size());
|
||||
for (; pick > 0; --pick) {
|
||||
alli.next();
|
||||
}
|
||||
return alli.hasNext() ? alli.next() : null;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.songoda.core.utils.gui;
|
||||
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.core.library.ServerVersion;
|
||||
import com.songoda.core.library.compatibility.ServerVersion;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
|
||||
|
|
Loading…
Reference in New Issue