commit 1791f3428c2af67b043810ac9c68d635c4b062b4 Author: FreestyleCrafter Date: Sat May 23 12:12:33 2015 +0200 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..c102544 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# AIOJetpacks +Source code of AIOJetpacks + +Complete source code of FreestyleCrafter AIO Jetpacks plugin. diff --git a/src/de/freestylecrafter/aio/jetpacks/AIOPlugin.java b/src/de/freestylecrafter/aio/jetpacks/AIOPlugin.java new file mode 100644 index 0000000..789596f --- /dev/null +++ b/src/de/freestylecrafter/aio/jetpacks/AIOPlugin.java @@ -0,0 +1,435 @@ +package de.freestylecrafter.aio.jetpacks; + +import java.io.IOException; + +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerGameModeChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.PlayerToggleFlightEvent; +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +public class AIOPlugin extends JavaPlugin implements Listener { + + private static AIOPlugin instance; + + private ConfigurationManager configManager; + private JetpackManager jetpackManager; + + private CmdExecutor cmdExecutor; + + @Override + public void onEnable() + { + AIOPlugin.instance = this; + + try + { + this.configManager = new ConfigurationManager(); + } catch (IOException e) + { + this.getLogger().warning(e.toString()); + return; + } + + this.jetpackManager = new JetpackManager(this.getConfigManager().getConfiguration()); + + this.getServer().getPluginManager().registerEvents(this, this); + + this.cmdExecutor = new CmdExecutor(); + + this.getCommand("jetpacks").setExecutor(this.cmdExecutor); + this.getCommand("jetpacks").setTabCompleter(this.cmdExecutor); + + // Run this after 20 ticks because some plugins are updating variables + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + if (!AIOPlugin.getInstance().getServer().getOnlinePlayers().isEmpty()) + { + for (Player p : AIOPlugin.getInstance().getServer().getOnlinePlayers()) + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer(p); + } + } + } + }, 20); + } + + @Override + public void onDisable() + { + if (!this.getServer().getOnlinePlayers().isEmpty() && this.getJetpackManager() != null) + { + for (Player p : this.getServer().getOnlinePlayers()) + { + this.getJetpackManager().removeJetpackItemForPlayer(p); + } + } + + this.getJetpackManager().unregisterOldRecipes(); + } + + public ConfigurationManager getConfigManager() + { + return this.configManager; + } + + public static AIOPlugin getInstance() + { + return AIOPlugin.instance; + } + + public JetpackManager getJetpackManager() + { + return this.jetpackManager; + } + + @EventHandler + public void onPlayerJoin(final PlayerJoinEvent e) + { + // Run this after 20 ticks because some plugins are updating variables + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer(e.getPlayer()); + } + }, 20); + } + + @EventHandler + public void onPlayerQuit(final PlayerQuitEvent e) + { + this.getJetpackManager().removeJetpackItemForPlayer(e.getPlayer()); + } + + @EventHandler + public void onPlayerChangeGameMode(final PlayerGameModeChangeEvent e) + { + // Run this next Tick because bukkit and some plugins are changing variables after calling that event + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer(e.getPlayer()); + } + }); + } + + @EventHandler + public void onPlayerDeath(final PlayerDeathEvent e) + { + // Run this next Tick because bukkit and some plugins are changing variables after calling that event + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer(e.getEntity()); + } + }); + } + + @EventHandler + public void onPlayerRespawn(final PlayerRespawnEvent e) + { + // Run this after 20 ticks because some plugins are updating variables + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer(e.getPlayer()); + } + }, 20); + } + + @EventHandler + public void onPlayerDamage(final EntityDamageEvent e) + { + if (!(e.getEntity() instanceof Player)) + return; + + // Run this next Tick because bukkit and some plugins are changing variables after calling that event + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer((Player) e.getEntity()); + } + }); + } + + @EventHandler + public void onPlayerChangedWorld(final PlayerChangedWorldEvent e) + { + AIOPlugin.getInstance().getJetpackManager().removeJetpackItemForPlayer(e.getPlayer()); + // Run this after 20 ticks because some plugins are updating variables + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer(e.getPlayer()); + } + }, 20); + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onPlayerInventoryClick(final InventoryClickEvent e) + { + if (!(e.getWhoClicked() instanceof Player)) + return; + + JetpackItem currentItem = JetpackItem.getJetpackItem(e.getCurrentItem()); + JetpackItem cursorItem = JetpackItem.getJetpackItem(e.getCursor()); + Player p = (Player) e.getWhoClicked(); + + if ((e.getAction().equals(InventoryAction.PLACE_ALL) || e.getAction().equals(InventoryAction.PLACE_ONE) || e.getAction().equals(InventoryAction.PLACE_SOME)) && (cursorItem != null && currentItem != null) && !(e.getSlotType().equals(SlotType.ARMOR) && e.getRawSlot() == 6)) + { + if (cursorItem.getItem().equals(currentItem.getItem())) + { + e.setCancelled(true); + } + } + + if ((e.getClick().equals(ClickType.LEFT) || e.getClick().equals(ClickType.RIGHT)) && cursorItem != null && (e.getSlotType().equals(SlotType.ARMOR) && e.getRawSlot() == 6)) + { + if (PermissionsHelper.canUseJetpack(cursorItem, p)) + { + this.getJetpackManager().removeJetpackItemForPlayer(p); + + ItemStack currentItemCopy = e.getCurrentItem().clone(); + ItemStack cursorItemCopy = e.getCursor().clone(); + + e.setCursor(currentItemCopy); + e.setCurrentItem(cursorItemCopy); + } + else + { + p.sendMessage(PermissionsHelper.MESSAGE_NOT_ALLOWED_USE); + } + e.setCancelled(true); + } + + if (e.getView().getType().equals(InventoryType.CRAFTING)) + { + if ((e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT)) && currentItem != null && !(e.getSlotType().equals(SlotType.ARMOR) || e.getRawSlot() == 6)) + { + if (PermissionsHelper.canUseJetpack(currentItem, p)) + { + this.getJetpackManager().removeJetpackItemForPlayer(p); + + ItemStack currentItemCopy = (e.getCurrentItem() != null ? e.getCurrentItem().clone() : null); + ItemStack chestplateItemCopy = (((Player) e.getWhoClicked()).getInventory().getChestplate() != null ? ((Player) e.getWhoClicked()).getInventory().getChestplate().clone() : null); + + e.setCurrentItem(chestplateItemCopy); + p.getInventory().setChestplate(currentItemCopy); + } + else + { + p.sendMessage(PermissionsHelper.MESSAGE_NOT_ALLOWED_USE); + } + e.setCancelled(true); + } + } + + if (e.getClick().equals(ClickType.NUMBER_KEY) && (e.getSlotType().equals(SlotType.ARMOR) && e.getRawSlot() == 6)) + { + JetpackItem hotbarItem = JetpackItem.getJetpackItem(e.getView().getBottomInventory().getItem(e.getHotbarButton())); + if (hotbarItem != null) + { + if (PermissionsHelper.canUseJetpack(hotbarItem, p)) + { + this.getJetpackManager().removeJetpackItemForPlayer(p); + + ItemStack currentItemCopy = e.getCurrentItem().clone(); + ItemStack hotbarItemCopy = e.getView().getBottomInventory().getItem(e.getHotbarButton()); + + e.getView().getBottomInventory().setItem(e.getHotbarButton(), currentItemCopy); + e.setCurrentItem(hotbarItemCopy); + } + else + { + p.sendMessage(PermissionsHelper.MESSAGE_NOT_ALLOWED_USE); + } + e.setCancelled(true); + } + } + + if ((e.getSlotType().equals(SlotType.ARMOR) && e.getRawSlot() == 6 && (!e.getClick().equals(ClickType.MIDDLE))) || currentItem != null) + { + // Run this next Tick because bukkit and some plugins are changing variables after calling that event + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer((Player) e.getWhoClicked()); + } + }); + } + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onPlayerCraftItem(CraftItemEvent e) + { + if (!(e.getWhoClicked() instanceof Player) || !(e.getView().getTopInventory() instanceof CraftingInventory)) + return; + + if (!e.getView().getType().equals(InventoryType.CRAFTING) && !e.getView().getType().equals(InventoryType.WORKBENCH)) + return; + + JetpackItem currentItem = JetpackItem.getJetpackItem(e.getCurrentItem()); + JetpackItem cursorItem = JetpackItem.getJetpackItem(e.getCursor()); + + if (currentItem != null && !PermissionsHelper.canCraftJetpack(currentItem, (Player) e.getWhoClicked())) + { + ((Player) e.getWhoClicked()).sendMessage(PermissionsHelper.MESSAGE_NOT_ALLOWED_CRAFT); + e.setCancelled(true); + return; + } + + if ((currentItem != null && cursorItem != null) || (currentItem != null && e.isShiftClick())) + { + e.setCancelled(true); + return; + } + + if (currentItem != null && (e.getCursor() == null || e.getCursor().getType().equals(Material.AIR))) + { + JetpackItem currentItemCopy = JetpackItem.getJetpackItem(e.getCurrentItem().clone()); + if (currentItemCopy != null) + { + currentItemCopy.setCraftTimestamp(); + e.setCursor(currentItemCopy.getItem()); + CraftingInventory inv = (CraftingInventory) e.getView().getTopInventory(); + + int maxSlot = (e.getView().getType().equals(InventoryType.CRAFTING) ? 4 : 9); + for (int i = 1; i <= maxSlot; i++) + { + ItemStack is = inv.getItem(i); + if (is != null && !is.getType().equals(Material.AIR)) + { + if (is.getAmount() - 1 <= 0) + inv.remove(is); + else + is.setAmount(is.getAmount() - 1); + } + } + ((Player) e.getWhoClicked()).updateInventory(); + } + } + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onPlayerInteract(PlayerInteractEvent e) + { + final Player p = e.getPlayer(); + if (e.getAction().equals(Action.RIGHT_CLICK_AIR) || e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) + { + JetpackItem inHand = JetpackItem.getJetpackItem(p.getItemInHand()); + if (inHand != null) + { + if (!p.getGameMode().equals(GameMode.CREATIVE)) + { + if (PermissionsHelper.canUseJetpack(inHand, p)) + { + this.getJetpackManager().removeJetpackItemForPlayer(p); + + ItemStack oldChestplate = (p.getInventory().getChestplate() == null ? null : p.getInventory().getChestplate().clone()); + p.getInventory().setChestplate(p.getItemInHand()); + p.setItemInHand(oldChestplate); + + p.updateInventory(); + + // Run this next Tick because bukkit and some plugins are changing variables after calling that event + this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer(p); + } + }); + } + else + { + p.sendMessage(PermissionsHelper.MESSAGE_NOT_ALLOWED_USE); + } + } + e.setCancelled(true); + } + } + } + + @EventHandler + public void onPlayerToggleFlight(PlayerToggleFlightEvent e) + { + this.getJetpackManager().checkJetpackItemForPlayer(e.getPlayer()); + JetpackItem item = this.getJetpackManager().getJetpackItemForPlayer(e.getPlayer()); + if (item != null) + { + if (item.isEnabled()) + { + item.setEnabled(false); + } + else + { + item.setEnabled(true); + } + e.setCancelled(true); + } + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent e) + { + Player p = e.getPlayer(); + + this.getJetpackManager().checkJetpackItemForPlayer(p); + JetpackItem item = this.getJetpackManager().getJetpackItemForPlayer(e.getPlayer()); + if (item != null && item.isEnabled()) + { + if (!item.getProfile().isInfiniteFuel()) + { + if (item.getFuel() <= 0) + { + item.reFuel(p.getInventory()); + if (item.getFuel() <= 0) + { + item.setEnabled(false); + return; + } + } + item.useFuel(1); + } + + if (p.isSprinting()) + p.setVelocity(p.getLocation().getDirection().multiply(item.getProfile().getFastSpeed())); + else if (p.isSneaking()) + p.setVelocity(p.getLocation().getDirection().multiply(item.getProfile().getSlowSpeed())); + else + p.setVelocity(p.getLocation().getDirection().multiply(item.getProfile().getNormalSpeed())); + } + } +} diff --git a/src/de/freestylecrafter/aio/jetpacks/CmdExecutor.java b/src/de/freestylecrafter/aio/jetpacks/CmdExecutor.java new file mode 100644 index 0000000..4551c38 --- /dev/null +++ b/src/de/freestylecrafter/aio/jetpacks/CmdExecutor.java @@ -0,0 +1,297 @@ +package de.freestylecrafter.aio.jetpacks; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +public class CmdExecutor implements CommandExecutor, TabCompleter +{ + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) + { + if (cmd.getName().equalsIgnoreCase("jetpacks")) + { + if (sender instanceof Player) + { + if (!PermissionsHelper.canCommandBase((Player) sender)) + { + sender.sendMessage(ChatColor.RED + "You don't have permission to use this command!"); + return true; + } + } + + if (args.length >= 1 && args[0].equalsIgnoreCase("cheat")) + { + if (sender instanceof Player) + { + if (!PermissionsHelper.canCommandCheat((Player) sender)) + { + sender.sendMessage(ChatColor.RED + "You don't have permission to cheat jetpacks by command!"); + return true; + } + } + + if (args.length == 2) + { + if (sender instanceof Player) + { + Player p = (Player) sender; + this.executeCheat(sender, p, p, args[1]); + } + else + { + sender.sendMessage("You are not a player, but you can cheat someone else a jetpack!"); + sender.sendMessage("Usage: /jetpacks cheat "); + return true; + } + } + else if (args.length == 3) + { + Player from = (sender instanceof Player ? (Player) sender : null); + @SuppressWarnings("deprecation") + Player to = AIOPlugin.getInstance().getServer().getPlayer(args[2]); + + this.executeCheat(sender, from, to, args[1]); + } + else + { + sender.sendMessage("Usage: /jetpacks cheat []"); + } + } + else if (args.length >= 1 && args[0].equalsIgnoreCase("reload")) + { + if (sender instanceof Player) + { + if (!PermissionsHelper.canCommandReload((Player) sender)) + { + sender.sendMessage(ChatColor.RED + "You don't have permission to reload the config!"); + return true; + } + } + + try + { + AIOPlugin.getInstance().getConfigManager().reloadConfig(); + if (!AIOPlugin.getInstance().getServer().getOnlinePlayers().isEmpty() && AIOPlugin.getInstance().getJetpackManager() != null) + { + for (Player p : AIOPlugin.getInstance().getServer().getOnlinePlayers()) + { + AIOPlugin.getInstance().getJetpackManager().removeJetpackItemForPlayer(p); + } + } + AIOPlugin.getInstance().getJetpackManager().reloadProfiles(AIOPlugin.getInstance().getConfigManager().getConfiguration()); + if (!AIOPlugin.getInstance().getServer().getOnlinePlayers().isEmpty()) + { + for (Player p : AIOPlugin.getInstance().getServer().getOnlinePlayers()) + { + AIOPlugin.getInstance().getJetpackManager().checkJetpackItemForPlayer(p); + } + } + sender.sendMessage(ChatColor.GREEN + "Reloaded AIO-Jetpacks successfully!"); + return true; + } catch (IOException e) + { + AIOPlugin.getInstance().getLogger().warning(e.toString()); + sender.sendMessage(ChatColor.RED + "Reloading failed. Please check console."); + return true; + } + } + else + { + if (args.length >= 1) + sender.sendMessage(ChatColor.RED + "Invalid command."); + + sender.sendMessage(ChatColor.GREEN + "== AIO Jetpacks help =="); + + boolean canCommandCheat = (sender instanceof Player ? PermissionsHelper.canCommandCheat((Player) sender) : true); + boolean canCommandReload = (sender instanceof Player ? PermissionsHelper.canCommandReload((Player) sender) : true); + if (!canCommandCheat && !canCommandReload) + { + sender.sendMessage("There is no help available, because you are not allowed to use any commands."); + } + else + { + if (canCommandCheat) + sender.sendMessage("/jetpacks cheat [] Allows you to manually cheat jetpacks"); + + if (canCommandReload) + sender.sendMessage("/jetpacks reload Reload the plugin and it's configuration"); + } + return true; + } + return true; + } + + return false; + } + + private void executeCheat(CommandSender sender, Player from, Player to, String profArg) + { + if (sender == null || (to == null && from == null)) + return; + + if (to != null && to.isOnline()) + { + Jetpack profile = AIOPlugin.getInstance().getJetpackManager().getProfileByName(profArg); + if (profile != null) + { + if (!(sender instanceof Player) || from == null || PermissionsHelper.canCheatJetpack(profile, from)) + { + if (to.getInventory().firstEmpty() != -1) + { + JetpackItem i = JetpackItem.getNewJetpackItem(profile); + if (i != null) + { + i.setCraftTimestamp(); + to.getInventory().addItem(i.getItem()); + sender.sendMessage("Gave player " + to.getName() + " a jetpack by name #" + profile.getName()); + return; + } + } + else + { + sender.sendMessage(to.getName() + " doesn't have enough space in his inventory to cheat him a jetpack by name #" + profile.getName()); + return; + } + } + else + { + sender.sendMessage("You don't have permission to cheat someone a jetpack by name #" + profile.getName()); + return; + } + } + else + { + sender.sendMessage("Couldn't find jetpack by name #" + profArg); + return; + } + } + else + { + sender.sendMessage("The player " + to.getName() + " is not online!"); + return; + } + } + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String commandLabel, String[] args) + { + if (cmd.getName().equals("jetpacks")) + { + if (args.length >= 1 && args[0].equalsIgnoreCase("cheat")) + { + if (sender instanceof Player) + { + if (!PermissionsHelper.canCommandCheat((Player) sender)) + { + return null; + } + } + + if (args.length == 2) + { + List list = new ArrayList(); + boolean needCheckInput = !(args[1].isEmpty()); + for (Jetpack j : AIOPlugin.getInstance().getJetpackManager().getProfiles()) + { + if (sender instanceof Player) + if (!PermissionsHelper.canCheatJetpack(j, (Player) sender)) + continue; + + if (!args[1].isEmpty() && j.getName().startsWith(args[1])) + { + list.clear(); + list.add(j.getName()); + needCheckInput = false; + break; + } + + list.add(j.getName()); + } + + if (needCheckInput) + list.clear(); + + return list; + } + else if (args.length == 3) + { + List list = new ArrayList(); + boolean needCheckInput = !(args[2].isEmpty()); + for (Player p : AIOPlugin.getInstance().getServer().getOnlinePlayers()) + { + if (!args[2].isEmpty() && p.getName().startsWith(args[1].toLowerCase())) + { + list.clear(); + list.add(p.getName()); + needCheckInput = false; + break; + } + + list.add(p.getName()); + } + + if (needCheckInput) + list.clear(); + + return list; + } + + return null; + } + else if (args.length >= 1 && args[0].equalsIgnoreCase("reload")) + { + return new ArrayList(); + } + else if (args.length >= 1 && !args[0].isEmpty() && "reload".startsWith(args[0].toLowerCase())) + { + List list = new ArrayList(); + + boolean canCommandReload = (sender instanceof Player ? PermissionsHelper.canCommandReload((Player) sender) : true); + + if (canCommandReload) + list.add("reload"); + + return list; + } + else if (args.length >= 1 && !args[0].isEmpty() && "cheat".startsWith(args[0].toLowerCase())) + { + List list = new ArrayList(); + + boolean canCommandCheat = (sender instanceof Player ? PermissionsHelper.canCommandCheat((Player) sender) : true); + + if (canCommandCheat) + list.add("cheat"); + + return list; + } + else if (args.length > 1) + { + return new ArrayList(); + } + else + { + List list = new ArrayList(); + + boolean canCommandCheat = (sender instanceof Player ? PermissionsHelper.canCommandCheat((Player) sender) : true); + boolean canCommandReload = (sender instanceof Player ? PermissionsHelper.canCommandReload((Player) sender) : true); + + if (canCommandCheat) + list.add("cheat"); + + if (canCommandReload) + list.add("reload"); + + return list; + } + } + return null; + } +} diff --git a/src/de/freestylecrafter/aio/jetpacks/ConfigurationManager.java b/src/de/freestylecrafter/aio/jetpacks/ConfigurationManager.java new file mode 100644 index 0000000..2506b5e --- /dev/null +++ b/src/de/freestylecrafter/aio/jetpacks/ConfigurationManager.java @@ -0,0 +1,105 @@ +package de.freestylecrafter.aio.jetpacks; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; + +public class ConfigurationManager +{ + private static final String CONFIG_FILE_NAME = "config.yml"; + private static final String HEADER = "AIO Jetpacks configuration\nuse-permissions: Enable or disable permissions system\nmessage-equip: Message to be shown on equip, %name% -> Jetpacks name\nmessage-unequip: Message to be shown on unequip, %name% -> Jetpacks name\n" + + "jetpacks: You can add your own jetpacks here\n: The jetpacks profile name\ndisplayName: Name the jetpack item should have\n" + + "item: The item that should be used as jetpack\nrecipe: To disable recipe, type []\n" + + " - First recipe row, to leave a field empty, write NULL\n - Second recipe row, to leave a field empty, write NULL\n - Third recipe row, to leave a field empty, write NULL\n" + + "enchantments: Here you can add enchantments to the item, write {} to leave empty.\n : Level\n" + + "infiniteFuel: Set if fuel is infinite\n" + + "fuel: The fuel item to use\nticksPerFuel: How many ticks you can fly with one piece of fuel\n" + + "normalSpeed: Normal speed of the jetpack\nfastSpeed: Speed when pressing sprint key + W\nslowSpeed: Speed when sneaking\n" + + "effects: Here you can add potion effects, write {} to leave empty.\n : Effect strength\n"; + + private File configFile; + private YamlConfiguration config; + + public ConfigurationManager() throws IOException + { + this.configFile = new File(AIOPlugin.getInstance().getDataFolder(), CONFIG_FILE_NAME); + this.reloadConfig(); + } + + public void reloadConfig() throws IOException + { + if (!this.configFile.exists() || !this.configFile.isFile()) + { + this.configFile.getParentFile().mkdirs(); + this.configFile.createNewFile(); + } + + boolean changedConfig = false; + this.config = YamlConfiguration.loadConfiguration(this.configFile); + + if (this.config.options() == null || this.config.options().header() == null || !this.config.options().header().equals(HEADER)) + { + this.config.options().header(HEADER); + + changedConfig = true; + } + if (!this.config.isBoolean("use-permissions")) + { + this.config.set("use-permissions", true); + + changedConfig = true; + } + if (!this.config.isString("message-equip")) + { + this.config.set("message-equip", ChatColor.AQUA + "[Jetpacks] " + ChatColor.GRAY + "%name%" + ChatColor.GREEN + " is now equipped." + ChatColor.YELLOW + " [Double jump to use]"); + + changedConfig = true; + } + if (!this.config.isString("message-unequip")) + { + this.config.set("message-unequip", ChatColor.AQUA + "[Jetpacks] " + ChatColor.GRAY + "%name%" + ChatColor.RED + " is no longer equipped!"); + + changedConfig = true; + } + if (!this.config.isConfigurationSection("jetpacks")) + { + this.config.set("jetpacks.example.displayName", "Example Jetpack"); + this.config.set("jetpacks.example.item", "IRON_CHESTPLATE"); + List l = new ArrayList(); + l.add("NULL REDSTONE NULL"); + l.add("REDSTONE IRON_CHESTPLATE REDSTONE"); + l.add("FEATHER BLAZE_ROD FEATHER"); + this.config.set("jetpacks.example.recipe", l); + this.config.set("jetpacks.example.enchantments.PROTECTION_ENVIRONMENTAL", 5); + this.config.set("jetpacks.example.infiniteFuel", false); + this.config.set("jetpacks.example.fuel", "COAL"); + this.config.set("jetpacks.example.ticksPerFuel", 300); + this.config.set("jetpacks.example.normalSpeed", 1.0); + this.config.set("jetpacks.example.fastSpeed", 1.5); + this.config.set("jetpacks.example.slowSpeed", 0.5); + this.config.set("jetpacks.example.effects.SPEED", 2); + + changedConfig = true; + } + + if (changedConfig) + { + this.saveConfiguration(); + } + } + + public YamlConfiguration getConfiguration() + { + return this.config; + } + + public void saveConfiguration() throws IOException + { + this.config.options().copyHeader(true); + this.config.save(this.configFile); + } +} diff --git a/src/de/freestylecrafter/aio/jetpacks/Jetpack.java b/src/de/freestylecrafter/aio/jetpacks/Jetpack.java new file mode 100644 index 0000000..8417528 --- /dev/null +++ b/src/de/freestylecrafter/aio/jetpacks/Jetpack.java @@ -0,0 +1,365 @@ +package de.freestylecrafter.aio.jetpacks; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ShapedRecipe; +import org.bukkit.potion.PotionEffectType; + +public class Jetpack +{ + private String name; + private String displayName; + private Material item; + private ShapedRecipe recipe; + private HashMap enchantments; + private boolean infiniteFuel; + private Material fuel; + private int ticksPerFuel; + private double normalSpeed; + private double fastSpeed; + private double slowSpeed; + private HashMap potionEffects; + + public Jetpack(ConfigurationSection section) throws IllegalArgumentException + { + if (section != null) + { + if (!section.getName().isEmpty()) + { + boolean needToSaveConfig = false; + + if (!section.isString("displayName")) + { + section.set("displayName", "Unnamed"); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'displayName', setting to default."); + needToSaveConfig = true; + } + if (!section.isString("item")) + { + section.set("item", "IRON_CHESTPLATE"); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'item', setting to default."); + needToSaveConfig = true; + } + if (!section.isList("recipe")) + { + section.set("recipe", new ArrayList()); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'recipe', setting to default."); + needToSaveConfig = true; + } + if (!section.isConfigurationSection("enchantments")) + { + section.createSection("enchantments"); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing section 'enchantments', creating default."); + needToSaveConfig = true; + } + if (!section.isBoolean("infiniteFuel")) + { + section.set("infiniteFuel", false); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'infiniteFuel', setting to default."); + needToSaveConfig = true; + } + if (!section.getBoolean("infiniteFuel")) + { + if (!section.isString("fuel")) + { + section.set("fuel", "COAL"); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'fuel', setting to default."); + needToSaveConfig = true; + } + if (!section.isInt("ticksPerFuel")) + { + section.set("ticksPerFuel", 640); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'ticksPerFuel', setting to default."); + needToSaveConfig = true; + } + } + if (!section.isDouble("normalSpeed")) + { + section.set("normalSpeed", 1.0); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'normalSpeed', setting to default."); + needToSaveConfig = true; + } + if (!section.isDouble("fastSpeed")) + { + section.set("fastSpeed", 1.5); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'fastSpeed', setting to default."); + needToSaveConfig = true; + } + if (!section.isDouble("slowSpeed")) + { + section.set("slowSpeed", 0.5); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing 'slowSpeed', setting to default."); + needToSaveConfig = true; + } + if (!section.isConfigurationSection("effects")) + { + section.createSection("effects"); + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " is missing section 'effects', creating default."); + needToSaveConfig = true; + } + + this.name = section.getName(); + this.displayName = section.getString("displayName"); + + this.item = Material.getMaterial(section.getString("item")); + if (this.item == null) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid 'item', material not found."); + throw new IllegalArgumentException(); + } + + this.infiniteFuel = section.getBoolean("infiniteFuel"); + + if (!infiniteFuel) + { + this.fuel = Material.getMaterial(section.getString("fuel")); + if (this.fuel == null) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid 'fuel', material not found."); + throw new IllegalArgumentException(); + } + + this.ticksPerFuel = (section.getInt("ticksPerFuel") >= 0 ? section.getInt("ticksPerFuel") : 0); + if (this.ticksPerFuel <= 0) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid 'ticksPerFuel', must be greater than 0."); + throw new IllegalArgumentException(); + } + } + else + { + this.fuel = Material.AIR; + this.ticksPerFuel = 0; + } + + this.normalSpeed = section.getDouble("normalSpeed"); + if (this.normalSpeed <= 0.0) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid 'normalSpeed', must be greater than 0.0."); + throw new IllegalArgumentException(); + } + this.fastSpeed = section.getDouble("fastSpeed"); + if (this.fastSpeed <= 0.0) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid 'fastSpeed', must be greater than 0.0."); + throw new IllegalArgumentException(); + } + this.slowSpeed = section.getDouble("slowSpeed"); + if (this.slowSpeed <= 0.0) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid 'slowSpeed', must be greater than 0.0."); + throw new IllegalArgumentException(); + } + + + this.potionEffects = new HashMap(); + ConfigurationSection effectSection = section.getConfigurationSection("effects"); + if (!effectSection.getKeys(false).isEmpty()) + { + for (String key : effectSection.getKeys(false)) + { + PotionEffectType effectType = PotionEffectType.getByName(key); + + if (effectType != null) + { + if (effectSection.isInt(key)) + { + int i = effectSection.getInt(key); + if (i < 0) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid potion strength in 'effects', potion strenght cannot be 0."); + throw new IllegalArgumentException(); + } + this.potionEffects.put(effectType, i); + } + } + else + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid potion type in 'effects', potion type not found."); + throw new IllegalArgumentException(); + } + } + } + + this.enchantments = new HashMap(); + ConfigurationSection enchantmentSection = section.getConfigurationSection("enchantments"); + if (!enchantmentSection.getKeys(false).isEmpty()) + { + for (String key : enchantmentSection.getKeys(false)) + { + Enchantment enchantType = Enchantment.getByName(key); + + if (enchantType != null) + { + int i = enchantmentSection.getInt(key); + if (i < 0) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has enchantment level in 'in enchantments', enchantment level must be greater than -1."); + throw new IllegalArgumentException(); + } + this.enchantments.put(enchantType, i); + } + else + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid enchantment type in 'enchantments', enchantment type not found."); + throw new IllegalArgumentException(); + } + } + } + + // Do this at the end because we need a nearly completed Profile + @SuppressWarnings("unchecked") + List recipeList = (List) section.getList("recipe"); + if (recipeList.size() == 3) + { + String[] row1 = recipeList.get(0).split(" "); + String[] row2 = recipeList.get(1).split(" "); + String[] row3 = recipeList.get(2).split(" "); + if (row1.length != 3 || row2.length != 3 || row3.length != 3) + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid crafting recipe in 'recipe', too much or too few items in a row."); + throw new IllegalArgumentException(); + } + + this.recipe = new ShapedRecipe(JetpackItem.getNewJetpackItem(this).getItem()).shape("123", "456", "789"); + + Material m1 = Material.getMaterial(row1[0]); + if (m1 != null) + recipe.setIngredient('1', m1); + + Material m2 = Material.getMaterial(row1[1]); + if (m2 != null) + recipe.setIngredient('2', m2); + + Material m3 = Material.getMaterial(row1[2]); + if (m3 != null) + recipe.setIngredient('3', m3); + + + Material m4 = Material.getMaterial(row2[0]); + if (m4 != null) + recipe.setIngredient('4', m4); + + Material m5 = Material.getMaterial(row2[1]); + if (m5 != null) + recipe.setIngredient('5', m5); + + Material m6 = Material.getMaterial(row2[2]); + if (m6 != null) + recipe.setIngredient('6', m6); + + + Material m7 = Material.getMaterial(row3[0]); + if (m7 != null) + recipe.setIngredient('7', m7); + + Material m8 = Material.getMaterial(row3[1]); + if (m8 != null) + recipe.setIngredient('8', m8); + + Material m9 = Material.getMaterial(row3[2]); + if (m9 != null) + recipe.setIngredient('9', m9); + + AIOPlugin.getInstance().getServer().addRecipe(this.recipe); + } + else if (recipeList.size() == 0) + { + // This is okay, do nothing + } + else + { + AIOPlugin.getInstance().getLogger().info("Jetpack profile #" + section.getName() + " has invalid crafting recipe in 'recipe', too much or too few rows."); + throw new IllegalArgumentException(); + } + + if (needToSaveConfig) + { + try + { + AIOPlugin.getInstance().getConfigManager().saveConfiguration(); + } catch (IOException e) + { + AIOPlugin.getInstance().getLogger().warning(e.toString()); + } + } + } + else + { + AIOPlugin.getInstance().getLogger().info("Invalid call. No or invalid ConfigurationSection given."); + throw new NullPointerException(); + } + } + else + { + AIOPlugin.getInstance().getLogger().info("Invalid call. No or invalid ConfigurationSection given."); + throw new NullPointerException(); + } + } + + public String getName() + { + return this.name; + } + + public String getDisplayName() + { + return this.displayName; + } + + public Material getItem() + { + return this.item; + } + + public ShapedRecipe getRecipe() + { + return this.recipe; + } + + public HashMap getEnchantments() + { + return this.enchantments; + } + + public boolean isInfiniteFuel() + { + return this.infiniteFuel; + } + + public Material getFuel() + { + return this.fuel; + } + + public int getTicksPerFuel() + { + return this.ticksPerFuel; + } + + public double getNormalSpeed() + { + return this.normalSpeed; + } + + public double getFastSpeed() + { + return this.fastSpeed; + } + + public double getSlowSpeed() + { + return this.slowSpeed; + } + + public HashMap getPotionEffects() + { + return this.potionEffects; + } +} diff --git a/src/de/freestylecrafter/aio/jetpacks/JetpackItem.java b/src/de/freestylecrafter/aio/jetpacks/JetpackItem.java new file mode 100644 index 0000000..ffca97b --- /dev/null +++ b/src/de/freestylecrafter/aio/jetpacks/JetpackItem.java @@ -0,0 +1,287 @@ +package de.freestylecrafter.aio.jetpacks; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.bukkit.ChatColor; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class JetpackItem +{ + private static final String LORE_PLUGIN_IDENTIFIER = "§r§a> Jetpack"; + private static final String LORE_PROFILE_NAME = "§r§7#%var%"; + private static final String LORE_FUEL_LEVEL = "§r§eFuel: %var%"; + private static final String LORE_FUEL_LEVEL_COSMETIC_MAX = "/%var%"; + private static final String LORE_COSMETIC_FUEL_TYPE = "§r§eFuel type: %var%"; + private static final String LORE_ADMINISTRATIONAL_TIMESTAMP_CRAFTED = "§r§8C: %var%"; + + private Jetpack jetpackProfile; + private ItemStack item; + + private int fuel = 0; + private boolean enabled = false; + private long timestamp_crafted = 0; + + private JetpackItem(Jetpack jetpackProfile, ItemStack item) + { + this.jetpackProfile = jetpackProfile; + if (item == null) + { + ItemStack s = new ItemStack(jetpackProfile.getItem(), 1); + ItemMeta m = s.getItemMeta(); + m.setDisplayName(jetpackProfile.getDisplayName()); + s.setItemMeta(m); + + if (jetpackProfile.getEnchantments() != null && !jetpackProfile.getEnchantments().isEmpty()) + { + for (Entry kv : jetpackProfile.getEnchantments().entrySet()) + { + s.addUnsafeEnchantment(kv.getKey(), kv.getValue()); + } + } + + this.item = s; + + this.fuel = 0; + this.timestamp_crafted = 0; + this.refreshLore(); + } + else + { + this.item = item; + + if (this.item.getAmount() != 1) + this.item.setAmount(1); + + this.refreshVariables(); + } + } + + private void refreshVariables() + { + String tmp_LORE_FUEL_LEVEL = ChatColor.stripColor(LORE_FUEL_LEVEL); + String tmp_LORE_ADMINISTRATIONAL_TIMESTAMP_CRAFTED = ChatColor.stripColor(LORE_ADMINISTRATIONAL_TIMESTAMP_CRAFTED); + for (String lore : this.item.getItemMeta().getLore()) + { + String strippedLore = ChatColor.stripColor(lore); + if (strippedLore.startsWith(tmp_LORE_FUEL_LEVEL.replace("%var%", "")) && !this.getProfile().isInfiniteFuel()) + { + String fuelLore = strippedLore.split("/")[0]; + try { + this.fuel = Integer.parseInt(fuelLore.split(": ")[1]); + } + catch (NumberFormatException e) + { + this.fuel = 0; + } + } + else if (strippedLore.startsWith(tmp_LORE_ADMINISTRATIONAL_TIMESTAMP_CRAFTED.replace("%var%", ""))) + { + try { + this.timestamp_crafted = Long.parseLong(strippedLore.split(": ")[1]); + + if (this.timestamp_crafted == -1) + this.setCraftTimestamp(); + } + catch (NumberFormatException e) + { + this.timestamp_crafted = 0; + } + } + } + + if (this.getProfile().isInfiniteFuel()) + this.fuel = 0; + } + + private void refreshLore() + { + List lores = new ArrayList(); + lores.add(LORE_PLUGIN_IDENTIFIER); + lores.add(LORE_PROFILE_NAME.replace("%var%", this.getProfile().getName())); + + if (!this.getProfile().isInfiniteFuel()) + { + lores.add(LORE_FUEL_LEVEL.replace("%var%", "" + this.fuel) + LORE_FUEL_LEVEL_COSMETIC_MAX.replace("%var%", "" + this.getProfile().getTicksPerFuel())); + lores.add(LORE_COSMETIC_FUEL_TYPE.replace("%var%", this.getProfile().getFuel().name())); + } + + if (this.timestamp_crafted > 0 || this.timestamp_crafted == -1) + { + lores.add(LORE_ADMINISTRATIONAL_TIMESTAMP_CRAFTED.replace("%var%", "" + this.timestamp_crafted)); + } + + ItemMeta m = this.getItem().getItemMeta(); + m.setLore(lores); + this.getItem().setItemMeta(m); + } + + public void setCraftTimestamp() + { + this.timestamp_crafted = System.currentTimeMillis(); + this.refreshLore(); + } + + public Jetpack getProfile() + { + return this.jetpackProfile; + } + + public ItemStack getItem() + { + return this.item; + } + + public void setItem(ItemStack item) + { + this.item = item; + this.refreshVariables(); + } + + public void setFuel(int fuelTicks) + { + this.fuel = (fuelTicks >= 0 ? fuelTicks : 0); + this.refreshLore(); + } + + public int getFuel() + { + return this.fuel; + } + + public void useFuel(int amount) + { + this.setFuel(this.getFuel() - (amount >= 0 ? amount : 0)); + } + + public void reFuel(int amount) + { + this.setFuel(this.getFuel() + (amount >= 0 ? amount : 0)); + } + + public void reFuel(Inventory i) + { + if (this.getProfile().isInfiniteFuel()) + return; + + if (i == null || i.getContents() == null || i.getContents().length == 0) + return; + + ItemStack smallestStack = null; + for (ItemStack item : i.getContents()) + { + if (item == null || item.getType() == null) + continue; + + if (item.getType().equals(this.getProfile().getFuel())) + { + if ((smallestStack == null || smallestStack.getAmount() > item.getAmount()) && (JetpackItem.getJetpackItem(item) == null)) + smallestStack = item; + + if (smallestStack != null && smallestStack.getAmount() <= 1) + break; + } + } + + if (smallestStack != null) + { + int amount = smallestStack.getAmount(); + if (amount - 1 <= 0) + i.remove(smallestStack); + else + smallestStack.setAmount(amount - 1); + + this.reFuel(this.getProfile().getTicksPerFuel()); + } + } + + public boolean isEnabled() + { + return this.enabled; + } + + public void setEnabled(boolean enabled) + { + this.enabled = enabled; + } + + // Check if item is a valid jetpack with the given profile + private static boolean isJetpackCorrect(Jetpack jetpackProfile, ItemStack item) + { + if (jetpackProfile == null || item == null || !item.hasItemMeta() || !item.getItemMeta().hasLore()) + return false; + + boolean hasIdentifier = false; + boolean hasName = false; + boolean hasFuel = jetpackProfile.isInfiniteFuel(); + + String tmp_LORE_PLUGIN_IDENTIFIER = ChatColor.stripColor(LORE_PLUGIN_IDENTIFIER); + String tmp_LORE_PROFILE_NAME = ChatColor.stripColor(LORE_PROFILE_NAME); + String tmp_LORE_FUEL_LEVEL = ChatColor.stripColor(LORE_FUEL_LEVEL); + + for (String lore : item.getItemMeta().getLore()) + { + String strippedLore = ChatColor.stripColor(lore); + + if (strippedLore.equals(tmp_LORE_PLUGIN_IDENTIFIER)) + hasIdentifier = true; + + if (strippedLore.equals(tmp_LORE_PROFILE_NAME.replace("%var%", jetpackProfile.getName()))) + hasName = true; + + if (strippedLore.startsWith(tmp_LORE_FUEL_LEVEL.replace("%var%", ""))) + hasFuel = true; + } + + return (hasIdentifier && hasName && hasFuel); + } + + public static boolean isJetpack_recipeCheck(ItemStack item) + { + if (item == null || !item.hasItemMeta() || !item.getItemMeta().hasLore()) + return false; + + boolean hasIdentifier = false; + boolean hasName = false; + + String tmp_LORE_PLUGIN_IDENTIFIER = ChatColor.stripColor(LORE_PLUGIN_IDENTIFIER); + String tmp_LORE_PROFILE_NAME = ChatColor.stripColor(LORE_PROFILE_NAME); + + for (String lore : item.getItemMeta().getLore()) + { + String strippedLore = ChatColor.stripColor(lore); + + if (strippedLore.equals(tmp_LORE_PLUGIN_IDENTIFIER)) + hasIdentifier = true; + + if (strippedLore.startsWith(tmp_LORE_PROFILE_NAME.replace("%var%", ""))) + hasName = true; + } + + return (hasIdentifier && hasName); + } + + // INSTANCE CREATORS + + public static JetpackItem getNewJetpackItem(Jetpack unfinishedProfile) + { + if (unfinishedProfile == null) + return null; + + return new JetpackItem(unfinishedProfile, null); + } + + public static JetpackItem getJetpackItem(ItemStack item) + { + for (Jetpack jetpackProfile : AIOPlugin.getInstance().getJetpackManager().getProfiles()) + { + if (JetpackItem.isJetpackCorrect(jetpackProfile, item)) + return new JetpackItem(jetpackProfile, item); + } + return null; + } +} diff --git a/src/de/freestylecrafter/aio/jetpacks/JetpackManager.java b/src/de/freestylecrafter/aio/jetpacks/JetpackManager.java new file mode 100644 index 0000000..475ec5c --- /dev/null +++ b/src/de/freestylecrafter/aio/jetpacks/JetpackManager.java @@ -0,0 +1,196 @@ +package de.freestylecrafter.aio.jetpacks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.GameMode; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Recipe; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class JetpackManager +{ + private List jetpackProfiles; + private HashMap activeJetpacks; + + public JetpackManager(YamlConfiguration config) + { + this.reloadProfiles(config); + } + + public void reloadProfiles(YamlConfiguration config) + { + if (config == null) + return; + + // Unregister old recipes + this.unregisterOldRecipes(); + + ArrayList jetpackProfiles_tmp = new ArrayList(); + + ConfigurationSection jetpackSection = config.getConfigurationSection("jetpacks"); + + Set keysUnsorted = jetpackSection.getKeys(false); + List keys = new ArrayList(keysUnsorted); + Collections.sort(keys); + + if (!keys.isEmpty()) + { + for (String subSection : keys) + { + try { + jetpackProfiles_tmp.add(new Jetpack(jetpackSection.getConfigurationSection(subSection))); + AIOPlugin.getInstance().getLogger().info("Registered jetpack #" + subSection); + } + catch (IllegalArgumentException e) + { + AIOPlugin.getInstance().getLogger().warning(e.toString()); + AIOPlugin.getInstance().getLogger().info("Skipping registration of jetpack #" + subSection); + } + catch (NullPointerException e) + { + AIOPlugin.getInstance().getLogger().warning(e.toString()); + AIOPlugin.getInstance().getLogger().info("Skipping registration of jetpack #" + subSection); + } + } + } + + this.activeJetpacks = new HashMap(); + this.jetpackProfiles = jetpackProfiles_tmp; + } + + public void unregisterOldRecipes() + { + Iterator i = AIOPlugin.getInstance().getServer().recipeIterator(); + while (i.hasNext()) + { + Recipe r = i.next(); + if (JetpackItem.isJetpack_recipeCheck(r.getResult())) + { + i.remove(); + } + } + } + + public List getProfiles() + { + return this.jetpackProfiles; + } + + public Jetpack getProfileByName(String name) + { + for (Jetpack jetpackProfile : AIOPlugin.getInstance().getJetpackManager().getProfiles()) + { + if (jetpackProfile.getName().equals(name)) + return jetpackProfile; + } + return null; + } + + public HashMap getActiveJetpackItems() + { + return this.activeJetpacks; + } + + public void checkJetpackItemForPlayer(Player p) + { + if (p == null) + return; + + if (p.getGameMode() != GameMode.CREATIVE && p.getInventory().getChestplate() != null && !p.isDead()) + { + JetpackItem jetpack = JetpackItem.getJetpackItem(p.getInventory().getChestplate()); + if (jetpack == null || !PermissionsHelper.canUseJetpack(jetpack, p)) + { + this.removeJetpackItemForPlayer(p); + return; + } + this.addJetpackItemForPlayer(p, jetpack); + } + else + { + this.removeJetpackItemForPlayer(p); + return; + } + } + + public JetpackItem getJetpackItemForPlayer(Player p) + { + if (p != null && this.activeJetpacks.containsKey(p.getUniqueId())) + return this.activeJetpacks.get(p.getUniqueId()); + + return null; + } + + public void removeJetpackItemForPlayer(Player p) + { + if (this.activeJetpacks.containsKey(p.getUniqueId())) + { + Jetpack profile = this.activeJetpacks.get(p.getUniqueId()).getProfile(); + this.activeJetpacks.remove(p.getUniqueId()); + + if (p.getGameMode() != GameMode.CREATIVE && p.getAllowFlight()) + p.setAllowFlight(false); + + if (profile.getPotionEffects() != null && !profile.getPotionEffects().isEmpty()) + { + for (Entry kv : profile.getPotionEffects().entrySet()) + { + p.removePotionEffect(kv.getKey()); + } + } + + String name = (profile == null || profile.getName() == null ? "unknown" : profile.getName()); + p.sendMessage(AIOPlugin.getInstance().getConfigManager().getConfiguration().getString("message-unequip", "").replace("%name%", "#" + name)); + } + } + + private void addJetpackItemForPlayer(Player p, JetpackItem i) + { + if (p == null || i == null) + return; + + if (this.activeJetpacks.containsKey(p.getUniqueId())) + { + JetpackItem current = this.activeJetpacks.get(p.getUniqueId()); + + if (current != null && current.getItem().equals(i.getItem())) + { + if (p.getGameMode() != GameMode.CREATIVE && !p.getAllowFlight()) + p.setAllowFlight(true); + + return; + } + else + this.removeJetpackItemForPlayer(p); + } + + if (PermissionsHelper.canUseJetpack(i, p)) + { + this.activeJetpacks.put(p.getUniqueId(), i); + + if (p.getGameMode() != GameMode.CREATIVE && !p.getAllowFlight()) + p.setAllowFlight(true); + + if (i.getProfile().getPotionEffects() != null && !i.getProfile().getPotionEffects().isEmpty()) + { + for (Entry kv : i.getProfile().getPotionEffects().entrySet()) + { + p.addPotionEffect(new PotionEffect(kv.getKey(), Integer.MAX_VALUE, kv.getValue()), true); + } + } + + String name = (i.getProfile() == null || i.getProfile().getName() == null ? "unknown" : i.getProfile().getName()); + p.sendMessage(AIOPlugin.getInstance().getConfigManager().getConfiguration().getString("message-equip", "").replace("%name%", "#" + name)); + } + } +} diff --git a/src/de/freestylecrafter/aio/jetpacks/PermissionsHelper.java b/src/de/freestylecrafter/aio/jetpacks/PermissionsHelper.java new file mode 100644 index 0000000..9470901 --- /dev/null +++ b/src/de/freestylecrafter/aio/jetpacks/PermissionsHelper.java @@ -0,0 +1,128 @@ +package de.freestylecrafter.aio.jetpacks; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class PermissionsHelper +{ + private static final String BASE_PERMISSION = "aio.jetpacks"; + private static final String JETPACKS_PERMISSION_COMMAND_BASE = BASE_PERMISSION + ".command.base"; + private static final String JETPACKS_PERMISSION_COMMAND_CHEAT = BASE_PERMISSION + ".command.cheat"; + private static final String JETPACKS_PERMISSION_COMMAND_RELOAD = BASE_PERMISSION + ".command.reload"; + private static final String JETPACKS_PERMISSION_USE_ALL = BASE_PERMISSION + ".jetpack.use.*"; + private static final String JETPACKS_PERMISSION_USE_VAR = BASE_PERMISSION + ".jetpack.use.%var%"; + private static final String JETPACKS_PERMISSION_CRAFT_ALL = BASE_PERMISSION + ".jetpack.craft.*"; + private static final String JETPACKS_PERMISSION_CRAFT_VAR = BASE_PERMISSION + ".jetpack.craft.%var%"; + private static final String JETPACKS_PERMISSION_CHEAT_ALL = BASE_PERMISSION + ".jetpack.cheat.*"; + private static final String JETPACKS_PERMISSION_CHEAT_VAR = BASE_PERMISSION + ".jetpack.cheat.%var%"; + + public static final String MESSAGE_NOT_ALLOWED_USE = ChatColor.RED + "You don't have permission to use this jetpack."; + public static final String MESSAGE_NOT_ALLOWED_CRAFT = ChatColor.RED + "You don't have permission to craft this jetpack."; + + public static boolean canUseJetpack(JetpackItem i, Player p) + { + if (i == null || p == null) + return false; + + return PermissionsHelper.canUseJetpack(i.getProfile(), p); + } + + public static boolean canUseJetpack(Jetpack j, Player p) + { + if (j == null || p == null) + return false; + + // If we don't use permissions, allow to use all jetpacks + if (!AIOPlugin.getInstance().getConfigManager().getConfiguration().getBoolean("use-permissions")) + return true; + + if (p.hasPermission(JETPACKS_PERMISSION_USE_ALL) || p.hasPermission(JETPACKS_PERMISSION_USE_VAR.replace("%var%", j.getName()))) + return true; + + return false; + } + + public static boolean canCraftJetpack(JetpackItem i, Player p) + { + if (i == null || p == null) + return false; + + return PermissionsHelper.canCraftJetpack(i.getProfile(), p); + } + + public static boolean canCraftJetpack(Jetpack j, Player p) + { + if (j == null || p == null) + return false; + + // If we don't use permissions, allow to craft all jetpacks + if (!AIOPlugin.getInstance().getConfigManager().getConfiguration().getBoolean("use-permissions")) + return true; + + if (p.hasPermission(JETPACKS_PERMISSION_CRAFT_ALL) || p.hasPermission(JETPACKS_PERMISSION_CRAFT_VAR.replace("%var%", j.getName()))) + return true; + + return false; + } + + public static boolean canCheatJetpack(Jetpack j, Player p) + { + if (j == null || p == null) + return false; + + // If we don't use permissions, check if player is op + if (!AIOPlugin.getInstance().getConfigManager().getConfiguration().getBoolean("use-permissions")) + return p.isOp(); + + if (p.hasPermission(JETPACKS_PERMISSION_CHEAT_ALL) || p.hasPermission(JETPACKS_PERMISSION_CHEAT_VAR.replace("%var%", j.getName()))) + return true; + + return false; + } + + + public static boolean canCommandBase(Player p) + { + if (p == null) + return false; + + // If we don't use permissions, check if player is op + if (!AIOPlugin.getInstance().getConfigManager().getConfiguration().getBoolean("use-permissions")) + return p.isOp(); + + if (p.hasPermission(JETPACKS_PERMISSION_COMMAND_BASE)) + return true; + + return false; + } + + public static boolean canCommandCheat(Player p) + { + if (p == null) + return false; + + // If we don't use permissions, check if player is op + if (!AIOPlugin.getInstance().getConfigManager().getConfiguration().getBoolean("use-permissions")) + return p.isOp(); + + if (p.hasPermission(JETPACKS_PERMISSION_COMMAND_CHEAT)) + return true; + + return false; + } + + public static boolean canCommandReload(Player p) + { + if (p == null) + return false; + + // If we don't use permissions, check if player is op + if (!AIOPlugin.getInstance().getConfigManager().getConfiguration().getBoolean("use-permissions")) + return p.isOp(); + + if (p.hasPermission(JETPACKS_PERMISSION_COMMAND_RELOAD)) + return true; + + return false; + } +} diff --git a/src/plugin.yml b/src/plugin.yml new file mode 100644 index 0000000..b34bcd8 --- /dev/null +++ b/src/plugin.yml @@ -0,0 +1,12 @@ +name: AIO-Jetpacks +main: de.freestylecrafter.aio.jetpacks.AIOPlugin +version: 1.0.4 +commands: + jetpacks: + description: AIO Jetpacks help + usage: /jetpacks + permission: aio.jetpacks.command.base +permissions: + aio.jetpacks.command.base: + description: Allows you to use /jetpacks + default: op