commit 799638e1cc3465ae26431c98215a4e89163013d5 Author: Trixkz Date: Fri Sep 20 02:33:18 2024 -0400 Initial commit. diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..fa02fde --- /dev/null +++ b/pom.xml @@ -0,0 +1,154 @@ + + + 4.0.0 + + com.loganmagnan + BlockHealth + 1.0 + jar + + BlockHealth + + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + fawe-repo + https://ci.athion.net/job/FastAsyncWorldEdit/ws/mvn/ + + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + + + jitpack.io + https://jitpack.io + + + + + + + + com.destroystokyo.paper + paper-api + 1.16.5-R0.1-SNAPSHOT + provided + + + + + com.google.code.gson + gson + 2.8.8 + compile + + + + + org.mongodb + mongo-java-driver + 3.12.10 + compile + + + + + org.projectlombok + lombok + 1.18.20 + provided + + + + + com.sk89q + worldedit + 6.0.0-SNAPSHOT + provided + + + + + com.boydti + fawe-api + latest + provided + + + + + me.clip + placeholderapi + 2.10.9 + provided + + + + com.github.decentsoftware-eu + decentholograms + 2.7.5 + provided + + + + net.wesjd + anvilgui + 1.5.3-SNAPSHOT + + + + \ No newline at end of file diff --git a/src/main/java/com/loganmagnan/blockhealth/BlockHealth.java b/src/main/java/com/loganmagnan/blockhealth/BlockHealth.java new file mode 100644 index 0000000..65fd7e6 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/BlockHealth.java @@ -0,0 +1,82 @@ +package com.loganmagnan.blockhealth; + +import com.loganmagnan.blockhealth.managers.BlockManager; +import com.loganmagnan.blockhealth.managers.PlayerDataManager; +import com.loganmagnan.blockhealth.utils.ClassRegistrationUtils; +import com.loganmagnan.blockhealth.utils.Utils; +import com.loganmagnan.blockhealth.utils.command.CommandFramework; +import com.loganmagnan.blockhealth.utils.menusystem.PlayerMenuUtil; +import lombok.Getter; +import com.loganmagnan.blockhealth.utils.config.FileConfig; +import com.loganmagnan.blockhealth.utils.config.file.Config; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.HashMap; + +@Getter +public class BlockHealth extends JavaPlugin { + + @Getter private static BlockHealth instance; + + private Config mainConfig; + private FileConfig messagesConfig; + + private PlayerDataManager playerDataManager; + private BlockManager blockManager; + + private HashMap playerMenuUtilMap = new HashMap<>(); + + private CommandFramework commandFramework = new CommandFramework(this); + + @Override + public void onEnable() { + instance = this; + + this.saveDefaultConfig(); + this.mainConfig = new Config("config", this); + this.messagesConfig = new FileConfig(this, "messages.yml"); + + Bukkit.getConsoleSender().sendMessage("------------------------------------------------"); + Bukkit.getConsoleSender().sendMessage(Utils.translate("&bBlockHealth &8- &av" + this.getDescription().getVersion())); + Bukkit.getConsoleSender().sendMessage(Utils.translate("&7Made by &eLoganM Development")); + Bukkit.getConsoleSender().sendMessage("------------------------------------------------"); + + this.loadCommands(); + this.loadManagers(); + this.loadListeners(); + this.loadRunnables(); + + if (this.getServer().getPluginManager().getPlugin("DecentHolograms") == null) { + Bukkit.getConsoleSender().sendMessage(Utils.translate("&cDecentHolograms not found")); + Bukkit.getConsoleSender().sendMessage(Utils.translate("&cBlockHealth has been disabled")); + + this.getServer().getPluginManager().disablePlugin(this); + } else { + Bukkit.getConsoleSender().sendMessage(Utils.translate("&aDecentHolograms has been enabled")); + } + } + + @Override + public void onDisable() { + instance = null; + } + + private void loadCommands() { + ClassRegistrationUtils.loadCommands("me.trixkz.blockhealth.commands"); + } + + private void loadManagers() { + this.playerDataManager = new PlayerDataManager(); + this.blockManager = new BlockManager(); + } + + private void loadListeners() { + ClassRegistrationUtils.loadListeners("me.trixkz.blockhealth.listeners"); + } + + private void loadRunnables() { + + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/listeners/MenuListener.java b/src/main/java/com/loganmagnan/blockhealth/listeners/MenuListener.java new file mode 100644 index 0000000..c001f98 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/listeners/MenuListener.java @@ -0,0 +1,26 @@ +package com.loganmagnan.blockhealth.listeners; + +import com.loganmagnan.blockhealth.utils.menusystem.Menu; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.InventoryHolder; + +public class MenuListener implements Listener { + + @EventHandler + public void onMenuClick(InventoryClickEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + + if (holder instanceof Menu) { + event.setCancelled(true); + + if (event.getCurrentItem() == null) { + return; + } + + Menu menu = (Menu) holder; + menu.handleMenu(event); + } + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/listeners/PlayerDataListener.java b/src/main/java/com/loganmagnan/blockhealth/listeners/PlayerDataListener.java new file mode 100644 index 0000000..bcd5505 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/listeners/PlayerDataListener.java @@ -0,0 +1,77 @@ +package com.loganmagnan.blockhealth.listeners; + +import com.loganmagnan.blockhealth.BlockHealth; +import com.loganmagnan.blockhealth.playerdata.PlayerData; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.*; + +public class PlayerDataListener implements Listener { + + private BlockHealth plugin = BlockHealth.getInstance(); + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onAsyncPlayerPreLogin(AsyncPlayerPreLoginEvent event) { + Player player = Bukkit.getPlayer(event.getUniqueId()); + if (player != null) { + if (player.isOnline()) { + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + event.setKickMessage("§cYou tried to login too quickly after disconnecting.\n§cTry again in a few seconds."); + + this.plugin.getServer().getScheduler().runTask(this.plugin, () -> player.kickPlayer("§cDuplicate Login")); + return; + } + + PlayerData playerData = this.plugin.getPlayerDataManager().getPlayerData(player.getUniqueId()); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerLogin(PlayerLoginEvent event) { + PlayerData playerData = this.plugin.getPlayerDataManager().getOrCreate(event.getPlayer().getUniqueId()); + if (playerData == null) { + event.setResult(PlayerLoginEvent.Result.KICK_OTHER); + event.setKickMessage("§cAn error has occurred while loading your profile. Please reconnect."); + return; + } + + if (!playerData.isLoaded()) { + event.setResult(PlayerLoginEvent.Result.KICK_OTHER); + event.setKickMessage("§cAn error has occurred while loading your profile. Please reconnect."); + } + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + event.setJoinMessage(null); + + Player player = event.getPlayer(); + + if (this.plugin.getBlockManager().getBlockHealthRunnable().getPlayers().contains(player)) { + return; + } + + this.plugin.getBlockManager().getBlockHealthRunnable().getPlayers().add(player); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + event.setQuitMessage(null); + + Player player = event.getPlayer(); + + if (!this.plugin.getBlockManager().getBlockHealthRunnable().getPlayers().contains(player)) { + return; + } + + this.plugin.getBlockManager().getBlockHealthRunnable().getPlayers().remove(player); + } + + @EventHandler + public void onPlayerKick(PlayerKickEvent event) { + Player player = event.getPlayer(); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/listeners/PlayerListener.java b/src/main/java/com/loganmagnan/blockhealth/listeners/PlayerListener.java new file mode 100644 index 0000000..3535ecf --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/listeners/PlayerListener.java @@ -0,0 +1,20 @@ +package com.loganmagnan.blockhealth.listeners; + +import com.loganmagnan.blockhealth.playerdata.PlayerData; +import com.loganmagnan.blockhealth.BlockHealth; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; + +public class PlayerListener implements Listener { + + private BlockHealth main = BlockHealth.getInstance(); + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + + PlayerData playerData = this.main.getPlayerDataManager().getPlayerData(player.getUniqueId()); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/listeners/WorldListener.java b/src/main/java/com/loganmagnan/blockhealth/listeners/WorldListener.java new file mode 100644 index 0000000..343a4f7 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/listeners/WorldListener.java @@ -0,0 +1,30 @@ +package com.loganmagnan.blockhealth.listeners; + +import com.loganmagnan.blockhealth.BlockHealth; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; + +public class WorldListener implements Listener { + + private BlockHealth main = BlockHealth.getInstance(); + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) { + + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + + Block block = event.getBlock(); + + this.main.getBlockManager().damageBlock(player, block); + + event.setCancelled(true); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/managers/BlockManager.java b/src/main/java/com/loganmagnan/blockhealth/managers/BlockManager.java new file mode 100644 index 0000000..614c36b --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/managers/BlockManager.java @@ -0,0 +1,137 @@ +package com.loganmagnan.blockhealth.managers; + +import com.loganmagnan.blockhealth.runnables.BlockHealthRunnable; +import lombok.Getter; +import lombok.Setter; +import com.loganmagnan.blockhealth.BlockHealth; +import com.loganmagnan.blockhealth.utils.Utils; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicInteger; + +@Getter +@Setter +public class BlockManager { + + private BlockHealth main = BlockHealth.getInstance(); + + private Map blocks = new HashMap(); + private Map blockHealths = new HashMap(); + private Map damageAmountsPerBreak = new HashMap(); + + private int defaultBlockHealth; + private int defaultMinimumDamageAmountPerBreak; + private int defaultMaximumDamageAmountPerBreak; + private int defaultDamageAmountPerBreak; + + private BlockHealthRunnable blockHealthRunnable; + + public BlockManager() { + for (String string : this.main.getMainConfig().getConfig().getConfigurationSection("BLOCKS").getKeys(false)) { + this.blockHealths.put(Material.valueOf(string.toUpperCase()), new AtomicInteger(this.main.getMainConfig().getConfig().getInt("BLOCKS." + string + ".HEALTH"))); + } + + for (String string : this.main.getMainConfig().getConfig().getConfigurationSection("BLOCKS").getKeys(false)) { + int minimumDamageAmountPerBreak = this.main.getMainConfig().getConfig().getInt("BLOCKS." + string + ".MINIMUM-DAMAGE-AMOUNT-PER-BREAK"); + int maximumDamageAmountPerBreak = this.main.getMainConfig().getConfig().getInt("BLOCKS." + string + ".MAXIMUM-DAMAGE-AMOUNT-PER-BREAK"); + int damageAmountPerBreak = ThreadLocalRandom.current().nextInt(minimumDamageAmountPerBreak, maximumDamageAmountPerBreak + 1); + + this.damageAmountsPerBreak.put(Material.valueOf(string.toUpperCase()), new AtomicInteger(damageAmountPerBreak)); + } + + this.defaultBlockHealth = this.main.getMainConfig().getConfig().getInt("DEFAULT-BLOCK-HEALTH"); + this.defaultMinimumDamageAmountPerBreak = this.main.getMainConfig().getConfig().getInt("DEFAULT-MINIMUM-DAMAGE-AMOUNT-PER-BREAK"); + this.defaultMaximumDamageAmountPerBreak = this.main.getMainConfig().getConfig().getInt("DEFAULT-MAXIMUM-DAMAGE-AMOUNT-PER-BREAK"); + this.defaultDamageAmountPerBreak = ThreadLocalRandom.current().nextInt(this.defaultMinimumDamageAmountPerBreak, this.defaultMaximumDamageAmountPerBreak + 1); + this.blockHealthRunnable = new BlockHealthRunnable(); + } + + public int getBlockHealth(Block block) { + if (!this.isBlockRegistered(block)) { + int blockHealth = this.getBlockMaximumHealth(block); + + this.addBlock(block, blockHealth); + + return blockHealth; + } + + return this.blocks.get(block).get(); + } + + public int getBlockMaximumHealth(Block block) { + Material material = block.getType(); + + int blockMaximumHealth = 0; + + if (this.blockHealths.containsKey(material)) { + blockMaximumHealth = this.blockHealths.get(material).get(); + } else { + blockMaximumHealth = this.defaultBlockHealth; + } + + return blockMaximumHealth; + } + + public int getDamageAmountPerBreak(Block block) { + Material material = block.getType(); + + int damageAmountPerBreak = 0; + + if (this.damageAmountsPerBreak.containsKey(material)) { + damageAmountPerBreak = this.damageAmountsPerBreak.get(material).get(); + } else { + damageAmountPerBreak = this.defaultDamageAmountPerBreak; + } + + return damageAmountPerBreak; + } + + public void addBlock(Block block, int blockHealth) { + this.blocks.put(block, new AtomicInteger(blockHealth)); + } + + public void removeBlock(Block block) { + this.blocks.remove(block); + } + + public void sendPlayerBlockHealthMessage(Player player, Block block) { + player.sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(Utils.translate("&bBlock Health: &f" + this.getBlockHealth(block)))); + } + + public boolean isBlockRegistered(Block block) { + return this.blocks.containsKey(block); + } + + public boolean isBlockBroken(Block block) { + return this.getBlockHealth(block) <= 0; + } + + public void damageBlock(Player player, Block block) { + ItemStack itemStack = player.getItemInHand(); + + int amount = 0; + amount = this.getDamageAmountPerBreak(block); + + // to do + // look for the custom items damage amounts + + int blockHealth = this.getBlockHealth(block); + blockHealth -= amount; + + this.blocks.get(block).set(blockHealth); + + if (this.isBlockBroken(block)) { + this.removeBlock(block); + + block.setType(Material.AIR); + } + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/managers/PlayerDataManager.java b/src/main/java/com/loganmagnan/blockhealth/managers/PlayerDataManager.java new file mode 100644 index 0000000..6f71384 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/managers/PlayerDataManager.java @@ -0,0 +1,32 @@ +package com.loganmagnan.blockhealth.managers; + +import com.loganmagnan.blockhealth.playerdata.PlayerData; +import com.loganmagnan.blockhealth.BlockHealth; +import com.loganmagnan.blockhealth.playerdata.PlayerState; +import lombok.Getter; + +import java.util.*; + +public class PlayerDataManager { + + private BlockHealth plugin = BlockHealth.getInstance(); + + @Getter private Map players = new HashMap<>(); + + public PlayerData getOrCreate(UUID uniqueId) { + return this.players.computeIfAbsent(uniqueId, PlayerData::new); + } + + public PlayerData getPlayerData(UUID uniqueId) { + return this.players.getOrDefault(uniqueId, new PlayerData(uniqueId)); + } + + public Collection getAllPlayers() { + return this.players.values(); + } + + public void loadPlayerData(PlayerData playerData) { + playerData.setPlayerState(PlayerState.SPAWN); + playerData.setLoaded(true); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/menus/BlockHealthsMenu.java b/src/main/java/com/loganmagnan/blockhealth/menus/BlockHealthsMenu.java new file mode 100644 index 0000000..2d3bae2 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/menus/BlockHealthsMenu.java @@ -0,0 +1,110 @@ +package com.loganmagnan.blockhealth.menus; + +import com.loganmagnan.blockhealth.utils.menusystem.ItemStackButton; +import com.loganmagnan.blockhealth.utils.menusystem.PaginatedMenu; +import com.loganmagnan.blockhealth.BlockHealth; +import com.loganmagnan.blockhealth.utils.Utils; +import com.loganmagnan.blockhealth.utils.menusystem.PlayerMenuUtil; +import net.wesjd.anvilgui.AnvilGUI; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class BlockHealthsMenu extends PaginatedMenu { + + private BlockHealth main = BlockHealth.getInstance(); + + public BlockHealthsMenu(PlayerMenuUtil playerMenuUtil) { + super(playerMenuUtil); + } + + @Override + public String getMenuName() { + return Utils.translate("&eBlock healths"); + } + + @Override + public int getSlots() { + return 54; + } + + @Override + public void handleMenu(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + + if (event.getView().getTitle().equalsIgnoreCase(Utils.translate("&eBlock healths"))) { + ItemStack itemStack = event.getCurrentItem(); + + for (Material material : this.main.getBlockManager().getBlockHealths().keySet()) { + if (itemStack.getType() != material) { + continue; + } + + new AnvilGUI.Builder().onComplete((anvilGUIPlayer, string) -> { + int blockHealth = Integer.parseInt(string); + + this.main.getBlockManager().getBlockHealths().get(material).set(blockHealth); + this.main.getMainConfig().getConfig().set("BLOCKS." + material.name() + ".HEALTH", blockHealth); + this.main.getMainConfig().save(); + + return AnvilGUI.Response.close(); + }).onClose(anvilGUIPlayer -> { + + }).title(Utils.translate("&eChange " + material.name() + " health")).text("").plugin(this.main).open(player); + } + + switch (ChatColor.stripColor(event.getCurrentItem().getItemMeta().getDisplayName())) { + case "Previous page": + if (this.page == 0) { + player.sendMessage(Utils.translate("&aYou are on the first page")); + } else { + this.page--; + this.open(player); + } + + break; + case "Close": + player.closeInventory(); + + break; + case "Next page": + if (!((this.index++) >= this.main.getBlockManager().getBlockHealths().size())) { + this.page++; + this.open(player); + } else { + player.sendMessage(Utils.translate("&aYou are on the last page")); + } + + break; + } + } + } + + @Override + public void setMenuItems(Player player) { + this.addMenuBorder(); + this.main.getBlockManager().getBlockHealths().forEach((material, atomicInteger) -> { + List lore = new ArrayList(); + lore.add(Utils.translate("&bBlock health: &f" + atomicInteger.get())); + lore.add(Utils.translate("")); + lore.add(Utils.translate("&7Click to change")); + + ItemStackButton itemStackButton = new ItemStackButton( + Utils.translate("&b" + material.name()), + lore, + material, + 0, + 1 + ); + + ItemStack itemStack = itemStackButton.makeItemStack(); + + this.inventory.addItem(itemStack); + }); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerData.java b/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerData.java new file mode 100644 index 0000000..1ef1ea7 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerData.java @@ -0,0 +1,33 @@ +package com.loganmagnan.blockhealth.playerdata; + +import com.loganmagnan.blockhealth.BlockHealth; +import com.loganmagnan.blockhealth.managers.PlayerDataManager; +import com.loganmagnan.blockhealth.playerdata.currentgame.PlayerCurrentGameData; +import lombok.Getter; +import lombok.Setter; + +import java.util.UUID; + +@Getter +@Setter +public class PlayerData { + + private PlayerDataManager playerDataManager = BlockHealth.getInstance().getPlayerDataManager(); + private PlayerState playerState = PlayerState.SPAWN; + + private PlayerSettings playerSettings = new PlayerSettings(); + private PlayerCurrentGameData currentGameData = new PlayerCurrentGameData(); + + private UUID uniqueId; + private boolean loaded; + + public PlayerData(UUID uniqueId) { + this.uniqueId = uniqueId; + this.loaded = false; + this.playerDataManager.loadPlayerData(this); + } + + public boolean isInSpawn() { + return this.playerState == PlayerState.SPAWN; + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerSettings.java b/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerSettings.java new file mode 100644 index 0000000..2e35e50 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerSettings.java @@ -0,0 +1,8 @@ +package com.loganmagnan.blockhealth.playerdata; + +import lombok.Data; + +@Data +public class PlayerSettings { + +} diff --git a/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerState.java b/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerState.java new file mode 100644 index 0000000..ccc3a57 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/playerdata/PlayerState.java @@ -0,0 +1,7 @@ +package com.loganmagnan.blockhealth.playerdata; + +public enum PlayerState { + + SPAWN, + PLAYING; +} diff --git a/src/main/java/com/loganmagnan/blockhealth/playerdata/currentgame/PlayerCurrentGameData.java b/src/main/java/com/loganmagnan/blockhealth/playerdata/currentgame/PlayerCurrentGameData.java new file mode 100644 index 0000000..28e26f2 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/playerdata/currentgame/PlayerCurrentGameData.java @@ -0,0 +1,10 @@ +package com.loganmagnan.blockhealth.playerdata.currentgame; + +import com.loganmagnan.blockhealth.BlockHealth; +import lombok.Data; + +@Data +public class PlayerCurrentGameData { + + private BlockHealth main = BlockHealth.getInstance(); +} diff --git a/src/main/java/com/loganmagnan/blockhealth/runnables/BlockHealthRunnable.java b/src/main/java/com/loganmagnan/blockhealth/runnables/BlockHealthRunnable.java new file mode 100644 index 0000000..5bd7463 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/runnables/BlockHealthRunnable.java @@ -0,0 +1,47 @@ +package com.loganmagnan.blockhealth.runnables; + +import lombok.Getter; +import lombok.Setter; +import com.loganmagnan.blockhealth.BlockHealth; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +public class BlockHealthRunnable implements Runnable { + + private BlockHealth main = BlockHealth.getInstance(); + + private List players = new ArrayList(); + + private int taskId; + + public BlockHealthRunnable() { + for (Player player : this.main.getServer().getOnlinePlayers()) { + this.players.add(player); + } + + this.taskId = this.main.getServer().getScheduler().scheduleSyncRepeatingTask(this.main, this, 2L, 2L); + } + + @Override + public void run() { + for (Player player : this.players) { + Block block = player.getTargetBlock(5); + + if (block == null) { + continue; + } + + if (block.getType() == Material.AIR) { + continue; + } + + this.main.getBlockManager().sendPlayerBlockHealthMessage(player, block); + } + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/ClassRegistrationUtils.java b/src/main/java/com/loganmagnan/blockhealth/utils/ClassRegistrationUtils.java new file mode 100644 index 0000000..5ab97fa --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/ClassRegistrationUtils.java @@ -0,0 +1,95 @@ +package com.loganmagnan.blockhealth.utils; + +import com.google.common.collect.ImmutableSet; +import com.loganmagnan.blockhealth.BlockHealth; +import org.bukkit.event.Listener; + +import java.io.IOException; +import java.net.URL; +import java.security.CodeSource; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public class ClassRegistrationUtils { + + public static void loadListeners(String packageName) { + for (Class clazz : getClassesInPackage(packageName)) { + if (isListener(clazz)) { + try { + BlockHealth.getInstance().getServer().getPluginManager().registerEvents((Listener) clazz.newInstance(), BlockHealth.getInstance()); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + } + } + + public static void loadCommands(String packageName) { + for (Class clazz : getClassesInPackage(packageName)) { + try { + clazz.newInstance(); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + } + + public static boolean isListener(Class clazz) { + for (Class interfaze : clazz.getInterfaces()) { + if (interfaze == Listener.class) { + return true; + } + } + + return false; + } + + public static Collection> getClassesInPackage(String packageName) { + JarFile jarFile; + Collection> classes = new ArrayList<>(); + CodeSource codeSource = BlockHealth.getInstance().getClass().getProtectionDomain().getCodeSource(); + URL resource = codeSource.getLocation(); + + String relPath = packageName.replace('.', '/'); + String resPath = resource.getPath().replace("%20", " "); + String jarPath = resPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); + + try { + jarFile = new JarFile(jarPath); + } catch (IOException e) { + throw new IllegalStateException("Unexpected IOException reading JAR File '" + jarPath + "'", e); + } + + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + String className = null; + if (entryName.endsWith(".class") && entryName.startsWith(relPath) && entryName.length() > relPath.length() + "/".length()) { + className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); + } + if (className != null) { + Class clazz = null; + try { + clazz = Class.forName(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + if (clazz != null) { + classes.add(clazz); + } + } + } + + try { + jarFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return ImmutableSet.copyOf(classes); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/Clickable.java b/src/main/java/com/loganmagnan/blockhealth/utils/Clickable.java new file mode 100644 index 0000000..fb289bc --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/Clickable.java @@ -0,0 +1,51 @@ +package com.loganmagnan.blockhealth.utils; + +import lombok.NoArgsConstructor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +@NoArgsConstructor +public class Clickable { + + private final List components = new ArrayList<>(); + + public Clickable(String msg) { + TextComponent message = new TextComponent(msg); + this.components.add(message); + } + + public Clickable(String msg, String hoverMsg, String clickString) { + this.add(msg, hoverMsg, clickString); + } + + public TextComponent add(String msg, String hoverMsg, String clickString) { + TextComponent message = new TextComponent(msg); + if (hoverMsg != null) { + message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hoverMsg).create())); + } + if (clickString != null) { + message.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, clickString)); + } + this.components.add(message); + + return message; + } + + public void add(String message) { + this.components.add(new TextComponent(message)); + } + + public void sendToPlayer(Player player) { + player.spigot().sendMessage(this.asComponents()); + } + + public TextComponent[] asComponents() { + return this.components.toArray(new TextComponent[0]); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/CustomLocation.java b/src/main/java/com/loganmagnan/blockhealth/utils/CustomLocation.java new file mode 100644 index 0000000..82eada3 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/CustomLocation.java @@ -0,0 +1,125 @@ +package com.loganmagnan.blockhealth.utils; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; + +import java.util.StringJoiner; + +@Getter +@Setter +@AllArgsConstructor +public class CustomLocation { + + private final long timestamp = System.currentTimeMillis(); + + private String world; + + private double x; + private double y; + private double z; + + private float yaw; + private float pitch; + + public CustomLocation(double x, double y, double z) { + this(x, y, z, 0.0F, 0.0F); + } + + public CustomLocation(String world, double x, double y, double z) { + this(world, x, y, z, 0.0F, 0.0F); + } + + public CustomLocation(double x, double y, double z, float yaw, float pitch) { + this("world", x, y, z, yaw, pitch); + } + + public static CustomLocation fromBukkitLocation(Location location) { + return new CustomLocation(location.getWorld().getName(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } + + public static CustomLocation stringToLocation(String string) { + String[] split = string.split(", "); + + double x = Double.parseDouble(split[0]); + double y = Double.parseDouble(split[1]); + double z = Double.parseDouble(split[2]); + + CustomLocation customLocation = new CustomLocation(x, y, z); + if (split.length == 4) { + customLocation.setWorld(split[3]); + } else if (split.length >= 5) { + customLocation.setYaw(Float.parseFloat(split[3])); + customLocation.setPitch(Float.parseFloat(split[4])); + if (split.length >= 6) { + customLocation.setWorld(split[5]); + } + } + + return customLocation; + } + + public static String locationToString(CustomLocation loc) { + StringJoiner joiner = new StringJoiner(", "); + joiner.add(Double.toString(loc.getX())); + joiner.add(Double.toString(loc.getY())); + joiner.add(Double.toString(loc.getZ())); + if (loc.getYaw() == 0.0f && loc.getPitch() == 0.0f) { + if (loc.getWorld().equals("world")) { + return joiner.toString(); + } else { + joiner.add(loc.getWorld()); + return joiner.toString(); + } + } else { + joiner.add(Float.toString(loc.getYaw())); + joiner.add(Float.toString(loc.getPitch())); + if (loc.getWorld().equals("world")) { + return joiner.toString(); + } else { + joiner.add(loc.getWorld()); + return joiner.toString(); + } + } + } + + public Location toBukkitLocation() { + return new Location(this.toBukkitWorld(), this.x, this.y, this.z, this.yaw, this.pitch); + } + + public World toBukkitWorld() { + if (this.world == null) { + return Bukkit.getServer().getWorlds().get(0); + } else { + return Bukkit.getServer().getWorld(this.world); + } + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CustomLocation)) { + return false; + } + + CustomLocation location = (CustomLocation) obj; + + return location.x == this.x && location.y == this.y && location.z == this.z && location.pitch == this.pitch && location.yaw == this.yaw; + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("x", this.x) + .append("y", this.y) + .append("z", this.z) + .append("yaw", this.yaw) + .append("pitch", this.pitch) + .append("world", this.world) + .append("timestamp", this.timestamp) + .toString(); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/ItemBuilder.java b/src/main/java/com/loganmagnan/blockhealth/utils/ItemBuilder.java new file mode 100644 index 0000000..ac25522 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/ItemBuilder.java @@ -0,0 +1,184 @@ +package com.loganmagnan.blockhealth.utils; + +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.material.MaterialData; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ItemBuilder implements Listener { + + private final ItemStack is; + + public ItemBuilder(final Material mat) { + is = new ItemStack(mat); + } + + public ItemBuilder(final ItemStack is) { + this.is = is; + } + + public ItemBuilder(Material m, int amount) { + this.is = new ItemStack(m, amount); + } + + public ItemBuilder amount(final int amount) { + is.setAmount(amount); + + return this; + } + + public ItemBuilder name(final String name) { + final ItemMeta meta = is.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder lore(final String name) { + final ItemMeta meta = is.getItemMeta(); + List lore = meta.getLore(); + if (lore == null) { + lore = new ArrayList<>(); + } + + lore.add(name); + meta.setLore(lore); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder lore(final List lore) { + List toSet = new ArrayList<>(); + ItemMeta meta = is.getItemMeta(); + + for (String string : lore) { + toSet.add(ChatColor.translateAlternateColorCodes('&', string)); + } + + meta.setLore(toSet); + is.setItemMeta(meta); + return this; + } + + public ItemBuilder durability(final int durability) { + is.setDurability((short) durability); + + return this; + } + + public ItemBuilder owner(String owner) { + if (this.is.getType() == Material.PLAYER_HEAD) { + SkullMeta meta = (SkullMeta) this.is.getItemMeta(); + meta.setOwner(owner); + this.is.setItemMeta(meta); + return this; + } + + throw new IllegalArgumentException("setOwner() only applicable for Skull Item"); + } + + @SuppressWarnings("deprecation") + public ItemBuilder data(final int data) { + is.setData(new MaterialData(is.getType(), (byte) data)); + + return this; + } + + public ItemBuilder enchantment(final Enchantment enchantment, final int level) { + is.addUnsafeEnchantment(enchantment, level); + return this; + } + + public ItemBuilder enchantment(final Enchantment enchantment) { + is.addUnsafeEnchantment(enchantment, 1); + return this; + } + + public ItemBuilder hideFlags() { + final ItemMeta meta = is.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder hideEnchants() { + final ItemMeta meta = is.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder hideUnbreakable() { + final ItemMeta meta = is.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder addUnbreakable() { + final ItemMeta meta = is.getItemMeta(); + meta.setUnbreakable(true); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder type(final Material material) { + is.setType(material); + return this; + } + + public ItemBuilder clearLore() { + final ItemMeta meta = is.getItemMeta(); + meta.setLore(new ArrayList<>()); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder clearEnchantments() { + for (final Enchantment e : is.getEnchantments().keySet()) { + is.removeEnchantment(e); + } + + return this; + } + + public ItemBuilder color(Color color) { + if (is.getType() == Material.LEATHER_BOOTS || is.getType() == Material.LEATHER_CHESTPLATE + || is.getType() == Material.LEATHER_HELMET || is.getType() == Material.LEATHER_LEGGINGS) { + LeatherArmorMeta meta = (LeatherArmorMeta) is.getItemMeta(); + meta.setColor(color); + is.setItemMeta(meta); + + return this; + } else { + throw new IllegalArgumentException("color() only applicable for leather armor!"); + } + } + + public ItemBuilder addEnchantments(Map enchantments) { + this.is.addEnchantments(enchantments); + return this; + } + + public ItemStack build() { + return is; + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/ItemUtil.java b/src/main/java/com/loganmagnan/blockhealth/utils/ItemUtil.java new file mode 100644 index 0000000..96f97c2 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/ItemUtil.java @@ -0,0 +1,162 @@ +package com.loganmagnan.blockhealth.utils; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +public final class ItemUtil { + + private ItemUtil() { + throw new RuntimeException("Cannot instantiate a utility class."); + } + + public static ItemStack createItem(Material material, String name) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + item.setItemMeta(meta); + + return item; + } + + public static ItemStack createItem(Material material, String name, int amount) { + ItemStack item = new ItemStack(material, amount); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + item.setItemMeta(meta); + + return item; + } + + public static ItemStack createItem(Material material, String name, int amount, short damage) { + ItemStack item = new ItemStack(material, amount, damage); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + item.setItemMeta(meta); + + return item; + } + + public static ItemStack createUnbreakableItem(Material material, String name, int amount, short damage) { + ItemStack item = new ItemStack(material, amount, damage); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + item.setItemMeta(meta); + + meta.setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_UNBREAKABLE); + item.setItemMeta(meta); + + return item; + } + + public static ItemStack createNoFlagsItem(Material material, String name, int amount, short damage) { + ItemStack item = new ItemStack(material, amount, damage); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + item.setItemMeta(meta); + + meta.setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); + item.setItemMeta(meta); + + return item; + } + + public static ItemStack createPlayerHead(Material material, String name, String playerHead, int amount, short damage) { + ItemStack item = new ItemStack(material, amount, damage); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + item.setItemMeta(meta); + + meta.setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_UNBREAKABLE); + item.setItemMeta(meta); + + if (item.getType() == Material.PLAYER_HEAD) { + SkullMeta skullMeta = (SkullMeta) item.getItemMeta(); + skullMeta.setOwner(playerHead); + item.setItemMeta(skullMeta); + + return item; + } + + return item; + } + + public static ItemStack setUnbreakable(ItemStack item) { + ItemMeta meta = item.getItemMeta(); + + meta.setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + item.setItemMeta(meta); + + return item; + } + + public static ItemStack renameItem(ItemStack item, String name) { + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + item.setItemMeta(meta); + + return item; + } + + public static ItemStack reloreItem(ItemStack item, String... lores) { + return reloreItem(ReloreType.OVERWRITE, item, lores); + } + + public static ItemStack reEnchantItem(ItemStack itemStack, Enchantment enchantment, int level, boolean b) { + ItemMeta meta = itemStack.getItemMeta(); + + meta.addEnchant(enchantment, level, b); + + itemStack.setItemMeta(meta); + return itemStack; + } + + public static ItemStack reloreItem(ReloreType type, ItemStack item, String... lores) { + ItemMeta meta = item.getItemMeta(); + + List lore = meta.getLore(); + if (lore == null) { + lore = new LinkedList<>(); + } + + switch (type) { + case APPEND: + lore.addAll(Arrays.asList(lores)); + meta.setLore(lore); + break; + case PREPEND: + List nLore = new LinkedList<>(Arrays.asList(lores)); + nLore.addAll(lore); + meta.setLore(nLore); + break; + case OVERWRITE: + meta.setLore(Arrays.asList(lores)); + break; + } + + item.setItemMeta(meta); + return item; + } + + public enum ReloreType { + OVERWRITE, PREPEND, APPEND + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/LocationUtils.java b/src/main/java/com/loganmagnan/blockhealth/utils/LocationUtils.java new file mode 100644 index 0000000..b8d5ea6 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/LocationUtils.java @@ -0,0 +1,34 @@ +package com.loganmagnan.blockhealth.utils; + +import org.bukkit.Location; +import org.bukkit.block.Block; + +import java.util.ArrayList; +import java.util.List; + +public class LocationUtils { + + public static List getBlocks(Location center, int radius) { + return getBlocks(center, radius, radius); + } + + public static List getBlocks(Location center, int radius, int yRadius) { + if (radius < 0) { + return new ArrayList<>(); + } + + int iterations = radius * 2 + 1; + + List blocks = new ArrayList<>(iterations * iterations * iterations); + + for (int x = -radius; x <= radius; x++) { + for (int y = -yRadius; y <= yRadius; y++) { + for (int z = -radius; z <= radius; z++) { + blocks.add(center.getBlock().getRelative(x, y, z)); + } + } + } + + return blocks; + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/MathUtil.java b/src/main/java/com/loganmagnan/blockhealth/utils/MathUtil.java new file mode 100644 index 0000000..f03d48d --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/MathUtil.java @@ -0,0 +1,58 @@ + package com.loganmagnan.blockhealth.utils; + + import java.util.Random; + + public final class MathUtil + { + public static boolean isInteger(String in) { + try { + Integer.parseInt(in); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + public static int randomNumber(int minimo, int maximo) { + Random random = new Random(); + int min = Math.min(maximo, maximo); + int max = Math.max(maximo, maximo); + int maxsize = min - max; + + return random.nextInt(maxsize + 1) + minimo; + } + + public static String convertTicksToMinutes(int ticks) { + long minute = ticks / 1200L; + long second = ticks / 20L - minute * 60L; + + String secondString = Math.round((float)second) + ""; + if (second < 10L) { + secondString = Character.MIN_VALUE + secondString; + } + + String minuteString = Math.round((float)minute) + ""; + if (minute == 0L) { + minuteString = "0"; + } + + return minuteString + ":" + secondString; + } + + public static String convertToRomanNumeral(int number) { + switch (number) { + case 1: + return "I"; + case 2: + return "II"; + } + + return null; + } + + public static double roundToHalves(double d) { + return Math.round(d * 2.0D) / 2.0D; + } + } + + diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/PlayerUtil.java b/src/main/java/com/loganmagnan/blockhealth/utils/PlayerUtil.java new file mode 100644 index 0000000..acdbb37 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/PlayerUtil.java @@ -0,0 +1,43 @@ +package com.loganmagnan.blockhealth.utils; + +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +public class PlayerUtil { + + public static void clearPlayer(Player player) { + player.setHealth(20.0D); + player.setFoodLevel(20); + player.setSaturation(12.8F); + player.setMaximumNoDamageTicks(20); + player.setFireTicks(0); + player.setFallDistance(0.0F); + player.setLevel(0); + player.setExp(0.0F); + player.setWalkSpeed(0.2F); + player.setFlySpeed(0.2F); + player.getInventory().setHeldItemSlot(0); + player.setAllowFlight(false); + player.getInventory().clear(); + player.getInventory().setArmorContents(null); + player.closeInventory(); + player.setGameMode(GameMode.SURVIVAL); + player.getActivePotionEffects().stream().map(PotionEffect::getType).forEach(player::removePotionEffect); + player.updateInventory(); + } + + public static void minusAmount(Player p, ItemStack i, int amount) { + if (i.getAmount() - amount <= 0) { + if (p.getInventory().getItemInHand().equals(i)) { + p.getInventory().setItemInHand(null); + } else { + p.getInventory().removeItem(i); + } + return; + } + i.setAmount(i.getAmount() - amount); + p.updateInventory(); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/TimeUtils.java b/src/main/java/com/loganmagnan/blockhealth/utils/TimeUtils.java new file mode 100644 index 0000000..b32158e --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/TimeUtils.java @@ -0,0 +1,44 @@ +package com.loganmagnan.blockhealth.utils; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.function.Supplier; + +public class TimeUtils { + + private static final ThreadLocal MMSS_BUILDER = ThreadLocal.withInitial((Supplier) StringBuilder::new); + + public static String formatIntoMMSS(int secs) { + final int seconds = secs % 60; + secs -= seconds; + long minutesCount = secs / 60; + final long minutes = minutesCount % 60L; + minutesCount -= minutes; + final long hours = minutesCount / 60L; + final StringBuilder result = MMSS_BUILDER.get(); + result.setLength(0); + if (hours > 0L) { + if (hours < 10L) { + result.append("0"); + } + result.append(hours); + result.append(":"); + } + if (minutes < 10L) { + result.append("0"); + } + result.append(minutes); + result.append(":"); + if (seconds < 10) { + result.append("0"); + } + result.append(seconds); + return result.toString(); + } + + public static String nowDate() { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy hh:mm:ss"); + LocalDateTime now = LocalDateTime.now(); + return dtf.format(now); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/Utils.java b/src/main/java/com/loganmagnan/blockhealth/utils/Utils.java new file mode 100644 index 0000000..a664b9e --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/Utils.java @@ -0,0 +1,42 @@ +package com.loganmagnan.blockhealth.utils; + +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.List; + +public class Utils { + + public static final String scoreboardBar = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "----------------------"; + public static final String chatBar = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "--------------------------------------------"; + + public static String translate(String message) { + return ChatColor.translateAlternateColorCodes('&', message); + } + + public static List translate(List lines) { + List strings = new ArrayList<>(); + for (String line : lines) { + strings.add(ChatColor.translateAlternateColorCodes('&', line)); + } + return strings; + } + + public static List translate(String[] lines) { + List strings = new ArrayList<>(); + for (String line : lines) { + if (line != null) { + strings.add(ChatColor.translateAlternateColorCodes('&', line)); + } + } + return strings; + } + + public static boolean isNumeric(String string) { + return regexNumeric(string).length() == 0; + } + + public static String regexNumeric(String string) { + return string.replaceAll("[0-9]", "").replaceFirst("\\.", ""); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/WorldUtils.java b/src/main/java/com/loganmagnan/blockhealth/utils/WorldUtils.java new file mode 100644 index 0000000..bc006f5 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/WorldUtils.java @@ -0,0 +1,322 @@ + package com.loganmagnan.blockhealth.utils; + + import org.bukkit.*; + import org.bukkit.block.Block; + import org.bukkit.entity.Player; + + import java.util.*; + + + public final class WorldUtils + { + public static String locationToString(Location l) { + return l.getWorld().getName() + "," + l.getBlockX() + "," + l.getBlockY() + "," + l.getBlockZ() + "," + l + .getPitch() + "," + l.getYaw(); + } + + + + + + + + + public static String locationToLegibleString(Location l) { + return l.getWorld().getName() + " (x:" + l.getBlockX() + ", y:" + l.getBlockY() + ", z:" + l.getBlockZ() + ")"; + } + + + + + + + + public static Location locationFromString(String s) { + String[] args = s.split(","); + try { + World world = Bukkit.getWorld(args[0]); + return new Location(world, Integer.parseInt(args[1]) + 0.5D, Integer.parseInt(args[2]), + Integer.parseInt(args[3]) + 0.5D, Float.parseFloat(args[4]), Float.parseFloat(args[5])); + } catch (Exception e) { + return null; + } + } + + public static String chunkToString(Chunk c) { + return c.getWorld().getName() + "," + c.getX() + "," + c.getZ(); + } + + public static Chunk chunkFromString(String s) { + String[] args = s.split(","); + try { + World world = Bukkit.getWorld(args[0]); + return world.getChunkAt(Integer.parseInt(args[1]), Integer.parseInt(args[2])); + } catch (Exception e) { + return null; + } + } + + + + + + + + public static Block getNearestBlockUnder(Location l) { + return l.getWorld().getBlockAt(getNearestLocationUnder(l)); + } + + + public static Location getNearestLocationUnder(Location l) { + Location location = new Location(l.getWorld(), l.getBlockX() + 0.5D, l.getBlockY(), l.getBlockZ() + 0.5D); + while (!location.getBlock().getType().isSolid()) { + location = location.add(0.0D, -1.0D, 0.0D); + if (location.getY() < 0.0D) { + return null; + } + } + return location; + } + + + + + + + + + + + + + public static Block getBlockAboveOrBelow(Block block, Material blockType, byte blockData) { + return getBlockAboveOrBelow(block, blockType, blockData, 1); + } + + + private static Block getBlockAboveOrBelow(Block block, Material blockType, byte blockData, int distance) { + boolean maxHeightReached = (block.getLocation().getBlockY() + distance > block.getWorld().getMaxHeight() - 1); + boolean minHeightReached = (block.getLocation().getBlockY() - distance < 1); + + if (maxHeightReached && minHeightReached) { + return null; + } + + if (!maxHeightReached) { + Block blockAbove = block.getWorld().getBlockAt(block.getLocation().add(0.0D, distance, 0.0D)); + if (blockAbove.getType() == blockType && blockAbove.getData() == blockData) { + return blockAbove; + } + } + + if (!minHeightReached) { + Block blockBelow = block.getWorld().getBlockAt(block.getLocation().subtract(0.0D, distance, 0.0D)); + if (blockBelow.getType() == blockType && blockBelow.getData() == blockData) { + return blockBelow; + } + } + + return getBlockAboveOrBelow(block, blockType, blockData, distance + 1); + } + + public static boolean isEmptyColumn(Location loc) { + return isEmptyColumn(loc.getWorld(), loc.getBlockX(), loc.getBlockZ(), loc.getBlockY()); + } + + public static boolean isEmptyColumn(World world, int x, int z) { + return isEmptyColumn(world, x, z, -1); + } + + public static boolean isEmptyColumn(World world, int x, int z, int yException) { + for (int y = 0; y < world.getMaxHeight(); y++) { + if (yException != y && world.getBlockAt(x, y, z).getType() != Material.AIR) { + return false; + } + } + return true; + } + + + + + + + + + public static Set getNearbyPlayers(Location location, double range) { + double rangeSquared = range * range; + Set nearbyPlayers = new HashSet<>(); + World world = location.getWorld(); + for (Player player : world.getPlayers()) { + if (player != null && player.getGameMode() != GameMode.SPECTATOR && + player.getLocation().distanceSquared(location) <= rangeSquared) { + nearbyPlayers.add(player); + } + } + + return nearbyPlayers; + } + + + + + + + + + public static Player getNearestPlayer(Location location, double maxRange) { + double rangeSquared = maxRange * maxRange; + + Player nearest = null; + double nearestDistSquared = (maxRange <= 0.0D) ? Double.MAX_VALUE : rangeSquared; + + for (Player player : location.getWorld().getPlayers()) { + if (player.getGameMode() != GameMode.SPECTATOR) { + double distSquared = player.getLocation().distanceSquared(location); + if (distSquared < nearestDistSquared) { + nearest = player; + nearestDistSquared = distSquared; + } + } + } + return nearest; + } + + public static Set getPlayersInCuboid(Location origin, double width, double height, double depth) { + if (width < 0.0D) { + origin.setX(origin.getX() + width); + width *= -1.0D; + } + if (height < 0.0D) { + origin.setY(origin.getY() + height); + height *= -1.0D; + } + if (depth < 0.0D) { + origin.setZ(origin.getZ() + depth); + depth *= -1.0D; + } + + Set nearbyPlayers = new HashSet<>(); + World world = origin.getWorld(); + for (Player player : world.getPlayers()) { + if (player.getGameMode() != GameMode.SPECTATOR) { + Location ploc = player.getLocation(); + if (ploc.getX() > origin.getX() && ploc.getX() < origin.getBlockX() + width && + ploc.getY() > origin.getY() && ploc.getY() < origin.getY() + height && + ploc.getZ() > origin.getZ() && ploc.getZ() < origin.getZ() + depth) { + nearbyPlayers.add(player); + } + } + } + + + return nearbyPlayers; + } + + public static List getCircle(Location center, double radius, int amount) { + World world = center.getWorld(); + double increment = 6.283185307179586D / amount; + List locations = new ArrayList<>(); + for (int i = 0; i < amount; i++) { + double angle = i * increment; + double x = center.getX() + radius * Math.cos(angle); + double z = center.getZ() + radius * Math.sin(angle); + locations.add(new Location(world, x, center.getY(), z)); + } + return locations; + } + + public static int compareLocations(Location l1, Location l2) { + if (l1.getY() > l2.getY()) { + return -1; + } + if (l1.getY() < l2.getY()) { + return 1; + } + + if (l1.getX() > l2.getX()) { + return -1; + } + if (l1.getX() < l2.getX()) { + return 1; + } + + return Double.compare(l2.getZ(), l1.getZ()); + } + + + public static List getChunksDiamond(Chunk c, int radius) { + if (radius <= 0) { + return Collections.singletonList(c); + } + + List chunks = new ArrayList<>(); + World world = c.getWorld(); + int ix = c.getX(); + int iz = c.getZ(); + int xmin = ix - radius, xmax = ix + radius; + int x = xmax, z = iz; + for (; x > ix; x--) { + chunks.add(world.getChunkAt(x, z)); + z++; + } + for (; x > xmin; x--) { + chunks.add(world.getChunkAt(x, z)); + z--; + } + for (; x < ix; x++) { + chunks.add(world.getChunkAt(x, z)); + z--; + } + for (; x < xmax; x++) { + chunks.add(world.getChunkAt(x, z)); + z++; + } + return chunks; + } + + public static List getChunksSquare(Chunk c, int radius) { + if (radius <= 0) { + return Collections.singletonList(c); + } + + List chunks = new ArrayList<>(); + World world = c.getWorld(); + int ix = c.getX(); + int iz = c.getZ(); + int xmin = ix - radius, xmax = ix + radius; + int zmin = iz - radius, zmax = iz + radius; + for (int x = xmin; x < xmax; x++) { + chunks.add(world.getChunkAt(x, zmin)); + chunks.add(world.getChunkAt(x, zmax)); + } + for (int z = zmin + 1; z < zmax - 1; z++) { + chunks.add(world.getChunkAt(xmin, z)); + chunks.add(world.getChunkAt(xmax, z)); + } + return chunks; + } + + + public static List getSphere(Location center, double radius) { + radius++; + List sphere = new ArrayList<>(); + int bx = center.getBlockX(); + int by = center.getBlockY(); + int bz = center.getBlockZ(); double x; + for (x = bx - radius; x <= bx + radius; x++) { + double y; for (y = by - radius; y <= by + radius; y++) { + double z; for (z = bz - radius; z <= bz + radius; z++) { + double distance = (bx - x) * (bx - x) + (bz - z) * (bz - z) + (by - y) * (by - y); + if (distance < radius * radius && distance >= (radius - 1.0D) * (radius - 1.0D)) { + sphere.add(new Location(center.getWorld(), x, y, z)); + } + } + } + } + + return sphere; + } + } + + diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/command/BaseCommand.java b/src/main/java/com/loganmagnan/blockhealth/utils/command/BaseCommand.java new file mode 100644 index 0000000..af26942 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/command/BaseCommand.java @@ -0,0 +1,12 @@ +package com.loganmagnan.blockhealth.utils.command; + +import com.loganmagnan.blockhealth.BlockHealth; + +public abstract class BaseCommand { + + public BaseCommand() { + BlockHealth.getInstance().getCommandFramework().registerCommands(this, null); + } + + public abstract void executeAs(CommandArguments command); +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/command/BukkitCommand.java b/src/main/java/com/loganmagnan/blockhealth/utils/command/BukkitCommand.java new file mode 100644 index 0000000..f0df734 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/command/BukkitCommand.java @@ -0,0 +1,82 @@ +package com.loganmagnan.blockhealth.utils.command; + +import org.apache.commons.lang.Validate; +import org.bukkit.command.Command; +import org.bukkit.command.*; +import org.bukkit.plugin.Plugin; + +import java.util.List; + +public class BukkitCommand extends Command { + + protected BukkitCompleter completer; + private Plugin ownerPlugin; + private CommandExecutor executor; + + protected BukkitCommand(String label, CommandExecutor executor, Plugin owner) { + super(label); + this.executor = executor; + this.ownerPlugin = owner; + this.usageMessage = ""; + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + boolean success = false; + + if (!ownerPlugin.isEnabled()) { + return false; + } + + if (!testPermission(sender)) { + return true; + } + + try { + success = executor.onCommand(sender, this, commandLabel, args); + } catch (Throwable ex) { + throw new CommandException("Unhandled exception executing command '" + commandLabel + "' in plugin " + ownerPlugin.getDescription().getFullName(), ex); + } + + if (!success && usageMessage.length() > 0) { + for (String line : usageMessage.replace("", commandLabel).split("\n")) { + sender.sendMessage(line); + } + } + + return success; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws CommandException, IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + List completions = null; + try { + if (completer != null) { + completions = completer.onTabComplete(sender, this, alias, args); + } + if (completions == null && executor instanceof TabCompleter) { + completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args); + } + } catch (Throwable ex) { + StringBuilder message = new StringBuilder(); + + message.append("Unhandled exception during tab completion for command '/").append(alias).append(' '); + for (String arg : args) { + message.append(arg).append(' '); + } + message.deleteCharAt(message.length() - 1).append("' in plugin ").append(ownerPlugin.getDescription().getFullName()); + + throw new CommandException(message.toString(), ex); + } + + if (completions == null) { + return super.tabComplete(sender, alias, args); + } + + return completions; + } +} \ No newline at end of file diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/command/BukkitCompleter.java b/src/main/java/com/loganmagnan/blockhealth/utils/command/BukkitCompleter.java new file mode 100644 index 0000000..4e50aa9 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/command/BukkitCompleter.java @@ -0,0 +1,48 @@ +package com.loganmagnan.blockhealth.utils.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class BukkitCompleter implements TabCompleter { + + private Map> completers = new HashMap<>(); + + public void addCompleter(String label, Method m, Object obj) { + completers.put(label, new AbstractMap.SimpleEntry<>(m, obj)); + } + + @SuppressWarnings("unchecked") + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + for (int i = args.length; i >= 0; i--) { + StringBuffer buffer = new StringBuffer(); + buffer.append(label.toLowerCase()); + for (int x = 0; x < i; x++) { + if (!args[x].equals("") && !args[x].equals(" ")) { + buffer.append("." + args[x].toLowerCase()); + } + } + + String cmdLabel = buffer.toString(); + if (completers.containsKey(cmdLabel)) { + Entry entry = completers.get(cmdLabel); + try { + return (List) entry.getKey().invoke(entry.getValue(), new CommandArguments(sender, command, label, args, cmdLabel.split("\\.").length - 1)); + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/command/Command.java b/src/main/java/com/loganmagnan/blockhealth/utils/command/Command.java new file mode 100644 index 0000000..4cb8425 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/command/Command.java @@ -0,0 +1,23 @@ +package com.loganmagnan.blockhealth.utils.command; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Command { + + public String name(); + + public String permission() default ""; + + public String[] aliases() default {}; + + public String description() default ""; + + public String usage() default ""; + + public boolean inGameOnly() default true; +} \ No newline at end of file diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/command/CommandArguments.java b/src/main/java/com/loganmagnan/blockhealth/utils/command/CommandArguments.java new file mode 100644 index 0000000..e736d5e --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/command/CommandArguments.java @@ -0,0 +1,52 @@ +package com.loganmagnan.blockhealth.utils.command; + +import lombok.Getter; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@Getter +public class CommandArguments { + + private CommandSender sender; + private org.bukkit.command.Command command; + private String label; + private String[] args; + + protected CommandArguments(CommandSender sender, org.bukkit.command.Command command, String label, String[] args, int subCommand) { + String[] modArgs = new String[args.length - subCommand]; + for (int i = 0; i < args.length - subCommand; i++) { + modArgs[i] = args[i + subCommand]; + } + + StringBuffer buffer = new StringBuffer(); + buffer.append(label); + for (int x = 0; x < subCommand; x++) { + buffer.append("." + args[x]); + } + String cmdLabel = buffer.toString(); + this.sender = sender; + this.command = command; + this.label = cmdLabel; + this.args = modArgs; + } + + public String getArgs(int index) { + return args[index]; + } + + public int length() { + return args.length; + } + + public boolean isPlayer() { + return sender instanceof Player; + } + + public Player getPlayer() { + if (sender instanceof Player) { + return (Player) sender; + } else { + return null; + } + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/command/CommandFramework.java b/src/main/java/com/loganmagnan/blockhealth/utils/command/CommandFramework.java new file mode 100644 index 0000000..600da32 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/command/CommandFramework.java @@ -0,0 +1,172 @@ +package com.loganmagnan.blockhealth.utils.command; + +import com.loganmagnan.blockhealth.BlockHealth; +import com.loganmagnan.blockhealth.utils.Utils; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandMap; +import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.entity.Player; +import org.bukkit.plugin.SimplePluginManager; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class CommandFramework implements CommandExecutor { + + private BlockHealth plugin; + private Map> commandMap = new HashMap<>(); + private CommandMap map; + + public CommandFramework(BlockHealth plugin) { + this.plugin = plugin; + + if (plugin.getServer().getPluginManager() instanceof SimplePluginManager) { + SimplePluginManager manager = (SimplePluginManager) plugin.getServer().getPluginManager(); + try { + Field field = SimplePluginManager.class.getDeclaredField("commandMap"); + field.setAccessible(true); + map = (CommandMap) field.get(manager); + } catch (IllegalArgumentException | SecurityException | NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + } + } + + @Override + public boolean onCommand(CommandSender sender, org.bukkit.command.Command cmd, String label, String[] args) { + return handleCommand(sender, cmd, label, args); + } + + public boolean handleCommand(CommandSender sender, org.bukkit.command.Command cmd, String label, String[] args) { + for (int i = args.length; i >= 0; i--) { + StringBuffer buffer = new StringBuffer(); + buffer.append(label.toLowerCase()); + for (int x = 0; x < i; x++) { + buffer.append("." + args[x].toLowerCase()); + } + + String cmdLabel = buffer.toString(); + if (commandMap.containsKey(cmdLabel)) { + Method method = commandMap.get(cmdLabel).getKey(); + Object methodObject = commandMap.get(cmdLabel).getValue(); + Command command = method.getAnnotation(Command.class); + if (!command.permission().equals("") && (!sender.hasPermission(command.permission()))) { + sender.sendMessage(Utils.translate("&cYou don't have permissions to perform this.")); + return true; + } + if (command.inGameOnly() && !(sender instanceof Player)) { + sender.sendMessage(Utils.translate("&cThis command can only be executed in game.")); + return true; + } + + try { + method.invoke(methodObject, new CommandArguments(sender, cmd, label, args, cmdLabel.split("\\.").length - 1)); + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + return true; + } + } + + defaultCommand(new CommandArguments(sender, cmd, label, args, 0)); + return true; + } + + public void registerCommands(Object obj, List aliases) { + for (Method method : obj.getClass().getMethods()) { + if (method.getAnnotation(Command.class) != null) { + Command command = method.getAnnotation(Command.class); + if (method.getParameterTypes().length > 1 || method.getParameterTypes()[0] != CommandArguments.class) { + System.out.println("Unable to register command " + method.getName() + ". Unexpected method arguments"); + continue; + } + + registerCommand(command, command.name(), method, obj); + for (String alias : command.aliases()) { + registerCommand(command, alias, method, obj); + } + if (aliases != null) { + for (String alias : aliases) { + registerCommand(command, alias, method, obj); + } + } + } else if (method.getAnnotation(Completer.class) != null) { + Completer comp = method.getAnnotation(Completer.class); + if (method.getParameterTypes().length > 1 || method.getParameterTypes().length == 0 || method.getParameterTypes()[0] != CommandArguments.class) { + System.out.println("Unable to register tab completer " + method.getName() + ". Unexpected method arguments"); + continue; + } + if (method.getReturnType() != List.class) { + System.out.println("Unable to register tab completer " + method.getName() + ". Unexpected return type"); + continue; + } + + registerCompleter(comp.name(), method, obj); + for (String alias : comp.aliases()) { + registerCompleter(alias, method, obj); + } + } + } + } + + public void registerCommand(Command command, String label, Method m, Object obj) { + commandMap.put(label.toLowerCase(), new AbstractMap.SimpleEntry<>(m, obj)); + commandMap.put(this.plugin.getName() + ':' + label.toLowerCase(), new AbstractMap.SimpleEntry<>(m, obj)); + + String cmdLabel = label.replace(".", ",").split(",")[0].toLowerCase(); + if (map.getCommand(cmdLabel) == null) { + org.bukkit.command.Command cmd = new BukkitCommand(cmdLabel, this, plugin); + map.register(plugin.getName(), cmd); + } + if (!command.description().equalsIgnoreCase("") && cmdLabel.equals(label)) { + map.getCommand(cmdLabel).setDescription(command.description()); + } + if (!command.usage().equalsIgnoreCase("") && cmdLabel.equals(label)) { + map.getCommand(cmdLabel).setUsage(command.usage()); + } + } + + public void registerCompleter(String label, Method m, Object obj) { + String cmdLabel = label.replace(".", ",").split(",")[0].toLowerCase(); + if (map.getCommand(cmdLabel) == null) { + org.bukkit.command.Command command = new BukkitCommand(cmdLabel, this, plugin); + map.register(plugin.getName(), command); + } + if (map.getCommand(cmdLabel) instanceof BukkitCommand) { + BukkitCommand command = (BukkitCommand) map.getCommand(cmdLabel); + if (command.completer == null) { + command.completer = new BukkitCompleter(); + } + command.completer.addCompleter(label, m, obj); + } else if (map.getCommand(cmdLabel) instanceof PluginCommand) { + try { + Object command = map.getCommand(cmdLabel); + Field field = command.getClass().getDeclaredField("completer"); + field.setAccessible(true); + if (field.get(command) == null) { + BukkitCompleter completer = new BukkitCompleter(); + completer.addCompleter(label, m, obj); + field.set(command, completer); + } else if (field.get(command) instanceof BukkitCompleter) { + BukkitCompleter completer = (BukkitCompleter) field.get(command); + completer.addCompleter(label, m, obj); + } else { + System.out.println("Unable to register tab completer " + m.getName() + ". A tab completer is already registered for that command!"); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + private void defaultCommand(CommandArguments args) { + args.getSender().sendMessage(args.getLabel() + " is not handled! Oh noes!"); + } +} \ No newline at end of file diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/command/Completer.java b/src/main/java/com/loganmagnan/blockhealth/utils/command/Completer.java new file mode 100644 index 0000000..f9817ca --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/command/Completer.java @@ -0,0 +1,15 @@ +package com.loganmagnan.blockhealth.utils.command; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Completer { + + String name(); + + String[] aliases() default {}; +} \ No newline at end of file diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/config/ConfigCursor.java b/src/main/java/com/loganmagnan/blockhealth/utils/config/ConfigCursor.java new file mode 100644 index 0000000..4c25a48 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/config/ConfigCursor.java @@ -0,0 +1,88 @@ +package com.loganmagnan.blockhealth.utils.config; + +import org.bukkit.Bukkit; +import org.bukkit.World; + +import java.util.List; +import java.util.Set; +import java.util.UUID; + +public class ConfigCursor { + + private final FileConfig fileConfig; + + private String path; + + public ConfigCursor(FileConfig fileConfig, String path) { + this.fileConfig = fileConfig; + this.path = path; + } + + public FileConfig getFileConfig() { + return this.fileConfig; + } + + public String getPath() { + return this.path; + } + + public void setPath(String path) { + this.path = path; + } + + public boolean exists() { + return exists(null); + } + + public boolean exists(String path) { + return this.fileConfig.getConfig().contains(this.path + ((path == null) ? "" : ("." + path))); + } + + public Set getKeys() { + return getKeys(null); + } + + public Set getKeys(String path) { + return this.fileConfig.getConfig().getConfigurationSection(this.path + ((path == null) ? "" : ("." + path))).getKeys(false); + } + + public boolean getBoolean(String path) { + return this.fileConfig.getConfig().getBoolean(((this.path == null) ? "" : (this.path + ".")) + "." + path); + } + + public int getInt(String path) { + return this.fileConfig.getConfig().getInt(((this.path == null) ? "" : (this.path + ".")) + "." + path); + } + + public long getLong(String path) { + return this.fileConfig.getConfig().getLong(((this.path == null) ? "" : (this.path + ".")) + "." + path); + } + + public String getString(String path) { + return this.fileConfig.getConfig().getString(((this.path == null) ? "" : (this.path + ".")) + "." + path); + } + + public List getStringList(String path) { + return this.fileConfig.getConfig().getStringList(((this.path == null) ? "" : (this.path + ".")) + "." + path); + } + + public UUID getUuid(String path) { + return UUID.fromString(this.fileConfig.getConfig().getString(this.path + "." + path)); + } + + public World getWorld(String path) { + return Bukkit.getWorld(this.fileConfig.getConfig().getString(this.path + "." + path)); + } + + public void set(Object value) { + set(null, value); + } + + public void set(String path, Object value) { + this.fileConfig.getConfig().set(this.path + ((path == null) ? "" : ("." + path)), value); + } + + public void save() { + this.fileConfig.save(); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/config/FileConfig.java b/src/main/java/com/loganmagnan/blockhealth/utils/config/FileConfig.java new file mode 100644 index 0000000..49d4ee1 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/config/FileConfig.java @@ -0,0 +1,50 @@ +package com.loganmagnan.blockhealth.utils.config; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; + +public class FileConfig { + + private File file; + + private FileConfiguration config; + + public File getFile() { + return this.file; + } + + public FileConfiguration getConfig() { + return this.config; + } + + public FileConfig(JavaPlugin plugin, String fileName) { + this.file = new File(plugin.getDataFolder(), fileName); + if (!this.file.exists()) { + this.file.getParentFile().mkdirs(); + if (plugin.getResource(fileName) == null) { + try { + this.file.createNewFile(); + } catch (IOException e) { + plugin.getLogger().severe("Failed to create new file " + fileName); + } + } else { + plugin.saveResource(fileName, false); + } + } + this.config = YamlConfiguration.loadConfiguration(this.file); + } + + public void save() { + try { + this.config.save(this.file); + } catch (IOException e) { + Bukkit.getLogger().severe("Could not save config file " + this.file.toString()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/config/file/Config.java b/src/main/java/com/loganmagnan/blockhealth/utils/config/file/Config.java new file mode 100644 index 0000000..5031e94 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/config/file/Config.java @@ -0,0 +1,39 @@ +package com.loganmagnan.blockhealth.utils.config.file; + +import lombok.Getter; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; + +@Getter +public class Config { + + private final FileConfiguration config; + private final File configFile; + protected boolean wasCreated; + + public Config(String name, JavaPlugin plugin) { + this.configFile = new File(plugin.getDataFolder() + "/" + name + ".yml"); + if (!this.configFile.exists()) { + try { + this.configFile.getParentFile().mkdirs(); + this.configFile.createNewFile(); + this.wasCreated = true; + } catch (IOException e) { + e.printStackTrace(); + } + } + this.config = YamlConfiguration.loadConfiguration(this.configFile); + } + + public void save() { + try { + this.config.save(configFile); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/config/file/ConfigFile.java b/src/main/java/com/loganmagnan/blockhealth/utils/config/file/ConfigFile.java new file mode 100644 index 0000000..8f6d34b --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/config/file/ConfigFile.java @@ -0,0 +1,103 @@ +package com.loganmagnan.blockhealth.utils.config.file; + +import lombok.Getter; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ConfigFile { + + @Getter private File file; + @Getter private YamlConfiguration configuration; + + public ConfigFile(JavaPlugin plugin, String name) { + file = new File(plugin.getDataFolder(), name + ".yml"); + + if (!file.getParentFile().exists()) { + file.getParentFile().mkdir(); + } + + plugin.saveResource(name + ".yml", false); + + configuration = YamlConfiguration.loadConfiguration(file); + } + + public double getDouble(String path) { + if (configuration.contains(path)) { + return configuration.getDouble(path); + } + return 0; + } + + public int getInt(String path) { + if (configuration.contains(path)) { + return configuration.getInt(path); + } + return 0; + } + + public boolean getBoolean(String path) { + if (configuration.contains(path)) { + return configuration.getBoolean(path); + } + return false; + } + + public String getString(String path) { + if (configuration.contains(path)) { + return ChatColor.translateAlternateColorCodes('&', configuration.getString(path)); + } + return "ERROR: STRING NOT FOUND"; + } + + public String getString(String path, String callback, boolean colorize) { + if (configuration.contains(path)) { + if (colorize) { + return ChatColor.translateAlternateColorCodes('&', configuration.getString(path)); + } else { + return configuration.getString(path); + } + } + return callback; + } + + public List getReversedStringList(String path) { + List list = getStringList(path); + if (list != null) { + int size = list.size(); + List toReturn = new ArrayList<>(); + for (int i = size - 1; i >= 0; i--) { + toReturn.add(list.get(i)); + } + return toReturn; + } + return Arrays.asList("ERROR: STRING LIST NOT FOUND!"); + } + + public List getStringList(String path) { + if (configuration.contains(path)) { + ArrayList strings = new ArrayList<>(); + for (String string : configuration.getStringList(path)) { + strings.add(ChatColor.translateAlternateColorCodes('&', string)); + } + return strings; + } + return Arrays.asList("ERROR: STRING LIST NOT FOUND!"); + } + + public List getStringListOrDefault(String path, List toReturn) { + if (configuration.contains(path)) { + ArrayList strings = new ArrayList<>(); + for (String string : configuration.getStringList(path)) { + strings.add(ChatColor.translateAlternateColorCodes('&', string)); + } + return strings; + } + return toReturn; + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/Cuboid.java b/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/Cuboid.java new file mode 100644 index 0000000..3b02b12 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/Cuboid.java @@ -0,0 +1,43 @@ +package com.loganmagnan.blockhealth.utils.cuboid; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +public class Cuboid { + + private final int xMin; + private final int xMax; + + private final int yMin; + private final int yMax; + + private final int zMin; + private final int zMax; + + private final World world; + + public Cuboid(final Location point1, final Location point2) { + this.xMin = Math.min(point1.getBlockX(), point2.getBlockX()); + this.xMax = Math.max(point1.getBlockX(), point2.getBlockX()); + this.yMin = Math.min(point1.getBlockY(), point2.getBlockY()); + this.yMax = Math.max(point1.getBlockY(), point2.getBlockY()); + this.zMin = Math.min(point1.getBlockZ(), point2.getBlockZ()); + this.zMax = Math.max(point1.getBlockZ(), point2.getBlockZ()); + + this.world = point1.getWorld(); + } + + private boolean contains(World world, int x, int y, int z) { + return world.getName().equals(this.world.getName()) && x >= xMin && x <= xMax && y >= yMin && y <= yMax && z >= zMin && z <= zMax; + } + + private boolean contains(Location loc) { + return this.contains(loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + + public boolean isInside(Player player) { + return this.contains(player.getLocation()); + } +} \ No newline at end of file diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidBlockIterator.java b/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidBlockIterator.java new file mode 100644 index 0000000..1c8570d --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidBlockIterator.java @@ -0,0 +1,97 @@ +package com.loganmagnan.blockhealth.utils.cuboid; + +import org.bukkit.World; +import org.bukkit.block.Block; + +import java.util.Iterator; + +public class CuboidBlockIterator implements Iterator { + + private World world; + private int baseX; + private int baseY; + private int baseZ; + private int sizeX; + private int sizeY; + private int sizeZ; + private int x; + private int y; + private int z; + + CuboidBlockIterator(World world, int x1, int y1, int z1, int x2, int y2, int z2) { + this.world = world; + this.baseX = x1; + this.baseY = y1; + this.baseZ = z1; + this.sizeX = Math.abs(x2 - x1) + 1; + this.sizeY = Math.abs(y2 - y1) + 1; + this.sizeZ = Math.abs(z2 - z1) + 1; + this.z = 0; + this.y = 0; + this.x = 0; + } + + @Override + public boolean hasNext() { + return this.x < this.sizeX && this.y < this.sizeY && this.z < this.sizeZ; + } + + @Override + public Block next() { + Block block = this.world.getBlockAt(this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z); + if (++this.x >= this.sizeX) { + this.x = 0; + if (++this.y >= this.sizeY) { + this.y = 0; + ++this.z; + } + } + return block; + } + + @Override + public void remove() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public World getWorld() { + return this.world; + } + + public int getBaseX() { + return this.baseX; + } + + public int getBaseY() { + return this.baseY; + } + + public int getBaseZ() { + return this.baseZ; + } + + public int getSizeX() { + return this.sizeX; + } + + public int getSizeY() { + return this.sizeY; + } + + public int getSizeZ() { + return this.sizeZ; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + public int getZ() { + return this.z; + } +} + diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidDirection.java b/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidDirection.java new file mode 100644 index 0000000..6f011ec --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidDirection.java @@ -0,0 +1,46 @@ +package com.loganmagnan.blockhealth.utils.cuboid; + +public enum CuboidDirection { + + NORTH, EAST, SOUTH, WEST, + UP, DOWN, HORIZONTAL, VERTICAL, BOTH, + UNKNOWN; + + private CuboidDirection() { + + } + + public CuboidDirection opposite() { + switch (this) { + case NORTH: { + return SOUTH; + } + case EAST: { + return WEST; + } + case SOUTH: { + return NORTH; + } + case WEST: { + return EAST; + } + case HORIZONTAL: { + return VERTICAL; + } + case VERTICAL: { + return HORIZONTAL; + } + case UP: { + return DOWN; + } + case DOWN: { + return UP; + } + case BOTH: { + return BOTH; + } + } + return UNKNOWN; + } +} + diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidLocationIterator.java b/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidLocationIterator.java new file mode 100644 index 0000000..994b301 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/cuboid/CuboidLocationIterator.java @@ -0,0 +1,97 @@ +package com.loganmagnan.blockhealth.utils.cuboid; + +import org.bukkit.Location; +import org.bukkit.World; + +import java.util.Iterator; + +public class CuboidLocationIterator implements Iterator { + + private World world; + private int baseX; + private int baseY; + private int baseZ; + private int sizeX; + private int sizeY; + private int sizeZ; + private int x; + private int y; + private int z; + + CuboidLocationIterator(World world, int x1, int y1, int z1, int x2, int y2, int z2) { + this.world = world; + this.baseX = x1; + this.baseY = y1; + this.baseZ = z1; + this.sizeX = Math.abs(x2 - x1) + 1; + this.sizeY = Math.abs(y2 - y1) + 1; + this.sizeZ = Math.abs(z2 - z1) + 1; + this.z = 0; + this.y = 0; + this.x = 0; + } + + @Override + public boolean hasNext() { + return this.x < this.sizeX && this.y < this.sizeY && this.z < this.sizeZ; + } + + @Override + public Location next() { + Location location = new Location(this.world, this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z); + if (++this.x >= this.sizeX) { + this.x = 0; + if (++this.y >= this.sizeY) { + this.y = 0; + ++this.z; + } + } + return location; + } + + @Override + public void remove() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public World getWorld() { + return this.world; + } + + public int getBaseX() { + return this.baseX; + } + + public int getBaseY() { + return this.baseY; + } + + public int getBaseZ() { + return this.baseZ; + } + + public int getSizeX() { + return this.sizeX; + } + + public int getSizeY() { + return this.sizeY; + } + + public int getSizeZ() { + return this.sizeZ; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + public int getZ() { + return this.z; + } +} + diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/ItemStackButton.java b/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/ItemStackButton.java new file mode 100644 index 0000000..4e99bea --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/ItemStackButton.java @@ -0,0 +1,29 @@ +package com.loganmagnan.blockhealth.utils.menusystem; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import com.loganmagnan.blockhealth.utils.ItemBuilder; +import com.loganmagnan.blockhealth.utils.Utils; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@RequiredArgsConstructor +public class ItemStackButton { + + private String name; + private List lore; + private Material material; + private int data; + private int amount; + + public ItemStack makeItemStack() { + return new ItemBuilder(this.material).name(Utils.translate(this.name)).lore(Utils.translate(this.lore)).durability(this.data).amount(this.amount).build(); + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/Menu.java b/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/Menu.java new file mode 100644 index 0000000..c1897ce --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/Menu.java @@ -0,0 +1,64 @@ +package com.loganmagnan.blockhealth.utils.menusystem; + +import com.loganmagnan.blockhealth.utils.ItemBuilder; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; + +public abstract class Menu implements InventoryHolder { + + protected PlayerMenuUtil playerMenuUtil; + protected Inventory inventory; + protected ItemStack FILLER_GLASS = new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE).durability(7).name("").build(); + + public Menu(PlayerMenuUtil playerMenuUtil) { + this.playerMenuUtil = playerMenuUtil; + } + + public abstract String getMenuName(); + + public abstract int getSlots(); + + public abstract void handleMenu(InventoryClickEvent event); + + public abstract void setMenuItems(Player player); + + public void open(Player player) { + inventory = Bukkit.createInventory(this, getSlots(), getMenuName()); + + this.setMenuItems(player); + + playerMenuUtil.getOwner().openInventory(inventory); + } + + @Override + public Inventory getInventory() { + return inventory; + } + + public void setFillerGlass(){ + for (int i = 0; i < this.getSlots(); i++) { + if (this.inventory.getItem(i) == null){ + this.inventory.setItem(i, this.FILLER_GLASS); + } + } + } + + public ItemStack makeItemStack(Material material, String displayName, String[] lore) { + ItemStack itemStack = new ItemStack(material); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(displayName); + + itemMeta.setLore(Arrays.asList(lore)); + itemStack.setItemMeta(itemMeta); + + return itemStack; + } +} diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/PaginatedMenu.java b/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/PaginatedMenu.java new file mode 100644 index 0000000..7967440 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/PaginatedMenu.java @@ -0,0 +1,62 @@ +package com.loganmagnan.blockhealth.utils.menusystem; + +import com.loganmagnan.blockhealth.utils.Utils; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public abstract class PaginatedMenu extends Menu { + + protected int page = 0; + protected int maxItemsPerPage = 28; + protected int index = 0; + + public PaginatedMenu(PlayerMenuUtil playerMenuUtil) { + super(playerMenuUtil); + } + + public void addMenuBorder() { + ItemStack previousPageItemStack = new ItemStack(Material.OAK_BUTTON, 1); + + ItemMeta previousPageItemMeta = previousPageItemStack.getItemMeta(); + previousPageItemMeta.setDisplayName(Utils.translate("&ePrevious page")); + + previousPageItemStack.setItemMeta(previousPageItemMeta); + + this.inventory.setItem(48, previousPageItemStack); + this.inventory.setItem(49, makeItemStack(Material.BARRIER, ChatColor.DARK_RED + "Close", new String[]{""})); + + ItemStack nextPageItemStack = new ItemStack(Material.STONE_BUTTON, 1); + + ItemMeta nextPageItemMeta = nextPageItemStack.getItemMeta(); + nextPageItemMeta.setDisplayName(Utils.translate("&eNext page")); + + nextPageItemStack.setItemMeta(nextPageItemMeta); + + this.inventory.setItem(50, nextPageItemStack); + + for (int i = 0; i < 10; i++) { + if (this.inventory.getItem(i) == null) { + this.inventory.setItem(i, this.FILLER_GLASS); + } + } + + this.inventory.setItem(17, this.FILLER_GLASS); + this.inventory.setItem(18, this.FILLER_GLASS); + this.inventory.setItem(26, this.FILLER_GLASS); + this.inventory.setItem(27, this.FILLER_GLASS); + this.inventory.setItem(35, this.FILLER_GLASS); + this.inventory.setItem(36, this.FILLER_GLASS); + + for (int i = 44; i < 54; i++) { + if (this.inventory.getItem(i) == null) { + this.inventory.setItem(i, this.FILLER_GLASS); + } + } + } + + public int getMaxItemsPerPage() { + return maxItemsPerPage; + } +} \ No newline at end of file diff --git a/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/PlayerMenuUtil.java b/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/PlayerMenuUtil.java new file mode 100644 index 0000000..0245708 --- /dev/null +++ b/src/main/java/com/loganmagnan/blockhealth/utils/menusystem/PlayerMenuUtil.java @@ -0,0 +1,20 @@ +package com.loganmagnan.blockhealth.utils.menusystem; + +import org.bukkit.entity.Player; + +public class PlayerMenuUtil { + + private Player owner; + + public PlayerMenuUtil(Player owner) { + this.owner = owner; + } + + public Player getOwner() { + return owner; + } + + public void setOwner(Player owner) { + this.owner = owner; + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..1abaf94 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,13 @@ +BLOCKS: + GRASS_BLOCK: + HEALTH: 100 + MINIMUM-DAMAGE-AMOUNT-PER-BREAK: 1 + MAXIMUM-DAMAGE-AMOUNT-PER-BREAK: 5 + STONE: + HEALTH: 100 + MINIMUM-DAMAGE-AMOUNT-PER-BREAK: 1 + MAXIMUM-DAMAGE-AMOUNT-PER-BREAK: 5 + +DEFAULT-BLOCK-HEALTH: 20 +DEFAULT-MINIMUM-DAMAGE-AMOUNT-PER-BREAK: 1 +DEFAULT-MAXIMUM-DAMAGE-AMOUNT-PER-BREAK: 5 \ No newline at end of file diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..53c7511 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,6 @@ +name: BlockHealth +version: 1.0 +author: Trixkz +api-version: 1.13 +depend: [DecentHolograms] +main: com.loganmagnan.blockhealth.BlockHealth \ No newline at end of file