Updated to 2.0.4 (not too much manual changes).

This commit is contained in:
CoderMarido 2018-08-24 18:09:50 +02:00
parent 02be1447fc
commit 122aecdc7e
7 changed files with 596 additions and 559 deletions

View File

@ -1,24 +1,11 @@
package net.sothatsit.heads; package net.sothatsit.heads;
import net.sothatsit.heads.cache.*; import java.io.File;
import net.sothatsit.heads.cache.legacy.CacheFileConverter; import java.io.IOException;
import net.sothatsit.heads.command.HeadsCommand; import java.util.Arrays;
import net.sothatsit.heads.command.RuntimeCommand; import java.util.Map;
import net.sothatsit.heads.config.FileConfigFile; import java.util.function.Consumer;
import net.sothatsit.heads.config.MainConfig;
import net.sothatsit.heads.cache.legacy.LegacyCacheConfig;
import net.sothatsit.heads.config.lang.Lang;
import net.sothatsit.heads.config.lang.LangConfig;
import net.sothatsit.heads.config.menu.Menus;
import net.sothatsit.heads.config.oldmenu.MenuConfig;
import net.sothatsit.heads.economy.*;
import net.sothatsit.heads.menu.ui.InventoryMenu;
import net.sothatsit.heads.oldmenu.ClickInventory;
import net.sothatsit.heads.util.Clock;
import net.sothatsit.heads.volatilecode.injection.ProtocolHackFixer;
import net.sothatsit.heads.volatilecode.reflection.Version;
import net.sothatsit.heads.volatilecode.reflection.craftbukkit.CommandMap;
import net.sothatsit.heads.volatilecode.reflection.craftbukkit.CraftServer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
@ -34,423 +21,441 @@ import org.bukkit.inventory.InventoryHolder;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; import net.sothatsit.heads.cache.CacheFile;
import java.io.IOException; import net.sothatsit.heads.cache.CacheHead;
import java.util.Arrays; import net.sothatsit.heads.cache.ModsFile;
import java.util.Map; import net.sothatsit.heads.cache.ModsFileHeader;
import java.util.function.Consumer; import net.sothatsit.heads.cache.legacy.CacheFileConverter;
import net.sothatsit.heads.cache.legacy.LegacyCacheConfig;
import net.sothatsit.heads.command.HeadsCommand;
import net.sothatsit.heads.command.RuntimeCommand;
import net.sothatsit.heads.config.FileConfigFile;
import net.sothatsit.heads.config.MainConfig;
import net.sothatsit.heads.config.lang.Lang;
import net.sothatsit.heads.config.lang.LangConfig;
import net.sothatsit.heads.config.menu.Menus;
import net.sothatsit.heads.config.oldmenu.MenuConfig;
import net.sothatsit.heads.economy.Economy;
import net.sothatsit.heads.economy.ItemEconomy;
import net.sothatsit.heads.economy.NoEconomy;
import net.sothatsit.heads.economy.PlayerPointsEconomy;
import net.sothatsit.heads.economy.VaultEconomy;
import net.sothatsit.heads.menu.ui.InventoryMenu;
import net.sothatsit.heads.oldmenu.ClickInventory;
import net.sothatsit.heads.util.Clock;
import net.sothatsit.heads.volatilecode.injection.ProtocolHackFixer;
import net.sothatsit.heads.volatilecode.reflection.Version;
import net.sothatsit.heads.volatilecode.reflection.craftbukkit.CommandMap;
import net.sothatsit.heads.volatilecode.reflection.craftbukkit.CraftServer;
public class Heads extends JavaPlugin implements Listener { public class Heads extends JavaPlugin implements Listener {
private static Heads instance; private static Heads instance;
private CacheFile cache; private CacheFile cache;
private MenuConfig oldMenuConfig; private MenuConfig oldMenuConfig;
private Menus menus; private Menus menus;
private MainConfig mainConfig; private MainConfig mainConfig;
private LangConfig langConfig; private LangConfig langConfig;
private Economy economy; private Economy economy;
private LegacyIDs legacyIDs; private LegacyIDs legacyIDs;
private boolean commandsRegistered = false; private boolean commandsRegistered = false;
private boolean blockStoreAvailable = false; private boolean blockStoreAvailable = false;
@Override
public void onEnable() {
if(Version.isBelow(Version.v1_8)) {
System.err.println("------------------------------------------------------------");
System.err.println(" Heads no longer supports versions below MineCraft 1.8 ");
System.err.println(" Please switch to Heads version 1.15.1 or before ");
System.err.println("------------------------------------------------------------");
Bukkit.getPluginManager().disablePlugin(this);
return;
}
instance = this;
Clock timer = Clock.start();
loadCache();
try {
legacyIDs = LegacyIDs.readResource("legacy-ids.txt");
} catch(IOException exception) {
legacyIDs = LegacyIDs.EMPTY;
severe("Unable to load legacy IDs to perform conversion from older Spigot versions");
exception.printStackTrace();
}
this.menus = new Menus();
this.menus.reload();
this.oldMenuConfig = new MenuConfig(getVersionedConfig("menus.yml")); @Override
this.langConfig = new LangConfig(); public void onEnable() {
this.mainConfig = new MainConfig(); if (Version.isBelow(Version.v1_8)) {
this.economy = hookEconomy(); System.err.println("------------------------------------------------------------");
System.err.println(" Heads no longer supports versions below MineCraft 1.8 ");
System.err.println(" Please switch to Heads version 1.15.1 or before ");
System.err.println("------------------------------------------------------------");
Bukkit.getPluginManager().disablePlugin(this);
return;
}
ProtocolHackFixer.fix(); instance = this;
registerCommands(); Clock timer = Clock.start();
tryHookBlockStore();
new HeadNamer().registerEvents(); loadCache();
Bukkit.getPluginManager().registerEvents(this, this); try {
legacyIDs = LegacyIDs.readResource("legacy-ids.txt");
} catch (IOException exception) {
legacyIDs = LegacyIDs.EMPTY;
severe("Unable to load legacy IDs to perform conversion from older Spigot versions");
exception.printStackTrace();
}
if(mainConfig.shouldCheckForUpdates()) { this.menus = new Menus();
checkForUpdates(); this.menus.reload();
}
info("Heads plugin enabled with " + cache.getHeadCount() + " heads " + timer); this.oldMenuConfig = new MenuConfig(getVersionedConfig("menus.yml"));
} this.langConfig = new LangConfig();
this.mainConfig = new MainConfig();
this.economy = hookEconomy();
@Override ProtocolHackFixer.fix();
public void onDisable() {
instance = null;
unregisterCommands();
}
private void checkForUpdates() { registerCommands();
async(() -> { tryHookBlockStore();
try {
String currentVersion = UpdateChecker.getCurrentVersion();
String latestVersion = UpdateChecker.getLatestVersion();
if(!UpdateChecker.isNewerVersion(latestVersion)) new HeadNamer().registerEvents();
return;
warning("A newer version of Heads, Heads v" + latestVersion + ", is available for download"); Bukkit.getPluginManager().registerEvents(this, this);
warning("You are currently using Heads v" + currentVersion);
} catch(IOException e) {
severe("There was an error checking for an update for Heads");
}
});
}
private void registerCommands() { if (mainConfig.shouldCheckForUpdates()) {
if (commandsRegistered) { checkForUpdates();
unregisterCommands(); }
}
SimpleCommandMap commandMap = CraftServer.get().getCommandMap(); info("Heads plugin enabled with " + cache.getHeadCount() + " heads " + timer);
}
RuntimeCommand heads = new RuntimeCommand(mainConfig.getHeadCommand()); @Override
heads.setExecutor(new HeadsCommand()); public void onDisable() {
heads.setDescription(mainConfig.getHeadDescription()); instance = null;
heads.setAliases(Arrays.asList(mainConfig.getHeadAliases()));
commandMap.register("heads", heads);
commandsRegistered = true;
}
private void unregisterCommands() {
SimpleCommandMap commandMap = CraftServer.get().getCommandMap();
Map<String, Command> map = CommandMap.getCommandMap(commandMap);
map.values().removeIf(command -> command instanceof RuntimeCommand);
commandsRegistered = false;
}
public void reloadConfigs() { unregisterCommands();
oldMenuConfig.reload(); }
menus.reload();
langConfig.reload();
mainConfig.reload();
registerCommands(); private void checkForUpdates() {
async(() -> {
try {
String currentVersion = UpdateChecker.getCurrentVersion();
String latestVersion = UpdateChecker.getLatestVersion();
economy = hookEconomy(); if (!UpdateChecker.isNewerVersion(latestVersion))
return;
tryHookBlockStore(); warning("A newer version of Heads, Heads v" + latestVersion + ", is available for download");
} warning("You are currently using Heads v" + currentVersion);
} catch (IOException e) {
severe("There was an error checking for an update for Heads");
}
});
}
public File getCacheFile() { private void registerCommands() {
if(!getDataFolder().exists() && !getDataFolder().mkdirs()) if (commandsRegistered) {
throw new RuntimeException("Unable to create the data folder to save plugin files"); unregisterCommands();
}
if(!getDataFolder().isDirectory()) SimpleCommandMap commandMap = CraftServer.get().getCommandMap();
throw new RuntimeException("plugins/Heads should be a directory, yet there is a file with the same name");
return new File(getDataFolder(), "heads.cache"); RuntimeCommand heads = new RuntimeCommand(mainConfig.getHeadCommand());
} heads.setExecutor(new HeadsCommand());
heads.setDescription(mainConfig.getHeadDescription());
heads.setAliases(Arrays.asList(mainConfig.getHeadAliases()));
private CacheFile loadCache() { commandMap.register("heads", heads);
File file = getCacheFile();
FileConfigFile legacyConfig = new FileConfigFile("cache.yml");
boolean requiresWrite = false; commandsRegistered = true;
}
if(!file.exists()) { private void unregisterCommands() {
requiresWrite = true; SimpleCommandMap commandMap = CraftServer.get().getCommandMap();
Map<String, Command> map = CommandMap.getCommandMap(commandMap);
if(legacyConfig.getFile().exists()) { map.values().removeIf(command -> command instanceof RuntimeCommand);
Clock timer = Clock.start();
LegacyCacheConfig legacy = new LegacyCacheConfig(legacyConfig); commandsRegistered = false;
cache = CacheFileConverter.convertToCacheFile("main-cache", legacy); }
info("Converted legacy yaml cache file to new binary file " + timer); public void reloadConfigs() {
} else { oldMenuConfig.reload();
cache = new CacheFile("main-cache"); menus.reload();
} langConfig.reload();
} else { mainConfig.reload();
try {
Clock timer = Clock.start();
cache = CacheFile.read(file); registerCommands();
info("Loaded cache file " + timer); economy = hookEconomy();
} catch (IOException e) {
severe("Unable to read heads.cache file");
throw new RuntimeException("There was an exception reading the heads.cache file", e);
}
}
if(installAddons() || requiresWrite) { tryHookBlockStore();
saveCache(); }
}
if(legacyConfig.getFile().exists() && !legacyConfig.getFile().delete()) { public File getCacheFile() {
severe("Unable to delete legacy yaml cache file"); if (!getDataFolder().exists() && !getDataFolder().mkdirs())
} throw new RuntimeException("Unable to create the data folder to save plugin files");
return cache; if (!getDataFolder().isDirectory())
} throw new RuntimeException("plugins/Heads should be a directory, yet there is a file with the same name");
public void saveCache() { return new File(getDataFolder(), "heads.cache");
File file = getCacheFile(); }
try { private CacheFile loadCache() {
Clock timer = Clock.start(); File file = getCacheFile();
FileConfigFile legacyConfig = new FileConfigFile("cache.yml");
cache.write(file); boolean requiresWrite = false;
info("Saved cache file " + timer); if (!file.exists()) {
} catch (IOException e) { requiresWrite = true;
severe("Unable to save the cache to heads.cache");
throw new RuntimeException("There was an exception saving the cache", e);
}
}
private ModsFileHeader readModsFileHeader() { if (legacyConfig.getFile().exists()) {
try { Clock timer = Clock.start();
return ModsFileHeader.readResource("cache.mods");
} catch (IOException e) {
severe("Unable to read header of cache.mods");
throw new RuntimeException("Unable to read header of cache.mods", e);
}
}
private ModsFile readModsFile() { LegacyCacheConfig legacy = new LegacyCacheConfig(legacyConfig);
try { cache = CacheFileConverter.convertToCacheFile("main-cache", legacy);
return ModsFile.readResource("cache.mods");
} catch (IOException e) {
severe("Unable to read mods from cache.mods");
throw new RuntimeException("Unable to read mods from cache.mods", e);
}
}
private boolean installAddons() { info("Converted legacy yaml cache file to new binary file " + timer);
Clock timer = Clock.start(); } else {
cache = new CacheFile("main-cache");
}
} else {
try {
Clock timer = Clock.start();
ModsFileHeader header = readModsFileHeader(); cache = CacheFile.read(file);
int newMods = header.getUninstalledMods(cache);
if(newMods == 0) info("Loaded cache file " + timer);
return false; } catch (IOException e) {
severe("Unable to read heads.cache file");
throw new RuntimeException("There was an exception reading the heads.cache file", e);
}
}
ModsFile mods = readModsFile(); if (installAddons() || requiresWrite) {
saveCache();
}
int newHeads = mods.installMods(cache); if (legacyConfig.getFile().exists() && !legacyConfig.getFile().delete()) {
severe("Unable to delete legacy yaml cache file");
}
if(newHeads > 0) { return cache;
info("Added " + newHeads + " new heads from " + newMods + " addons " + timer); }
} else {
info("Installed " + newMods + " addons " + timer);
}
return true; public void saveCache() {
} File file = getCacheFile();
private Economy hookEconomy() { try {
if(!mainConfig.isEconomyEnabled()) Clock timer = Clock.start();
return new NoEconomy();
Economy economy = null; cache.write(file);
if(mainConfig.isVaultEconomyEnabled()) { info("Saved cache file " + timer);
economy = tryHookEconomy(null, new VaultEconomy()); } catch (IOException e) {
} severe("Unable to save the cache to heads.cache");
throw new RuntimeException("There was an exception saving the cache", e);
}
}
if(mainConfig.isItemEconomyEnabled()) { private ModsFileHeader readModsFileHeader() {
economy = tryHookEconomy(economy, new ItemEconomy()); try {
} return ModsFileHeader.readResource("cache.mods");
} catch (IOException e) {
severe("Unable to read header of cache.mods");
throw new RuntimeException("Unable to read header of cache.mods", e);
}
}
if(mainConfig.isPlayerPointsEconomyEnabled()) { private ModsFile readModsFile() {
economy = tryHookEconomy(economy, new PlayerPointsEconomy()); try {
} return ModsFile.readResource("cache.mods");
} catch (IOException e) {
severe("Unable to read mods from cache.mods");
throw new RuntimeException("Unable to read mods from cache.mods", e);
}
}
if(economy == null || economy instanceof NoEconomy) { private boolean installAddons() {
severe("Economy enabled in config.yml yet Vault, PlayerPoints and Item economies disabled. " + Clock timer = Clock.start();
"Player's will not be able to purchase heads.");
economy = (economy != null ? economy : new NoEconomy()); ModsFileHeader header = readModsFileHeader();
} int newMods = header.getUninstalledMods(cache);
return economy; if (newMods == 0)
} return false;
private Economy tryHookEconomy(Economy currentlyHooked, Economy toHook) { ModsFile mods = readModsFile();
if(currentlyHooked != null) {
warning(toHook.getName() + " economy is not the only economy enabled in the config.yml.");
if(!(currentlyHooked instanceof NoEconomy)) int newHeads = mods.installMods(cache);
return currentlyHooked;
}
if(!toHook.tryHook()) { if (newHeads > 0) {
severe(toHook.getName() + " enabled in config.yml, yet Heads was unable to hook into it."); info("Added " + newHeads + " new heads from " + newMods + " addons " + timer);
return new NoEconomy(); } else {
} info("Installed " + newMods + " addons " + timer);
}
info("Loaded " + toHook.getName() + " economy"); return true;
return toHook; }
}
private void tryHookBlockStore() { private Economy hookEconomy() {
if (mainConfig.shouldUseBlockStore() && Bukkit.getPluginManager().getPlugin("BlockStore") != null) { if (!mainConfig.isEconomyEnabled())
blockStoreAvailable = false; return new NoEconomy();
try { Economy economy = null;
Class<?> apiClass = Class.forName("net.sothatsit.blockstore.BlockStoreApi");
if (mainConfig.isVaultEconomyEnabled()) {
apiClass.getDeclaredMethod("retrieveBlockMeta", economy = tryHookEconomy(null, new VaultEconomy());
Plugin.class, Location.class, Plugin.class, String.class, Consumer.class); }
info("Hooked BlockStore"); if (mainConfig.isItemEconomyEnabled()) {
economy = tryHookEconomy(economy, new ItemEconomy());
blockStoreAvailable = true; }
} catch (ClassNotFoundException | NoSuchMethodException e) { if (mainConfig.isPlayerPointsEconomyEnabled()) {
severe("Unable to hook BlockStore, the version of BlockStore you are " + economy = tryHookEconomy(economy, new PlayerPointsEconomy());
"using may be outdated. Heads requires BlockStore v1.5.0."); }
severe("Please update BlockStore and report this to Sothatsit if the problem persists.");
} if (economy == null || economy instanceof NoEconomy) {
} severe("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());
@EventHandler(priority = EventPriority.HIGHEST) }
public void onInventoryClick(InventoryClickEvent e) {
Inventory inventory = e.getInventory(); return economy;
}
if(inventory == null)
return; private Economy tryHookEconomy(Economy currentlyHooked, Economy toHook) {
if (currentlyHooked != null) {
InventoryHolder holder = inventory.getHolder(); warning(toHook.getName() + " economy is not the only economy enabled in the config.yml.");
if (holder instanceof ClickInventory) { if (!(currentlyHooked instanceof NoEconomy))
((ClickInventory) holder).onClick(e); return currentlyHooked;
} else if (holder instanceof InventoryMenu) { }
((InventoryMenu) holder).onClick(e);
} if (!toHook.tryHook()) {
} severe(toHook.getName() + " enabled in config.yml, yet Heads was unable to hook into it.");
return new NoEconomy();
public boolean isExemptFromCost(Player player) { }
if(!mainConfig.isEconomyEnabled() || player.hasPermission("heads.bypasscost") )
return true; info("Loaded " + toHook.getName() + " economy");
return toHook;
return mainConfig.isFreeInCreative() && player.getGameMode() == GameMode.CREATIVE; }
}
private void tryHookBlockStore() {
public boolean chargeForHead(Player player, CacheHead head) { if (mainConfig.shouldUseBlockStore() && Bukkit.getPluginManager().getPlugin("BlockStore") != null) {
if(isExemptFromCost(player)) blockStoreAvailable = false;
return true;
try {
double cost = head.getCost(); Class<?> apiClass = Class.forName("net.sothatsit.blockstore.BlockStoreApi");
if(cost <= 0) apiClass.getDeclaredMethod("retrieveBlockMeta", Plugin.class, Location.class, Plugin.class, String.class, Consumer.class);
return true;
info("Hooked BlockStore");
if(!economy.hasBalance(player, cost)) {
Lang.Menu.Get.notEnoughMoney(head.getName(), head.getCost()).send(player); blockStoreAvailable = true;
return false;
} } catch (ClassNotFoundException | NoSuchMethodException e) {
severe("Unable to hook BlockStore, the version of BlockStore you are " + "using may be outdated. Heads requires BlockStore v1.5.0.");
if(!economy.takeBalance(player, cost)) { severe("Please update BlockStore and report this to Sothatsit if the problem persists.");
Lang.Menu.Get.transactionError(head.getName(), head.getCost()).send(player); }
return false; }
} }
Lang.Menu.Get.purchased(head.getName(), head.getCost()).send(player); @EventHandler(priority = EventPriority.HIGHEST)
return true; public void onInventoryClick(InventoryClickEvent e) {
} Inventory inventory = e.getInventory();
public static String getCategoryPermission(String category) { if (inventory == null)
return "heads.category." + category.toLowerCase().replace(' ', '_'); return;
}
InventoryHolder holder = inventory.getHolder();
public static Heads getInstance() {
return instance; if (holder instanceof ClickInventory) {
} ((ClickInventory) holder).onClick(e);
} else if (holder instanceof InventoryMenu) {
public static LegacyIDs getLegacyIDs() { ((InventoryMenu) holder).onClick(e);
return instance.legacyIDs; }
} }
public static MainConfig getMainConfig() { public boolean isExemptFromCost(Player player) {
return instance.mainConfig; if (!mainConfig.isEconomyEnabled() || player.hasPermission("heads.bypasscost"))
} return true;
public static CacheFile getCache() { return mainConfig.isFreeInCreative() && player.getGameMode() == GameMode.CREATIVE;
return instance.cache; }
}
public boolean chargeForHead(Player player, CacheHead head) {
public static Menus getMenus() { if (isExemptFromCost(player))
return instance.menus; return true;
}
double cost = head.getCost();
public static MenuConfig getMenuConfig() {
return instance.oldMenuConfig; if (cost <= 0)
} return true;
public static LangConfig getLangConfig() { if (!economy.hasBalance(player, cost)) {
return instance.langConfig; Lang.Menu.Get.notEnoughMoney(head.getName(), head.getCost()).send(player);
} return false;
}
public static Economy getEconomy() {
return instance.economy; if (!economy.takeBalance(player, cost)) {
} Lang.Menu.Get.transactionError(head.getName(), head.getCost()).send(player);
return false;
public static boolean isBlockStoreAvailable() { }
return instance.blockStoreAvailable;
} Lang.Menu.Get.purchased(head.getName(), head.getCost()).send(player);
return true;
public static void info(String info) { }
instance.getLogger().info(info);
} public static String getCategoryPermission(String category) {
return "heads.category." + category.toLowerCase().replace(' ', '_');
public static void warning(String warning) { }
instance.getLogger().warning(warning);
} public static Heads getInstance() {
return instance;
public static void severe(String severe) { }
instance.getLogger().severe(severe);
} public static LegacyIDs getLegacyIDs() {
return instance.legacyIDs;
public static void sync(Runnable task) { }
Bukkit.getScheduler().runTask(instance, task);
} public static MainConfig getMainConfig() {
return instance.mainConfig;
public static void async(Runnable task) { }
Bukkit.getScheduler().runTaskAsynchronously(instance, task);
} public static CacheFile getCache() {
return instance.cache;
public static FileConfigFile getVersionedConfig(String resource) { }
if(Version.isBelow(Version.v1_13))
return new FileConfigFile(resource, "pre1_13/" + resource); public static Menus getMenus() {
return instance.menus;
return new FileConfigFile(resource); }
}
public static MenuConfig getMenuConfig() {
return instance.oldMenuConfig;
}
public static LangConfig getLangConfig() {
return instance.langConfig;
}
public static Economy getEconomy() {
return instance.economy;
}
public static boolean isBlockStoreAvailable() {
return instance.blockStoreAvailable;
}
public static void info(String info) {
instance.getLogger().info(info);
}
public static void warning(String warning) {
instance.getLogger().warning(warning);
}
public static void severe(String severe) {
instance.getLogger().severe(severe);
}
public static void sync(Runnable task) {
Bukkit.getScheduler().runTask(instance, task);
}
public static void async(Runnable task) {
Bukkit.getScheduler().runTaskAsynchronously(instance, task);
}
public static FileConfigFile getVersionedConfig(String resource) {
if (Version.isBelow(Version.v1_13))
return new FileConfigFile(resource, "pre1_13/" + resource);
return new FileConfigFile(resource);
}
} }

View File

@ -3,24 +3,42 @@ package net.sothatsit.heads;
import java.util.List; import java.util.List;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.scheduler.BukkitRunnable;
public class LiveHead { public class LiveHead {
private int frames; private int frames;
private List<Heads> fases; private List<Heads> texures;
private Location location; private Location location;
public LiveHead(int frames, List<Heads> fases, Location location /*.more.*/) { // Do not pay attention to this class, this is just a sort of sketch which is not ready.
public LiveHead(int frames, List<Heads> texures, Location location /*.more.*/) {
// Safety first, experimental features should not crash servers. // Safety first, experimental features should not crash servers.
if (frames > 60) if (frames > 60)
frames = 60; frames = 60;
this.frames = frames; this.frames = frames;
this.fases = fases; if (texures.size() > frames)
while (texures.size() != frames) {
texures.remove(0);
}
this.texures = texures;
this.location = location; this.location = location;
} }
public void renderTexure() { public void renderTexures() {
int interval = frames / 20; 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(Heads.getInstance(), 0, interval);
// Render (but I am too tired for now). // Render (but I am too tired for now).
// TODO: External classes from the animation packages. // TODO: External classes from the animation packages.
} }

View File

@ -93,6 +93,7 @@ public class GetCommand extends AbstractCommand {
Lang.Command.Get.adding(name).send(player); Lang.Command.Get.adding(name).send(player);
player.getInventory().addItem(head.getItemStack()); player.getInventory().addItem(head.getItemStack());
player.updateInventory();
} }
} }
} }

View File

@ -1,43 +1,43 @@
package net.sothatsit.heads.command.user; package net.sothatsit.heads.command.user;
import net.sothatsit.heads.command.AbstractCommand;
import net.sothatsit.heads.config.MainConfig;
import net.sothatsit.heads.config.lang.Lang;
import net.sothatsit.heads.oldmenu.mode.InvModeType;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import net.sothatsit.heads.command.AbstractCommand;
import net.sothatsit.heads.config.MainConfig;
import net.sothatsit.heads.config.lang.Lang;
import net.sothatsit.heads.oldmenu.mode.InvModeType;
public class OpenMenuCommand extends AbstractCommand { public class OpenMenuCommand extends AbstractCommand {
@Override @Override
public String getCommandLabel(MainConfig config) { public String getCommandLabel(MainConfig config) {
return null; return null;
} }
@Override @Override
public String getPermission() { public String getPermission() {
return "heads.menu"; return "heads.menu";
} }
@Override @Override
public Lang.HelpSection getHelp() { public Lang.HelpSection getHelp() {
return Lang.Command.OpenMenu.help(); return Lang.Command.OpenMenu.help();
} }
@Override @Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
Lang.Command.Errors.mustBePlayer().send(sender); Lang.Command.Errors.mustBePlayer().send(sender);
return true; return true;
} }
InvModeType.GET.open((Player) sender);
// CacheHeadsMenu.openHeadsMenu((Player) sender); InvModeType.GET.open((Player) sender);
// CacheHeadsMenu.openHeadsMenu((Player) sender);
return true;
}
return true;
}
} }

View File

@ -1,201 +1,193 @@
package net.sothatsit.heads.menu; package net.sothatsit.heads.menu;
import net.sothatsit.heads.menu.ui.element.Element;
import net.sothatsit.heads.Heads;
import net.sothatsit.heads.cache.CacheFile;
import net.sothatsit.heads.cache.CacheHead;
import net.sothatsit.heads.menu.ui.*;
import net.sothatsit.heads.menu.ui.item.Button;
import net.sothatsit.heads.util.Checks;
import net.sothatsit.heads.menu.ui.item.Item;
import net.sothatsit.heads.util.Stringify;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import net.sothatsit.heads.Heads;
import net.sothatsit.heads.cache.CacheFile;
import net.sothatsit.heads.cache.CacheHead;
import net.sothatsit.heads.menu.ui.Bounds;
import net.sothatsit.heads.menu.ui.InventoryMenu;
import net.sothatsit.heads.menu.ui.MenuResponse;
import net.sothatsit.heads.menu.ui.element.Element;
import net.sothatsit.heads.menu.ui.item.Button;
import net.sothatsit.heads.menu.ui.item.Item;
import net.sothatsit.heads.util.Checks;
import net.sothatsit.heads.util.Stringify;
public class CacheHeadsMenu extends Element { public class CacheHeadsMenu extends Element {
public static final Item defaultClose = Item.create(Material.REDSTONE_BLOCK).name("&cClose Menu"); 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 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 Item defaultSearch = Item.create(Material.COMPASS).name("&7Search Heads");
public static final String defaultCategoriesTitle = "Categories"; public static final String defaultCategoriesTitle = "Categories";
public static final String defaultCategoryTitle = "%category%"; public static final String defaultCategoryTitle = "%category%";
public static final Template defaultTemplate = new Template( public static final Template defaultTemplate = new Template(CategoriesMenu.defaultTemplate, HeadsMenu.defaultTemplate, defaultClose, defaultBack, defaultSearch, defaultCategoriesTitle, defaultCategoryTitle);
CategoriesMenu.defaultTemplate, HeadsMenu.defaultTemplate,
defaultClose, defaultBack, defaultSearch,
defaultCategoriesTitle, defaultCategoryTitle
);
private Template template; private Template template;
private final CacheFile cache; private final CacheFile cache;
private final InventoryMenu inventoryMenu; private final InventoryMenu inventoryMenu;
private final CategoriesMenu categoriesMenu; private final CategoriesMenu categoriesMenu;
private final HeadsMenu headsMenu; private final HeadsMenu headsMenu;
private String selectedCategory = null; private String selectedCategory = null;
public CacheHeadsMenu(CacheFile cache, InventoryMenu inventoryMenu, Bounds bounds, public CacheHeadsMenu(CacheFile cache, InventoryMenu inventoryMenu, Bounds bounds, Function<CacheHead, MenuResponse> onSelect) {
Function<CacheHead, MenuResponse> onSelect) { super(bounds);
super(bounds);
Checks.ensureNonNull(cache, "cache"); Checks.ensureNonNull(cache, "cache");
Checks.ensureNonNull(inventoryMenu, "inventoryMenu"); Checks.ensureNonNull(inventoryMenu, "inventoryMenu");
Checks.ensureNonNull(onSelect, "onSelect"); Checks.ensureNonNull(onSelect, "onSelect");
Checks.ensureTrue(bounds.height >= 3, "bounds must have a height of at least 3"); Checks.ensureTrue(bounds.height >= 3, "bounds must have a height of at least 3");
this.cache = cache; this.cache = cache;
this.inventoryMenu = inventoryMenu; this.inventoryMenu = inventoryMenu;
this.categoriesMenu = new CategoriesMenu(cache, bounds, this::selectCategory); this.categoriesMenu = new CategoriesMenu(cache, bounds, this::selectCategory);
this.headsMenu = new HeadsMenu(bounds, onSelect); this.headsMenu = new HeadsMenu(bounds, onSelect);
setTemplate(defaultTemplate); setTemplate(defaultTemplate);
} }
public boolean onCategoriesScreen() { public boolean onCategoriesScreen() {
return selectedCategory == null; return selectedCategory == null;
} }
public MenuResponse close() { public MenuResponse close() {
return MenuResponse.CLOSE; return MenuResponse.CLOSE;
} }
public MenuResponse back() { public MenuResponse back() {
this.selectedCategory = null; this.selectedCategory = null;
inventoryMenu.setTitle(template.getCategoriesTitle()); inventoryMenu.setTitle(template.getCategoriesTitle());
return MenuResponse.UPDATE; return MenuResponse.UPDATE;
} }
public MenuResponse search() { public MenuResponse search() {
inventoryMenu.getPlayer().sendMessage("Search"); inventoryMenu.getPlayer().sendMessage("Search");
return MenuResponse.NONE; return MenuResponse.NONE;
} }
public MenuResponse selectCategory(String category) { public MenuResponse selectCategory(String category) {
Checks.ensureNonNull(category, "category"); Checks.ensureNonNull(category, "category");
List<CacheHead> heads = cache.getCategoryHeads(category); List<CacheHead> heads = cache.getCategoryHeads(category);
if(heads.size() == 0) { if (heads.size() == 0) {
return back(); return back();
} }
this.selectedCategory = category; this.selectedCategory = category;
this.headsMenu.setItems(heads); this.headsMenu.setItems(heads);
inventoryMenu.setTitle(template.getCategoryTitle(category)); inventoryMenu.setTitle(template.getCategoryTitle(category));
return MenuResponse.UPDATE; return MenuResponse.UPDATE;
} }
@Override @Override
public Button[] getItems() { public Button[] getItems() {
if(onCategoriesScreen()) { if (onCategoriesScreen()) {
return categoriesMenu.getItems(); return categoriesMenu.getItems();
} else { } else {
return headsMenu.getItems(); return headsMenu.getItems();
} }
} }
public void setTemplate(Template template) { public void setTemplate(Template template) {
Checks.ensureNonNull(template, "template"); Checks.ensureNonNull(template, "template");
this.template = template; this.template = template;
this.template.init(this); this.template.init(this);
if(onCategoriesScreen()) { if (onCategoriesScreen()) {
inventoryMenu.setTitle(template.getCategoriesTitle()); inventoryMenu.setTitle(template.getCategoriesTitle());
} else { } else {
inventoryMenu.setTitle(template.getCategoryTitle(selectedCategory)); inventoryMenu.setTitle(template.getCategoryTitle(selectedCategory));
} }
} }
@Override @Override
public String toString() { public String toString() {
return Stringify.builder() return Stringify.builder().entry("template", template).entry("cache", cache).entry("headsMenu", headsMenu).entry("categoriesMenu", categoriesMenu).toString();
.entry("template", template) }
.entry("cache", cache)
.entry("headsMenu", headsMenu)
.entry("categoriesMenu", categoriesMenu).toString();
}
public static final class Template { public static final class Template {
private final CategoriesMenu.Template categoriesTemplate; private final CategoriesMenu.Template categoriesTemplate;
private final HeadsMenu.Template headsTemplate; private final HeadsMenu.Template headsTemplate;
private final Item close; private final Item close;
private final Item back; private final Item back;
private final Item search; private final Item search;
private final String categoriesTitle; private final String categoriesTitle;
private final String categoryTitle; private final String categoryTitle;
public Template(CategoriesMenu.Template categoriesTemplate, HeadsMenu.Template headsTemplate, public Template(CategoriesMenu.Template categoriesTemplate, HeadsMenu.Template headsTemplate, Item close, Item back, Item search, String categoriesTitle, String categoryTitle) {
Item close, Item back, Item search, String categoriesTitle, String categoryTitle) {
Checks.ensureNonNull(categoriesTemplate, "categoriesTemplate"); Checks.ensureNonNull(categoriesTemplate, "categoriesTemplate");
Checks.ensureNonNull(headsTemplate, "headsTemplate"); Checks.ensureNonNull(headsTemplate, "headsTemplate");
Checks.ensureNonNull(close, "close"); Checks.ensureNonNull(close, "close");
Checks.ensureNonNull(back, "back"); Checks.ensureNonNull(back, "back");
Checks.ensureNonNull(search, "search"); Checks.ensureNonNull(search, "search");
Checks.ensureNonNull(categoriesTemplate, "categoriesTemplate"); Checks.ensureNonNull(categoriesTemplate, "categoriesTemplate");
Checks.ensureNonNull(categoryTitle, "categoryTitle"); Checks.ensureNonNull(categoryTitle, "categoryTitle");
this.categoriesTemplate = categoriesTemplate; this.categoriesTemplate = categoriesTemplate;
this.headsTemplate = headsTemplate; this.headsTemplate = headsTemplate;
this.close = close; this.close = close;
this.back = back; this.back = back;
this.search = search; this.search = search;
this.categoriesTitle = ChatColor.translateAlternateColorCodes('&', categoriesTitle); this.categoriesTitle = ChatColor.translateAlternateColorCodes('&', categoriesTitle);
this.categoryTitle = ChatColor.translateAlternateColorCodes('&', categoryTitle); this.categoryTitle = ChatColor.translateAlternateColorCodes('&', categoryTitle);
} }
public String getCategoriesTitle() { public String getCategoriesTitle() {
return categoriesTitle; return categoriesTitle;
} }
public String getCategoryTitle(String category) { public String getCategoryTitle(String category) {
return categoryTitle.replace("%category%", category); return categoryTitle.replace("%category%", category);
} }
private void init(CacheHeadsMenu menu) { private void init(CacheHeadsMenu menu) {
Button close = this.close.buildButton(menu::close); Button close = this.close.buildButton(menu::close);
Button back = this.back.buildButton(menu::back); Button back = this.back.buildButton(menu::back);
Button search = this.search.buildButton(menu::search); Button search = this.search.buildButton(menu::search);
menu.categoriesMenu.setTemplate(categoriesTemplate, close, search); menu.categoriesMenu.setTemplate(categoriesTemplate, close, search);
menu.headsMenu.setTemplate(headsTemplate, back, search); menu.headsMenu.setTemplate(headsTemplate, back, search);
} }
@Override @Override
public String toString() { public String toString() {
return Stringify.builder() return Stringify.builder().entry("categoriesTemplate", categoriesTemplate).entry("headsTemplate", headsTemplate).toString();
.entry("categoriesTemplate", categoriesTemplate) }
.entry("headsTemplate", headsTemplate).toString();
}
} }
public static void openHeadsMenu(Player player) { @Deprecated
InventoryMenu inventory = new InventoryMenu(player, "Heads", 6); public static void openHeadsMenu(Player player) {
InventoryMenu inventory = new InventoryMenu(player, "Heads", 6);
CacheHeadsMenu menu = new CacheHeadsMenu(Heads.getCache(), inventory, inventory.bounds, head -> { CacheHeadsMenu menu = new CacheHeadsMenu(Heads.getCache(), inventory, inventory.bounds, head -> {
player.sendMessage(head.getName()); player.sendMessage(head.getName());
return MenuResponse.NONE; return MenuResponse.NONE;
}); });
menu.setTemplate(Heads.getMenus().getBrowseTemplate()); menu.setTemplate(Heads.getMenus().getBrowseTemplate());
inventory.addElement(menu); inventory.addElement(menu);
inventory.open(); inventory.open();
} }
} }

View File

@ -0,0 +1,21 @@
package net.sothatsit.heads.patches;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import net.sothatsit.heads.volatilecode.reflection.Version;
public class HeadPlace implements Listener {
// TODO: Patch the issue reported by BlackGamer000 on 1.8.
// register event
@EventHandler
public void onHeadPlace(BlockPlaceEvent event) {
if (Version.isBelow(Version.v1_8)) {
// Need to find a fix for the texures on 1.8
}
}
}

View File

@ -1,7 +1,7 @@
main: net.sothatsit.heads.Heads main: net.sothatsit.heads.Heads
author: Marido author: Marido
name: Heads name: Heads
version: 2.0.3 version: 2.0.4
api-version: 1.13 api-version: 1.13
softdepend: [Vault, PlayerPoints, BlockStore] softdepend: [Vault, PlayerPoints, BlockStore]
loadbefore: [DeluxeMenus] loadbefore: [DeluxeMenus]