Mirror von
https://github.com/TheSilentPro/HeadDB.git
synchronisiert 2024-12-28 20:00:10 +01:00
refactoring & some changes
Dieser Commit ist enthalten in:
Ursprung
6a7cffc10c
Commit
ed68213c4d
@ -1,8 +1,6 @@
|
|||||||
package tsp.headdb;
|
package tsp.headdb;
|
||||||
|
|
||||||
import de.leonhard.storage.Config;
|
import de.leonhard.storage.Config;
|
||||||
import de.leonhard.storage.Json;
|
|
||||||
import de.leonhard.storage.LightningBuilder;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import tsp.headdb.api.HeadAPI;
|
import tsp.headdb.api.HeadAPI;
|
||||||
@ -12,6 +10,7 @@ import tsp.headdb.listener.PagedPaneListener;
|
|||||||
import tsp.headdb.listener.MenuListener;
|
import tsp.headdb.listener.MenuListener;
|
||||||
import tsp.headdb.util.Log;
|
import tsp.headdb.util.Log;
|
||||||
import tsp.headdb.util.Metrics;
|
import tsp.headdb.util.Metrics;
|
||||||
|
import tsp.headdb.util.Storage;
|
||||||
import tsp.headdb.util.Utils;
|
import tsp.headdb.util.Utils;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import net.milkbowl.vault.economy.Economy;
|
import net.milkbowl.vault.economy.Economy;
|
||||||
@ -19,8 +18,7 @@ import net.milkbowl.vault.economy.Economy;
|
|||||||
public class HeadDB extends JavaPlugin {
|
public class HeadDB extends JavaPlugin {
|
||||||
|
|
||||||
private static HeadDB instance;
|
private static HeadDB instance;
|
||||||
private Config config;
|
private Storage storage;
|
||||||
private Json playerdata;
|
|
||||||
private Economy economy = null;
|
private Economy economy = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -28,10 +26,9 @@ public class HeadDB extends JavaPlugin {
|
|||||||
instance = this;
|
instance = this;
|
||||||
Log.info("Loading HeadDB - " + getDescription().getVersion());
|
Log.info("Loading HeadDB - " + getDescription().getVersion());
|
||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
config = LightningBuilder.fromPath("config.yml", "plugins/HeadDB").createConfig().addDefaultsFromInputStream();
|
storage = new Storage().init(this);
|
||||||
playerdata = LightningBuilder.fromPath("playerdata.json", "plugins/HeadDB").createJson();
|
|
||||||
|
|
||||||
if (config.getBoolean("economy.enable")) {
|
if (storage.getConfig().getBoolean("economy.enable")) {
|
||||||
Log.debug("Starting economy...");
|
Log.debug("Starting economy...");
|
||||||
this.economy = this.setupEconomy();
|
this.economy = this.setupEconomy();
|
||||||
if (this.economy == null) {
|
if (this.economy == null) {
|
||||||
@ -52,8 +49,8 @@ public class HeadDB extends JavaPlugin {
|
|||||||
Log.debug("Registering commands...");
|
Log.debug("Registering commands...");
|
||||||
getCommand("headdb").setExecutor(new Command_headdb());
|
getCommand("headdb").setExecutor(new Command_headdb());
|
||||||
|
|
||||||
if (config.getBoolean("fetchStartup")) {
|
if (storage.getConfig().getBoolean("fetchStartup")) {
|
||||||
if (config.getBoolean("asyncStartup")) {
|
if (storage.getConfig().getBoolean("asyncStartup")) {
|
||||||
Log.debug("Initializing Database... (ASYNC)");
|
Log.debug("Initializing Database... (ASYNC)");
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(this, () -> HeadAPI.getDatabase().update());
|
Bukkit.getScheduler().runTaskAsynchronously(this, () -> HeadAPI.getDatabase().update());
|
||||||
} else {
|
} else {
|
||||||
@ -74,19 +71,20 @@ public class HeadDB extends JavaPlugin {
|
|||||||
return this.economy = economyProvider.getProvider();
|
return this.economy = economyProvider.getProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Config getCfg() {
|
public Config getConfiguration() {
|
||||||
return config;
|
return storage.getConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Json getPlayerdata() {
|
public Storage getStorage() {
|
||||||
return playerdata;
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Economy getEconomy() {
|
||||||
|
return this.economy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HeadDB getInstance() {
|
public static HeadDB getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Economy getEconomy() {
|
|
||||||
return this.economy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public class Head {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID getUUID() {
|
public UUID getUniqueId() {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ public class Head {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Head withUUID(UUID uuid) {
|
public Head withUniqueId(UUID uuid) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -81,8 +81,8 @@ public final class HeadAPI {
|
|||||||
* @return The head
|
* @return The head
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Head getHeadByUUID(UUID uuid) {
|
public static Head getHeadByUniqueId(UUID uuid) {
|
||||||
return database.getHeadByUUID(uuid);
|
return database.getHeadByUniqueId(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Head> getHeadsByTag(String tag) {
|
public static List<Head> getHeadsByTag(String tag) {
|
||||||
@ -147,11 +147,11 @@ public final class HeadAPI {
|
|||||||
* @param id The ID of the head
|
* @param id The ID of the head
|
||||||
*/
|
*/
|
||||||
public static void addFavoriteHead(UUID uuid, int id) {
|
public static void addFavoriteHead(UUID uuid, int id) {
|
||||||
List<Integer> favs = HeadDB.getInstance().getPlayerdata().getIntegerList(uuid.toString() + ".favorites");
|
List<Integer> favs = HeadDB.getInstance().getConfiguration().getIntegerList(uuid.toString() + ".favorites");
|
||||||
if (!favs.contains(id)) {
|
if (!favs.contains(id)) {
|
||||||
favs.add(id);
|
favs.add(id);
|
||||||
}
|
}
|
||||||
HeadDB.getInstance().getPlayerdata().set(uuid.toString() + ".favorites", favs);
|
HeadDB.getInstance().getStorage().getPlayerData().set(uuid.toString() + ".favorites", favs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -161,14 +161,14 @@ public final class HeadAPI {
|
|||||||
* @param id The ID of the head
|
* @param id The ID of the head
|
||||||
*/
|
*/
|
||||||
public static void removeFavoriteHead(UUID uuid, int id) {
|
public static void removeFavoriteHead(UUID uuid, int id) {
|
||||||
List<Integer> favs = HeadDB.getInstance().getPlayerdata().getIntegerList(uuid.toString() + ".favorites");
|
List<Integer> favs = HeadDB.getInstance().getStorage().getPlayerData().getIntegerList(uuid.toString() + ".favorites");
|
||||||
for (int i = 0; i < favs.size(); i++) {
|
for (int i = 0; i < favs.size(); i++) {
|
||||||
if (favs.get(i) == id) {
|
if (favs.get(i) == id) {
|
||||||
favs.remove(i);
|
favs.remove(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HeadDB.getInstance().getPlayerdata().set(uuid.toString() + ".favorites", favs);
|
HeadDB.getInstance().getStorage().getPlayerData().set(uuid.toString() + ".favorites", favs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,7 +179,7 @@ public final class HeadAPI {
|
|||||||
*/
|
*/
|
||||||
public static List<Head> getFavoriteHeads(UUID uuid) {
|
public static List<Head> getFavoriteHeads(UUID uuid) {
|
||||||
List<Head> heads = new ArrayList<>();
|
List<Head> heads = new ArrayList<>();
|
||||||
List<Integer> ids = HeadDB.getInstance().getPlayerdata().getIntegerList(uuid.toString() + ".favorites");
|
List<Integer> ids = HeadDB.getInstance().getStorage().getPlayerData().getIntegerList(uuid.toString() + ".favorites");
|
||||||
for (int id : ids) {
|
for (int id : ids) {
|
||||||
Head head = getHeadByID(id);
|
Head head = getHeadByID(id);
|
||||||
heads.add(head);
|
heads.add(head);
|
||||||
@ -196,7 +196,7 @@ public final class HeadAPI {
|
|||||||
*/
|
*/
|
||||||
public static List<LocalHead> getLocalHeads() {
|
public static List<LocalHead> getLocalHeads() {
|
||||||
List<LocalHead> heads = new ArrayList<>();
|
List<LocalHead> heads = new ArrayList<>();
|
||||||
for (String key : HeadDB.getInstance().getPlayerdata().singleLayerKeySet()) {
|
for (String key : HeadDB.getInstance().getStorage().getPlayerData().singleLayerKeySet()) {
|
||||||
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(key));
|
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(key));
|
||||||
heads.add(new LocalHead(player.getUniqueId())
|
heads.add(new LocalHead(player.getUniqueId())
|
||||||
.withName(player.getName()));
|
.withName(player.getName()));
|
||||||
|
@ -35,7 +35,7 @@ public class LocalHead {
|
|||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID getUuid() {
|
public UUID getUniqueId() {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ public class LocalHead {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalHead withUUID(UUID uuid) {
|
public LocalHead withUniqueId(UUID uuid) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import java.net.URL;
|
|||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the Database that holds all heads
|
* This is the Database that holds all heads
|
||||||
@ -53,10 +54,10 @@ public class HeadDatabase {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Head getHeadByUUID(UUID uuid) {
|
public Head getHeadByUniqueId(UUID uuid) {
|
||||||
List<Head> heads = getHeads();
|
List<Head> heads = getHeads();
|
||||||
for (Head head : heads) {
|
for (Head head : heads) {
|
||||||
if (head.getUUID().equals(uuid)) {
|
if (head.getUniqueId().equals(uuid)) {
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,6 +119,12 @@ public class HeadDatabase {
|
|||||||
return getHeads();
|
return getHeads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all heads from the api provider
|
||||||
|
*
|
||||||
|
* @return Map containing each head in it's category. Returns null if the fetching failed.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
public Map<Category, List<Head>> getHeadsNoCache() {
|
public Map<Category, List<Head>> getHeadsNoCache() {
|
||||||
Map<Category, List<Head>> result = new HashMap<>();
|
Map<Category, List<Head>> result = new HashMap<>();
|
||||||
List<Category> categories = Category.getCategories();
|
List<Category> categories = Category.getCategories();
|
||||||
@ -125,6 +132,7 @@ public class HeadDatabase {
|
|||||||
int id = 1;
|
int id = 1;
|
||||||
for (Category category : categories) {
|
for (Category category : categories) {
|
||||||
Log.debug("Caching heads from: " + category.getName());
|
Log.debug("Caching heads from: " + category.getName());
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
List<Head> heads = new ArrayList<>();
|
List<Head> heads = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
String line;
|
String line;
|
||||||
@ -146,7 +154,7 @@ public class HeadDatabase {
|
|||||||
|
|
||||||
Head head = new Head(id)
|
Head head = new Head(id)
|
||||||
.withName(obj.get("name").toString())
|
.withName(obj.get("name").toString())
|
||||||
.withUUID(uuid.isEmpty() ? UUID.randomUUID() : UUID.fromString(uuid))
|
.withUniqueId(uuid.isEmpty() ? UUID.randomUUID() : UUID.fromString(uuid))
|
||||||
.withValue(obj.get("value").toString())
|
.withValue(obj.get("value").toString())
|
||||||
.withTags(obj.get("tags") != null ? obj.get("tags").toString() : "None")
|
.withTags(obj.get("tags") != null ? obj.get("tags").toString() : "None")
|
||||||
.withCategory(category);
|
.withCategory(category);
|
||||||
@ -154,9 +162,13 @@ public class HeadDatabase {
|
|||||||
id++;
|
id++;
|
||||||
heads.add(head);
|
heads.add(head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long elapsed = (System.currentTimeMillis() - start);
|
||||||
|
Log.debug(category.getName() + " -> Done! Time: " + elapsed + "ms (" + TimeUnit.MILLISECONDS.toSeconds(elapsed) + "s)");
|
||||||
} catch (ParseException | IOException e) {
|
} catch (ParseException | IOException e) {
|
||||||
Log.error("Failed to fetch heads (no-cache) | Stack Trace:");
|
Log.error("Failed to fetch heads (no-cache) | Stack Trace:");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
updated = System.nanoTime();
|
updated = System.nanoTime();
|
||||||
@ -166,12 +178,23 @@ public class HeadDatabase {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
/**
|
||||||
|
* Updates the cached heads
|
||||||
|
*
|
||||||
|
* @return Returns true if the update was successful.
|
||||||
|
*/
|
||||||
|
public boolean update() {
|
||||||
Map<Category, List<Head>> heads = getHeadsNoCache();
|
Map<Category, List<Head>> heads = getHeadsNoCache();
|
||||||
|
if (heads == null) {
|
||||||
|
Log.error("Failed to update database! Check above for any errors.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
HEADS.clear();
|
HEADS.clear();
|
||||||
for (Map.Entry<Category, List<Head>> entry : heads.entrySet()) {
|
for (Map.Entry<Category, List<Head>> entry : heads.entrySet()) {
|
||||||
HEADS.put(entry.getKey(), entry.getValue());
|
HEADS.put(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLastUpdate() {
|
public long getLastUpdate() {
|
||||||
@ -181,8 +204,8 @@ public class HeadDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLastUpdateOld() {
|
public boolean isLastUpdateOld() {
|
||||||
if (HeadDB.getInstance().getCfg() == null && getLastUpdate() >= 3600) return true;
|
if (HeadDB.getInstance().getConfiguration() == null && getLastUpdate() >= 3600) return true;
|
||||||
return getLastUpdate() >= HeadDB.getInstance().getCfg().getLong("refresh");
|
return getLastUpdate() >= HeadDB.getInstance().getConfiguration().getLong("refresh");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ public class InventoryUtils {
|
|||||||
if (uiLocation.containsKey(category)) return uiLocation.get(category);
|
if (uiLocation.containsKey(category)) return uiLocation.get(category);
|
||||||
|
|
||||||
// Try to get the value from the config file.
|
// Try to get the value from the config file.
|
||||||
if (HeadDB.getInstance().getCfg().contains("ui.category." + category + ".location")) {
|
if (HeadDB.getInstance().getConfiguration().contains("ui.category." + category + ".location")) {
|
||||||
uiLocation.put(category, HeadDB.getInstance().getCfg().getInt("ui.category." + category + ".location"));
|
uiLocation.put(category, HeadDB.getInstance().getConfiguration().getInt("ui.category." + category + ".location"));
|
||||||
return uiLocation.get(category);
|
return uiLocation.get(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,8 +47,8 @@ public class InventoryUtils {
|
|||||||
if (uiItem.containsKey(category)) return uiItem.get(category);
|
if (uiItem.containsKey(category)) return uiItem.get(category);
|
||||||
|
|
||||||
// Try to get a head from the config file.
|
// Try to get a head from the config file.
|
||||||
if (HeadDB.getInstance().getCfg().contains("ui.category." + category + ".head")) {
|
if (HeadDB.getInstance().getConfiguration().contains("ui.category." + category + ".head")) {
|
||||||
int id = HeadDB.getInstance().getCfg().getInt("ui.category." + category + ".head");
|
int id = HeadDB.getInstance().getConfiguration().getInt("ui.category." + category + ".head");
|
||||||
Head head = HeadAPI.getHeadByID(id);
|
Head head = HeadAPI.getHeadByID(id);
|
||||||
if (head != null) {
|
if (head != null) {
|
||||||
uiItem.put(category, head.getItemStack());
|
uiItem.put(category, head.getItemStack());
|
||||||
@ -57,8 +57,8 @@ public class InventoryUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to get an item from the config file.
|
// Try to get an item from the config file.
|
||||||
if (HeadDB.getInstance().getCfg().contains("ui.category." + category + ".item")) {
|
if (HeadDB.getInstance().getConfiguration().contains("ui.category." + category + ".item")) {
|
||||||
String cfg = HeadDB.getInstance().getCfg().getString("ui.category." + category + ".item");
|
String cfg = HeadDB.getInstance().getConfiguration().getString("ui.category." + category + ".item");
|
||||||
Material mat = Material.matchMaterial(cfg);
|
Material mat = Material.matchMaterial(cfg);
|
||||||
|
|
||||||
// AIR is allowed as the fill material for the menu, but not as a category item.
|
// AIR is allowed as the fill material for the menu, but not as a category item.
|
||||||
@ -272,7 +272,7 @@ public class InventoryUtils {
|
|||||||
if (player.hasPermission("headdb.economy.free") || player.hasPermission("headdb.economy." + category + ".free")) return 0;
|
if (player.hasPermission("headdb.economy.free") || player.hasPermission("headdb.economy." + category + ".free")) return 0;
|
||||||
|
|
||||||
// Otherwise, get the price for this category from the config file.
|
// Otherwise, get the price for this category from the config file.
|
||||||
return HeadDB.getInstance().getCfg().getDouble("economy.cost." + category);
|
return HeadDB.getInstance().getConfiguration().getDouble("economy.cost." + category);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean processPayment(Player player, int amount, String category, String description) {
|
public static boolean processPayment(Player player, int amount, String category, String description) {
|
||||||
|
@ -13,7 +13,7 @@ public class JoinListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onJoin(PlayerJoinEvent e) {
|
public void onJoin(PlayerJoinEvent e) {
|
||||||
HeadDB.getInstance().getPlayerdata().set(e.getPlayer().getUniqueId().toString() + ".username", e.getPlayer().getName());
|
HeadDB.getInstance().getStorage().getPlayerData().set(e.getPlayer().getUniqueId().toString() + ".username", e.getPlayer().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ public class Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void log(LogLevel level, String message) {
|
public static void log(LogLevel level, String message) {
|
||||||
if (level == LogLevel.DEBUG && !HeadDB.getInstance().getCfg().getBoolean("debug")) {
|
if (level == LogLevel.DEBUG && !HeadDB.getInstance().getStorage().getConfig().getBoolean("debug")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bukkit.getConsoleSender().sendMessage(Utils.colorize("&7[&9&l" + name + "&7] " + level.getColor() + "[" + level.name() + "]: " + message));
|
Bukkit.getConsoleSender().sendMessage(Utils.colorize("&7[&9&l" + name + "&7] " + level.getColor() + "[" + level.name() + "]: " + message));
|
||||||
|
27
src/main/java/tsp/headdb/util/Storage.java
Normale Datei
27
src/main/java/tsp/headdb/util/Storage.java
Normale Datei
@ -0,0 +1,27 @@
|
|||||||
|
package tsp.headdb.util;
|
||||||
|
|
||||||
|
import de.leonhard.storage.Config;
|
||||||
|
import de.leonhard.storage.Json;
|
||||||
|
import de.leonhard.storage.LightningBuilder;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
public class Storage {
|
||||||
|
|
||||||
|
private Config config;
|
||||||
|
private Json playerdata;
|
||||||
|
|
||||||
|
public Storage init(JavaPlugin plugin) {
|
||||||
|
config = LightningBuilder.fromPath("config.yml", plugin.getDataFolder().getAbsolutePath()).createConfig().addDefaultsFromInputStream();
|
||||||
|
playerdata = LightningBuilder.fromPath("playerdata.json", plugin.getDataFolder().getAbsolutePath()).createJson();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Config getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Json getPlayerData() {
|
||||||
|
return playerdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,7 @@ description: ${project.description}
|
|||||||
main: tsp.headdb.HeadDB
|
main: tsp.headdb.HeadDB
|
||||||
version: ${project.version}
|
version: ${project.version}
|
||||||
softdepend: [Vault]
|
softdepend: [Vault]
|
||||||
api-version: 1.16
|
api-version: 1.13
|
||||||
author: Silent
|
author: Silent
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren