diff --git a/pom.xml b/pom.xml
index 9a596b5..847fab4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.drtshock
PlayerVaultsX
- 4.1.17
+ 4.2.0-SNAPSHOT
PlayerVaultsX
https://www.spigotmc.org/resources/51204/
@@ -74,6 +74,10 @@
vault-repo
http://nexus.hc.to/content/repositories/pub_releases/
+
+ fuuid-repo
+ https://github.com/factions-site/repo/raw/public
+
spigot-repo
https://hub.spigotmc.org/nexus/content/groups/public/
@@ -119,6 +123,12 @@
0.1.0
compile
+
+ org.kitteh
+ paste-gg-api
+ 0.9.1
+ compile
+
org.spigotmc
spigot-api
diff --git a/src/main/java/com/drtshock/playervaults/PlayerVaults.java b/src/main/java/com/drtshock/playervaults/PlayerVaults.java
index 16ba66c..83eca7b 100644
--- a/src/main/java/com/drtshock/playervaults/PlayerVaults.java
+++ b/src/main/java/com/drtshock/playervaults/PlayerVaults.java
@@ -20,6 +20,7 @@ package com.drtshock.playervaults;
import com.drtshock.playervaults.commands.ConvertCommand;
import com.drtshock.playervaults.commands.DeleteCommand;
+import com.drtshock.playervaults.commands.HelpMeCommand;
import com.drtshock.playervaults.commands.SignCommand;
import com.drtshock.playervaults.commands.SignSetInfo;
import com.drtshock.playervaults.commands.VaultCommand;
@@ -30,11 +31,10 @@ import com.drtshock.playervaults.listeners.Listeners;
import com.drtshock.playervaults.listeners.SignListener;
import com.drtshock.playervaults.listeners.VaultPreloadListener;
import com.drtshock.playervaults.tasks.Cleanup;
+import com.drtshock.playervaults.vaultmanagement.EconomyOperations;
import com.drtshock.playervaults.vaultmanagement.VaultManager;
import com.drtshock.playervaults.vaultmanagement.VaultViewInfo;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
-import net.milkbowl.vault.economy.Economy;
-import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -47,23 +47,28 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.plugin.Plugin;
-import org.bukkit.plugin.RegisteredServiceProvider;
-import org.bukkit.plugin.SimplePluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import sun.misc.Unsafe;
import java.io.File;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.regex.Pattern;
@@ -77,7 +82,6 @@ public class PlayerVaults extends JavaPlugin {
// VaultViewInfo - Inventory
private final HashMap openInventories = new HashMap<>();
private final Set blockedMats = new HashSet<>();
- private Economy economy;
private boolean useVault;
private YamlConfiguration signs;
private File signsFile;
@@ -92,6 +96,7 @@ public class PlayerVaults extends JavaPlugin {
private Config config = new Config();
private BukkitAudiences platform;
private Translation translation = new Translation(this);
+ private List exceptions = new CopyOnWriteArrayList<>();
public static PlayerVaults getInstance() {
return instance;
@@ -142,9 +147,10 @@ public class PlayerVaults extends JavaPlugin {
getCommand("pvdel").setExecutor(new DeleteCommand(this));
getCommand("pvconvert").setExecutor(new ConvertCommand(this));
getCommand("pvsign").setExecutor(new SignCommand(this));
+ getCommand("pvhelpme").setExecutor(new HelpMeCommand(this));
debug("registered commands", time);
time = System.currentTimeMillis();
- useVault = setupEconomy();
+ useVault = EconomyOperations.setup();
debug("setup economy", time);
if (getConf().getPurge().isEnabled()) {
@@ -167,15 +173,18 @@ public class PlayerVaults extends JavaPlugin {
this.metricsDrillPie("vault_econ", () -> {
Map> map = new HashMap<>();
Map entry = new HashMap<>();
- entry.put(economy == null ? "none" : economy.getName(), 1);
+ entry.put(!this.useVault ? "none" : EconomyOperations.getName(), 1);
map.put(isEconomyEnabled() ? "enabled" : "disabled", entry);
return map;
});
if (isEconomyEnabled()) {
- String name = economy.getName();
+ String name = EconomyOperations.getName();
if (name.equals("Essentials Economy")) {
name = "Essentials";
}
+ if (name.equals("CMIEconomy")) {
+ name = "CMI";
+ }
Plugin plugin = getServer().getPluginManager().getPlugin(name);
if (plugin != null) {
this.metricsDrillPie("vault_econ_plugins", () -> {
@@ -190,10 +199,8 @@ public class PlayerVaults extends JavaPlugin {
}
if (vault != null) {
- RegisteredServiceProvider provider = getServer().getServicesManager().getRegistration(Permission.class);
- if (provider != null) {
- Permission perm = provider.getProvider();
- String name = perm.getName();
+ String name = EconomyOperations.getPermsName();
+ if (name != null) {
Plugin plugin = getServer().getPluginManager().getPlugin(name);
final String version;
if (plugin == null) {
@@ -212,6 +219,7 @@ public class PlayerVaults extends JavaPlugin {
}
this.metricsSimplePie("signs", () -> getConf().isSigns() ? "enabled" : "disabled");
+ this.metricsSimplePie("cats", () -> HelpMeCommand.likesCats ? "meow" : "purr");
this.metricsSimplePie("cleanup", () -> getConf().getPurge().isEnabled() ? "enabled" : "disabled");
this.metricsDrillPie("block_items", () -> {
@@ -309,20 +317,6 @@ public class PlayerVaults extends JavaPlugin {
return true;
}
- private boolean setupEconomy() {
- if (getServer().getPluginManager().getPlugin("Vault") == null) {
- return false;
- }
-
- RegisteredServiceProvider provider = getServer().getServicesManager().getRegistration(Economy.class);
- if (provider == null) {
- return false;
- }
-
- economy = provider.getProvider();
- return economy != null;
- }
-
private void loadConfig() {
File configYaml = new File(this.getDataFolder(), "config.yml");
if (!(new File(this.getDataFolder(), "config.conf").exists()) && configYaml.exists()) {
@@ -448,10 +442,6 @@ public class PlayerVaults extends JavaPlugin {
return this.openInventories;
}
- public Economy getEconomy() {
- return this.economy;
- }
-
public boolean isEconomyEnabled() {
return this.getConf().getEconomy().isEnabled() && this.useVault;
}
@@ -548,4 +538,34 @@ public class PlayerVaults extends JavaPlugin {
public String getVaultTitle(String id) {
return this.translation.vaultTitle().with("vault", id).getLegacy();
}
+
+ public String getExceptions() {
+ if (this.exceptions.isEmpty()) {
+ return null;
+ }
+ StringBuilder builder = new StringBuilder();
+ boolean more = false;
+ for (String e : this.exceptions) {
+ if (more) {
+ builder.append("\n\n");
+ } else {
+ more = true;
+ }
+ builder.append(e);
+ }
+ return builder.toString();
+ }
+
+ public T addException(T t) {
+ if (this.getConf().isDebug()) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(ZonedDateTime.now(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"))).append('\n');
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter);
+ t.printStackTrace(printWriter);
+ builder.append(stringWriter.toString());
+ this.exceptions.add(builder.toString());
+ }
+ return t;
+ }
}
diff --git a/src/main/java/com/drtshock/playervaults/commands/HelpMeCommand.java b/src/main/java/com/drtshock/playervaults/commands/HelpMeCommand.java
new file mode 100644
index 0000000..455737f
--- /dev/null
+++ b/src/main/java/com/drtshock/playervaults/commands/HelpMeCommand.java
@@ -0,0 +1,139 @@
+/*
+ * PlayerVaultsX
+ * Copyright (C) 2013 Trent Hensler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.drtshock.playervaults.commands;
+
+import com.drtshock.playervaults.PlayerVaults;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.event.ClickEvent;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.kitteh.pastegg.PasteBuilder;
+import org.kitteh.pastegg.PasteContent;
+import org.kitteh.pastegg.PasteFile;
+import org.kitteh.pastegg.Visibility;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.logging.Level;
+
+public class HelpMeCommand implements CommandExecutor {
+ public static final boolean likesCats = Arrays.stream(PlayerVaults.class.getDeclaredMethods()).anyMatch(m -> m.isSynthetic() && m.getName().startsWith("loadC") && m.getName().endsWith("0"));
+ private final PlayerVaults plugin;
+
+ public HelpMeCommand(PlayerVaults plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(final CommandSender sender, Command command, String label, String[] args) {
+ if (!sender.hasPermission("playervaults.admin")) {
+ this.plugin.getTL().noPerms().title().send(sender);
+ } else {
+ StringBuilder mainInfo = new StringBuilder();
+ mainInfo.append(Bukkit.getName()).append(" version: ").append(Bukkit.getServer().getVersion()).append('\n');
+ mainInfo.append("Plugin ").append(likesCats ? "version" : "Version").append(": ").append(plugin.getDescription().getVersion()).append('\n');
+ mainInfo.append("Java version: ").append(System.getProperty("java.version")).append('\n');
+ if (args.length >= 1 && args[0].equalsIgnoreCase("mini")) {
+ Audience audience = PlayerVaults.getInstance().getPlatform().sender(sender);
+ for (String string : mainInfo.toString().split("\n")) {
+ audience.sendMessage(MiniMessage.get().parse((sender instanceof Player ? "" : "") + string));
+ }
+ return true;
+ }
+ mainInfo.append('\n');
+ mainInfo.append("Command run by: ").append(sender.getName()).append('\n');
+ mainInfo.append('\n');
+ mainInfo.append("Plugins:\n");
+ for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
+ mainInfo.append(' ').append(plugin.getName()).append(" - ").append(plugin.getDescription().getVersion()).append('\n');
+ mainInfo.append(" ").append(plugin.getDescription().getAuthors()).append('\n');
+ }
+
+ new BukkitRunnable() {
+ private final PasteBuilder builder = new PasteBuilder().name("PlayerVaultsX Debug")
+ .visibility(Visibility.UNLISTED)
+ .expires(ZonedDateTime.now(ZoneOffset.UTC).plusDays(3));
+ private int i = 0;
+
+ private void add(String name, String content) {
+ builder.addFile(new PasteFile(i++ + name, new PasteContent(PasteContent.ContentType.TEXT, content)));
+ }
+
+ private String getFile(Path file) {
+ try {
+ return new String(Files.readAllBytes(file), StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ return ExceptionUtils.getFullStackTrace(e);
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ Path dataPath = plugin.getDataFolder().toPath();
+ add("info.txt", mainInfo.toString());
+ String exceptionLog = plugin.getExceptions();
+ if (exceptionLog != null) {
+ add("exceptions.txt", exceptionLog);
+ }
+ add("main.conf", getFile(dataPath.resolve("config.conf")));
+ PasteBuilder.PasteResult result = builder.build();
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ Audience audience = PlayerVaults.getInstance().getPlatform().sender(sender);
+ if (result.getPaste().isPresent()) {
+ String delKey = result.getPaste().get().getDeletionKey().orElse("No deletion key");
+ String url = "https://paste.gg/anonymous/" + result.getPaste().get().getId();
+ audience.sendMessage(Component.text("URL generated: ").append(Component.text().clickEvent(ClickEvent.openUrl(url)).content(url)));
+ audience.sendMessage(MiniMessage.get().parse((sender instanceof Player ? "" : "") + "Deletion key: " + delKey));
+ } else {
+ audience.sendMessage(MiniMessage.get().parse("Failed to generate output. See console for details."));
+ PlayerVaults.getInstance().getLogger().warning("Received: " + result.getMessage());
+ }
+ }
+ }.runTask(PlayerVaults.getInstance());
+ } catch (Exception e) {
+ PlayerVaults.getInstance().getLogger().log(Level.SEVERE, "Failed to execute debug command", e);
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ PlayerVaults.getInstance().getPlatform().sender(sender).sendMessage(MiniMessage.get().parse("Failed to generate output. See console for details."));
+ }
+ }.runTask(PlayerVaults.getInstance());
+ }
+ }
+ }.runTaskAsynchronously(PlayerVaults.getInstance());
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java
index a06f459..d617a66 100644
--- a/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java
+++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java
@@ -4,7 +4,6 @@ import com.drtshock.playervaults.PlayerVaults;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
-import org.bukkit.util.io.BukkitObjectInputStream;
import org.kitteh.cardboardbox.CardboardBox;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
@@ -20,7 +19,7 @@ public class CardboardBoxSerialization {
try {
return Base64Coder.encodeLines(writeInventory(inventory.getContents()));
} catch (IOException e) {
- throw new IllegalStateException("Failed to save items for " + target, e);
+ throw PlayerVaults.getInstance().addException(new IllegalStateException("Failed to save items for " + target, e));
}
}
@@ -35,6 +34,7 @@ public class CardboardBoxSerialization {
try {
return readInventory(Base64Coder.decodeLines(data));
} catch (IOException e) {
+ PlayerVaults.getInstance().addException(new IllegalStateException("Failed to save items for " + target, e));
PlayerVaults.getInstance().getLogger().log(Level.SEVERE, "Failed to load items for " + target, e);
return null;
}
diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java
index a0b6e36..1ca3f35 100644
--- a/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java
+++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java
@@ -19,9 +19,13 @@
package com.drtshock.playervaults.vaultmanagement;
import com.drtshock.playervaults.PlayerVaults;
+import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.economy.EconomyResponse;
+import net.milkbowl.vault.permission.Permission;
+import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
+import org.bukkit.plugin.RegisteredServiceProvider;
import java.io.File;
@@ -30,6 +34,33 @@ import java.io.File;
*/
public class EconomyOperations {
+ private static Economy economy;
+
+ public static boolean setup() {
+ economy = null;
+ if (Bukkit.getServer().getPluginManager().getPlugin("Vault") != null) {
+ RegisteredServiceProvider provider = Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
+ if (provider != null) {
+ economy = provider.getProvider();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static String getName() {
+ return economy == null ? "NONE" : economy.getName();
+ }
+
+ public static String getPermsName() {
+ RegisteredServiceProvider provider = Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
+ if (provider != null) {
+ Permission perm = provider.getProvider();
+ return perm.getName();
+ }
+ return null;
+ }
+
/**
* Have a player pay to open a vault.
*
@@ -49,7 +80,7 @@ public class EconomyOperations {
return true;
}
double cost = PlayerVaults.getInstance().getConf().getEconomy().getFeeToOpen();
- EconomyResponse resp = PlayerVaults.getInstance().getEconomy().withdrawPlayer(player, cost);
+ EconomyResponse resp = economy.withdrawPlayer(player, cost);
if (resp.transactionSuccess()) {
PlayerVaults.getInstance().getTL().costToOpen().title().with("price", cost + "").send(player);
return true;
@@ -71,7 +102,7 @@ public class EconomyOperations {
}
double cost = PlayerVaults.getInstance().getConf().getEconomy().getFeeToCreate();
- EconomyResponse resp = PlayerVaults.getInstance().getEconomy().withdrawPlayer(player, cost);
+ EconomyResponse resp = economy.withdrawPlayer(player, cost);
if (resp.transactionSuccess()) {
PlayerVaults.getInstance().getTL().costToCreate().title().with("price", cost + "").send(player);
return true;
@@ -105,7 +136,7 @@ public class EconomyOperations {
}
double cost = PlayerVaults.getInstance().getConf().getEconomy().getRefundOnDelete();
- EconomyResponse resp = PlayerVaults.getInstance().getEconomy().depositPlayer(player, cost);
+ EconomyResponse resp = economy.depositPlayer(player, cost);
if (resp.transactionSuccess()) {
PlayerVaults.getInstance().getTL().refundAmount().title().with("price", cost + "").send(player);
return true;
diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java
index d1ee5de..1bec04c 100644
--- a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java
+++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java
@@ -370,6 +370,7 @@ public class VaultManager {
try {
yaml.save(file);
} catch (IOException e) {
+ PlayerVaults.getInstance().addException(new IllegalStateException("Failed to save vault file for: " + holder, e));
PlayerVaults.getInstance().getLogger().log(Level.SEVERE, "Failed to save vault file for: " + holder, e);
}
PlayerVaults.debug("Saved vault for " + holder);
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 0a28577..8014d5f 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -23,6 +23,9 @@ commands:
pvreload:
description: Reload the configuration and language files.
permission: playervaults.admin
+ pvhelpme:
+ description: Pastes debug info to get better assistance.
+ permission: playervaults.admin
permissions:
playervaults.admin: