Merge pull request #16

Add UI customization options to config.yml & economy
Dieser Commit ist enthalten in:
Silent 2021-07-05 14:42:16 +02:00 committet von GitHub
Commit 149512d207
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
10 geänderte Dateien mit 240 neuen und 2094 gelöschten Zeilen

Datei anzeigen

@ -68,6 +68,13 @@
<artifactId>anvilgui</artifactId> <artifactId>anvilgui</artifactId>
<version>1.5.1-SNAPSHOT</version> <version>1.5.1-SNAPSHOT</version>
</dependency> </dependency>
<!-- Vault -->
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

Datei anzeigen

@ -13,12 +13,15 @@ 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.Utils; import tsp.headdb.util.Utils;
import org.bukkit.plugin.RegisteredServiceProvider;
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 Config config;
private Json playerdata; private Json playerdata;
private Economy economy = null;
@Override @Override
public void onEnable() { public void onEnable() {
@ -28,6 +31,16 @@ public class HeadDB extends JavaPlugin {
config = LightningBuilder.fromPath("config.yml", "plugins/HeadDB").createConfig().addDefaultsFromInputStream(); config = LightningBuilder.fromPath("config.yml", "plugins/HeadDB").createConfig().addDefaultsFromInputStream();
playerdata = LightningBuilder.fromPath("playerdata.json", "plugins/HeadDB").createJson(); playerdata = LightningBuilder.fromPath("playerdata.json", "plugins/HeadDB").createJson();
if (config.getBoolean("economy.enable")) {
Log.debug("Starting economy...");
this.economy = this.setupEconomy();
if (this.economy == null) {
Log.error("Economy support requires Vault and an economy provider plugin.");
} else {
Log.info("Economy provider: " + this.economy.getName());
}
}
Log.debug("Starting metrics..."); Log.debug("Starting metrics...");
new Metrics(this, Utils.METRICS_ID); new Metrics(this, Utils.METRICS_ID);
@ -52,6 +65,15 @@ public class HeadDB extends JavaPlugin {
Log.info("Done!"); Log.info("Done!");
} }
private Economy setupEconomy() {
if (!this.getServer().getPluginManager().isPluginEnabled("Vault")) return null;
RegisteredServiceProvider<Economy> economyProvider = this.getServer().getServicesManager().getRegistration(Economy.class);
if (economyProvider == null) return null;
return this.economy = economyProvider.getProvider();
}
public Config getCfg() { public Config getCfg() {
return config; return config;
} }
@ -64,4 +86,7 @@ public class HeadDB extends JavaPlugin {
return instance; return instance;
} }
public Economy getEconomy() {
return this.economy;
}
} }

Datei anzeigen

@ -9,7 +9,6 @@ import org.bukkit.inventory.meta.SkullMeta;
import tsp.headdb.database.Category; import tsp.headdb.database.Category;
import tsp.headdb.util.Log; import tsp.headdb.util.Log;
import tsp.headdb.util.Utils; import tsp.headdb.util.Utils;
import tsp.headdb.util.XMaterial;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;

Datei anzeigen

@ -6,7 +6,6 @@ import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import tsp.headdb.util.Utils; import tsp.headdb.util.Utils;
import tsp.headdb.util.XMaterial;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

Datei anzeigen

@ -11,25 +11,26 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public enum Category { public enum Category {
ALPHABET("alphabet", ChatColor.YELLOW, 20),
ALPHABET("alphabet", ChatColor.YELLOW), ANIMALS("animals", ChatColor.DARK_AQUA, 21),
ANIMALS("animals", ChatColor.DARK_AQUA), BLOCKS("blocks", ChatColor.DARK_GRAY, 22),
BLOCKS("blocks", ChatColor.DARK_GRAY), DECORATION("decoration", ChatColor.LIGHT_PURPLE, 23),
DECORATION("decoration", ChatColor.LIGHT_PURPLE), FOOD_DRINKS("food-drinks", ChatColor.GOLD, 24),
FOOD_DRINKS("food-drinks", ChatColor.GOLD), HUMANS("humans", ChatColor.DARK_BLUE, 29),
HUMANS("humans", ChatColor.DARK_BLUE), HUMANOID("humanoid", ChatColor.AQUA, 30),
HUMANOID("humanoid", ChatColor.AQUA), MISCELLANEOUS("miscellaneous", ChatColor.DARK_GREEN, 31),
MISCELLANEOUS("miscellaneous", ChatColor.DARK_GREEN), MONSTERS("monsters", ChatColor.RED, 32),
MONSTERS("monsters", ChatColor.RED), PLANTS("plants", ChatColor.GREEN, 33);
PLANTS("plants", ChatColor.GREEN);
private final String name; private final String name;
private final ChatColor color; private final ChatColor color;
private final int location;
private final Map<Category, Head> item = new HashMap<>(); private final Map<Category, Head> item = new HashMap<>();
Category(String name, ChatColor color) { Category(String name, ChatColor color, int location) {
this.name = name; this.name = name;
this.color = color; this.color = color;
this.location = location;
} }
public String getName() { public String getName() {
@ -40,6 +41,10 @@ public enum Category {
return color; return color;
} }
public int getLocation() {
return location;
}
public ItemStack getItem() { public ItemStack getItem() {
if (item.containsKey(this)) { if (item.containsKey(this)) {
return item.get(this).getItemStack(); return item.get(this).getItemStack();

Datei anzeigen

@ -7,18 +7,70 @@ import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import tsp.headdb.HeadDB;
import tsp.headdb.api.Head; import tsp.headdb.api.Head;
import tsp.headdb.api.HeadAPI; import tsp.headdb.api.HeadAPI;
import tsp.headdb.api.LocalHead; import tsp.headdb.api.LocalHead;
import tsp.headdb.database.Category; import tsp.headdb.database.Category;
import tsp.headdb.util.Utils; import tsp.headdb.util.Utils;
import tsp.headdb.util.XMaterial;
import net.milkbowl.vault.economy.Economy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class InventoryUtils { public class InventoryUtils {
private static final Map<String, Integer> uiLocation = new HashMap<>();
private static final Map<String, ItemStack> uiItem = new HashMap<>();
public static int uiGetLocation(String category, int slot) {
// Try to use the cached value first.
if (uiLocation.containsKey(category)) return uiLocation.get(category);
// Try to get the value from the config file.
if (HeadDB.getInstance().getCfg().contains("ui.category." + category + ".location")) {
uiLocation.put(category, HeadDB.getInstance().getCfg().getInt("ui.category." + category + ".location"));
return uiLocation.get(category);
}
// No valid value in the config file, return the given default.
uiLocation.put(category, slot);
return slot;
}
public static ItemStack uiGetItem(String category, ItemStack item) {
// Try to use the cached item first.
if (uiItem.containsKey(category)) return uiItem.get(category);
// Try to get a head from the config file.
if (HeadDB.getInstance().getCfg().contains("ui.category." + category + ".head")) {
int id = HeadDB.getInstance().getCfg().getInt("ui.category." + category + ".head");
Head head = HeadAPI.getHeadByID(id);
if (head != null) {
uiItem.put(category, head.getItemStack());
return uiItem.get(category);
}
}
// Try to get an item from the config file.
if (HeadDB.getInstance().getCfg().contains("ui.category." + category + ".item")) {
String cfg = HeadDB.getInstance().getCfg().getString("ui.category." + category + ".item");
Material mat = Material.matchMaterial(cfg);
// AIR is allowed as the fill material for the menu, but not as a category item.
if (mat != null && (category.equals("fill") || mat != Material.AIR)) {
uiItem.put(category, new ItemStack(mat));
return uiItem.get(category);
}
}
// No valid head or item in the config file, return the given default.
uiItem.put(category, item);
return item;
}
public static void openLocalMenu(Player player) { public static void openLocalMenu(Player player) {
PagedPane pane = new PagedPane(4, 6, Utils.colorize("&c&lHeadDB &8- &aLocal Heads")); PagedPane pane = new PagedPane(4, 6, Utils.colorize("&c&lHeadDB &8- &aLocal Heads"));
@ -27,13 +79,11 @@ public class InventoryUtils {
for (LocalHead localHead : heads) { for (LocalHead localHead : heads) {
pane.addButton(new Button(localHead.getItemStack(), e -> { pane.addButton(new Button(localHead.getItemStack(), e -> {
if (e.getClick() == ClickType.SHIFT_LEFT) { if (e.getClick() == ClickType.SHIFT_LEFT) {
ItemStack item = localHead.getItemStack(); purchaseItem(player, localHead.getItemStack(), 64, "local", localHead.getName());
item.setAmount(64);
player.getInventory().addItem(item);
return; return;
} }
if (e.getClick() == ClickType.LEFT) { if (e.getClick() == ClickType.LEFT) {
player.getInventory().addItem(localHead.getItemStack()); purchaseItem(player, localHead.getItemStack(), 1, "local", localHead.getName());
return; return;
} }
if (e.getClick() == ClickType.RIGHT) { if (e.getClick() == ClickType.RIGHT) {
@ -53,13 +103,11 @@ public class InventoryUtils {
for (Head head : heads) { for (Head head : heads) {
pane.addButton(new Button(head.getItemStack(), e -> { pane.addButton(new Button(head.getItemStack(), e -> {
if (e.getClick() == ClickType.SHIFT_LEFT) { if (e.getClick() == ClickType.SHIFT_LEFT) {
ItemStack item = head.getItemStack(); purchaseItem(player, head.getItemStack(), 64, head.getCategory().getName(), head.getName());
item.setAmount(64);
player.getInventory().addItem(item);
return; return;
} }
if (e.getClick() == ClickType.LEFT) { if (e.getClick() == ClickType.LEFT) {
player.getInventory().addItem(head.getItemStack()); purchaseItem(player, head.getItemStack(), 1, head.getCategory().getName(), head.getName());
} }
if (e.getClick() == ClickType.RIGHT) { if (e.getClick() == ClickType.RIGHT) {
HeadAPI.removeFavoriteHead(player.getUniqueId(), head.getId()); HeadAPI.removeFavoriteHead(player.getUniqueId(), head.getId());
@ -79,13 +127,11 @@ public class InventoryUtils {
for (Head head : heads) { for (Head head : heads) {
pane.addButton(new Button(head.getItemStack(), e -> { pane.addButton(new Button(head.getItemStack(), e -> {
if (e.getClick() == ClickType.SHIFT_LEFT) { if (e.getClick() == ClickType.SHIFT_LEFT) {
ItemStack item = head.getItemStack(); purchaseItem(player, head.getItemStack(), 64, head.getCategory().getName(), head.getName());
item.setAmount(64);
player.getInventory().addItem(item);
return; return;
} }
if (e.getClick() == ClickType.LEFT) { if (e.getClick() == ClickType.LEFT) {
player.getInventory().addItem(head.getItemStack()); purchaseItem(player, head.getItemStack(), 1, head.getCategory().getName(), head.getName());
} }
if (e.getClick() == ClickType.RIGHT) { if (e.getClick() == ClickType.RIGHT) {
HeadAPI.addFavoriteHead(player.getUniqueId(), head.getId()); HeadAPI.addFavoriteHead(player.getUniqueId(), head.getId());
@ -105,13 +151,11 @@ public class InventoryUtils {
for (Head head : heads) { for (Head head : heads) {
pane.addButton(new Button(head.getItemStack(), e -> { pane.addButton(new Button(head.getItemStack(), e -> {
if (e.getClick() == ClickType.SHIFT_LEFT) { if (e.getClick() == ClickType.SHIFT_LEFT) {
ItemStack item = head.getItemStack(); purchaseItem(player, head.getItemStack(), 64, head.getCategory().getName(), head.getName());
item.setAmount(64);
player.getInventory().addItem(item);
return; return;
} }
if (e.getClick() == ClickType.LEFT) { if (e.getClick() == ClickType.LEFT) {
player.getInventory().addItem(head.getItemStack()); purchaseItem(player, head.getItemStack(), 1, head.getCategory().getName(), head.getName());
} }
if (e.getClick() == ClickType.RIGHT) { if (e.getClick() == ClickType.RIGHT) {
HeadAPI.addFavoriteHead(player.getUniqueId(), head.getId()); HeadAPI.addFavoriteHead(player.getUniqueId(), head.getId());
@ -130,13 +174,11 @@ public class InventoryUtils {
for (Head head : heads) { for (Head head : heads) {
pane.addButton(new Button(head.getItemStack(), e -> { pane.addButton(new Button(head.getItemStack(), e -> {
if (e.getClick() == ClickType.SHIFT_LEFT) { if (e.getClick() == ClickType.SHIFT_LEFT) {
ItemStack item = head.getItemStack(); purchaseItem(player, head.getItemStack(), 64, head.getCategory().getName(), head.getName());
item.setAmount(64);
player.getInventory().addItem(item);
return; return;
} }
if (e.getClick() == ClickType.LEFT) { if (e.getClick() == ClickType.LEFT) {
player.getInventory().addItem(head.getItemStack()); purchaseItem(player, head.getItemStack(), 1, head.getCategory().getName(), head.getName());
} }
if (e.getClick() == ClickType.RIGHT) { if (e.getClick() == ClickType.RIGHT) {
HeadAPI.addFavoriteHead(player.getUniqueId(), head.getId()); HeadAPI.addFavoriteHead(player.getUniqueId(), head.getId());
@ -151,21 +193,20 @@ public class InventoryUtils {
public static void openDatabase(Player player) { public static void openDatabase(Player player) {
Inventory inventory = Bukkit.createInventory(null, 54, Utils.colorize("&c&lHeadDB &8(" + HeadAPI.getHeads().size() + ")")); Inventory inventory = Bukkit.createInventory(null, 54, Utils.colorize("&c&lHeadDB &8(" + HeadAPI.getHeads().size() + ")"));
fill(inventory, new ItemStack(Material.BLACK_STAINED_GLASS_PANE));
for (Category category : Category.getCategories()) { for (Category category : Category.getCategories()) {
ItemStack item = category.getItem(); ItemStack item = uiGetItem(category.getName(), category.getItem());
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
meta.setDisplayName(Utils.colorize(category.getColor() + "&l" + category.getName().toUpperCase())); meta.setDisplayName(Utils.colorize(category.getColor() + "&l" + category.getName().toUpperCase()));
List<String> lore = new ArrayList<>(); List<String> lore = new ArrayList<>();
lore.add(Utils.colorize("&e" + HeadAPI.getHeads(category).size() + " heads")); lore.add(Utils.colorize("&e" + HeadAPI.getHeads(category).size() + " heads"));
meta.setLore(lore); meta.setLore(lore);
item.setItemMeta(meta); item.setItemMeta(meta);
inventory.addItem(item); inventory.setItem(uiGetLocation(category.getName(), category.getLocation()), item);
} }
if (player.hasPermission("headdb.favorites")) { if (player.hasPermission("headdb.favorites")) {
inventory.setItem(39, buildButton( inventory.setItem(uiGetLocation("favorites", 39), buildButton(
XMaterial.BOOK.parseItem(), uiGetItem("favorites", new ItemStack(Material.BOOK)),
"&eFavorites", "&eFavorites",
"", "",
"&8Click to view your favorites") "&8Click to view your favorites")
@ -173,8 +214,8 @@ public class InventoryUtils {
} }
if (player.hasPermission("headdb.search")) { if (player.hasPermission("headdb.search")) {
inventory.setItem(40, buildButton( inventory.setItem(uiGetLocation("search", 40), buildButton(
XMaterial.DARK_OAK_SIGN.parseItem(), uiGetItem("search", new ItemStack(Material.DARK_OAK_SIGN)),
"&9Search", "&9Search",
"", "",
"&8Click to open search menu" "&8Click to open search menu"
@ -182,36 +223,33 @@ public class InventoryUtils {
} }
if (player.hasPermission("headdb.local")) { if (player.hasPermission("headdb.local")) {
inventory.setItem(41, buildButton( inventory.setItem(uiGetLocation("local", 41), buildButton(
XMaterial.COMPASS.parseItem(), uiGetItem("local", new ItemStack(Material.COMPASS)),
"&aLocal", "&aLocal",
"", "",
"&8Heads from any players that have logged on the server" "&8Heads from any players that have logged on the server"
)); ));
} }
fill(inventory);
player.openInventory(inventory); player.openInventory(inventory);
} }
public static void fill(Inventory inv, ItemStack item) { public static void fill(Inventory inv) {
int size = inv.getSize(); ItemStack item = uiGetItem("fill", new ItemStack(Material.BLACK_STAINED_GLASS_PANE));
int[] ignored = new int[]{20, 21, 22, 23, 24, 29, 30, 31, 32, 33}; // Do not bother filling the inventory if item to fill it with is AIR.
if (item == null || item.getType() == Material.AIR) return;
// Fill // Fill any non-empty inventory slots with the given item.
int size = inv.getSize();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (!contains(i, ignored)) { ItemStack slotItem = inv.getItem(i);
ItemStack slotItem = inv.getItem(i); if (slotItem == null || slotItem.getType() == Material.AIR) {
if (slotItem == null || slotItem.getType() == Material.AIR) { inv.setItem(i, item);
inv.setItem(i, item);
}
} }
} }
} }
private static boolean contains(int n, int... array) {
return Arrays.binarySearch(array, n) > -1;
}
private static ItemStack buildButton(ItemStack item, String name, String... lore) { private static ItemStack buildButton(ItemStack item, String name, String... lore) {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
meta.setDisplayName(Utils.colorize(name)); meta.setDisplayName(Utils.colorize(name));
@ -228,4 +266,45 @@ public class InventoryUtils {
return item; return item;
} }
public static double getCategoryCost(Player player, String category) {
// If the player has the permission headdb.economy.free or headdb.economy.CATEGORY.free, the item is free.
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.
return HeadDB.getInstance().getCfg().getDouble("economy.cost." + category);
}
public static boolean processPayment(Player player, int amount, String category, String description) {
Economy economy = HeadDB.getInstance().getEconomy();
// If economy is disabled or no plugin is present, the item is free.
// Don't mention receiving it for free in this case, since it is always free.
if (economy == null) {
player.sendMessage(String.format("You received %d x %s!", amount, description));
return true;
}
double cost = getCategoryCost(player, category) * amount;
// If the cost is higher than zero, attempt to charge for it.
if (cost > 0) {
if (economy.has(player, cost)) {
economy.withdrawPlayer(player, cost);
player.sendMessage(String.format("You purchased %d x %s for %.2f %s!", amount, description, cost, economy.currencyNamePlural()));
return true;
}
player.sendMessage(String.format("You do not have enough %s to purchase %d x %s.", economy.currencyNamePlural(), amount, description));
return false;
}
// Otherwise, the item is free.
player.sendMessage(String.format("You received %d x %s for free!", amount, description));
return true;
}
public static void purchaseItem(Player player, ItemStack item, int amount, String category, String description) {
if (!processPayment(player, amount, category, description)) return;
item.setAmount(amount);
player.getInventory().addItem(item);
}
} }

Datei anzeigen

@ -2,6 +2,7 @@ package tsp.headdb.listener;
import net.wesjd.anvilgui.AnvilGUI; import net.wesjd.anvilgui.AnvilGUI;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -13,7 +14,6 @@ import tsp.headdb.HeadDB;
import tsp.headdb.database.Category; import tsp.headdb.database.Category;
import tsp.headdb.inventory.InventoryUtils; import tsp.headdb.inventory.InventoryUtils;
import tsp.headdb.util.Utils; import tsp.headdb.util.Utils;
import tsp.headdb.util.XMaterial;
public class MenuListener implements Listener { public class MenuListener implements Listener {
@ -35,7 +35,7 @@ public class MenuListener implements Listener {
int slot = e.getSlot(); int slot = e.getSlot();
ItemStack item = inventory.getItem(slot); ItemStack item = inventory.getItem(slot);
if (item != null && item.getType() != XMaterial.AIR.parseMaterial()) { if (item != null && item.getType() != Material.AIR) {
String name = ChatColor.stripColor(item.getItemMeta().getDisplayName().toLowerCase()); String name = ChatColor.stripColor(item.getItemMeta().getDisplayName().toLowerCase());
if (name.equalsIgnoreCase("favorites")) { if (name.equalsIgnoreCase("favorites")) {
if (!player.hasPermission("headdb.favorites")) { if (!player.hasPermission("headdb.favorites")) {

Datei-Diff unterdrückt, da er zu groß ist Diff laden

Datei anzeigen

@ -7,5 +7,69 @@ asyncStartup: false
# If the cached heads are older than these amount of seconds, the plugin will refresh the database # If the cached heads are older than these amount of seconds, the plugin will refresh the database
refresh: 3600 refresh: 3600
# Economy options
economy:
enable: false
cost:
alphabet: 100
animals: 100
blocks: 100
decoration: 100
food-drinks: 100
humans: 100
humanoid: 100
miscellaneous: 100
monsters: 100
plants: 100
local: 1000
# UI customization options.
ui:
category:
# Head categories. You can use item: instead of head: here, but AIR is not supported.
alphabet:
location: 20
head: 1788
animals:
location: 21
head: 5741
blocks:
location: 22
head: 8624
decoration:
location: 23
head: 11046
food-drinks:
location: 24
head: 17442
humans:
location: 29
head: 19361
humanoid:
location: 30
head: 28320
miscellaneous:
location: 31
head: 32746
monsters:
location: 32
head: 34819
plants:
location: 33
head: 37278
# Meta categories, used for UI elements. AIR is not supported. You can use head: instead of item: here.
favorites:
location: 39
item: BOOK
search:
location: 40
item: DARK_OAK_SIGN
local:
location: 41
item: COMPASS
# Item used to fill unused slots in the categories menu. AIR is supported. You can use head: instead of item: here.
fill:
item: BLACK_STAINED_GLASS_PANE
# Debug Mode # Debug Mode
debug: false debug: false

Datei anzeigen

@ -3,6 +3,7 @@ description: ${project.description}
main: tsp.headdb.HeadDB main: tsp.headdb.HeadDB
version: ${project.version} version: ${project.version}
softdepend: [Vault]
api-version: 1.16 api-version: 1.16
author: Silent author: Silent