diff --git a/src/main/java/lol/hyper/toolstats/ToolStats.java b/src/main/java/lol/hyper/toolstats/ToolStats.java index 4070d34..c2fa7e4 100644 --- a/src/main/java/lol/hyper/toolstats/ToolStats.java +++ b/src/main/java/lol/hyper/toolstats/ToolStats.java @@ -21,6 +21,7 @@ import lol.hyper.githubreleaseapi.GitHubRelease; import lol.hyper.githubreleaseapi.GitHubReleaseAPI; import lol.hyper.toolstats.commands.CommandToolStats; import lol.hyper.toolstats.events.*; +import lol.hyper.toolstats.tools.HashMaker; import lol.hyper.toolstats.tools.ItemLore; import lol.hyper.toolstats.tools.NumberFormat; import net.kyori.adventure.platform.bukkit.BukkitAudiences; @@ -29,7 +30,6 @@ import org.bukkit.*; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import space.arim.morepaperlib.MorePaperLib; @@ -60,6 +60,10 @@ public final class ToolStats extends JavaPlugin { * Stores how many blocks were mined. */ public final NamespacedKey genericMined = new NamespacedKey(this, "generic-mined"); + /** + * Stores how many crops were harvested. + */ + public final NamespacedKey cropsHarvested = new NamespacedKey(this, "crops-mined"); /** * Stores how many fish were caught. */ @@ -80,6 +84,10 @@ public final class ToolStats extends JavaPlugin { * Key for tracking new elytras that spawn. */ public final NamespacedKey newElytra = new NamespacedKey(this, "new"); + /** + * Key for item has. + */ + public final NamespacedKey hash = new NamespacedKey(this, "hash"); /** * Stores how an item was created. * 0 = crafted. @@ -115,6 +123,7 @@ public final class ToolStats extends JavaPlugin { private BukkitAudiences adventure; public MorePaperLib morePaperLib; + public HashMaker hashMaker; @Override @@ -126,6 +135,7 @@ public final class ToolStats extends JavaPlugin { logger.info("Copying default config!"); } loadConfig(); + hashMaker = new HashMaker(this); blocksMined = new BlocksMined(this); craftItem = new CraftItem(this); chunkPopulate = new ChunkPopulate(this); @@ -198,12 +208,12 @@ public final class ToolStats extends JavaPlugin { /** * Checks the config to see if we want to show lore on certain items. * - * @param itemStack The item to check. + * @param material The item type to check. * @param configName The config we are checking under. * @return If we want to allow lore or not. */ - public boolean checkConfig(ItemStack itemStack, String configName) { - String itemName = itemStack.getType().toString().toLowerCase(); + public boolean checkConfig(Material material, String configName) { + String itemName = material.toString().toLowerCase(); String itemType = null; if (itemName.contains("bow") || itemName.contains("shears") || itemName.contains("trident")) { if (itemName.contains("bow")) { @@ -301,6 +311,9 @@ public final class ToolStats extends JavaPlugin { if (lore.contains("{fish}")) { lore = lore.replace("{fish}", ""); } + if (lore.contains("{crops}")) { + lore = lore.replace("{crops}", ""); + } } return lore; } diff --git a/src/main/java/lol/hyper/toolstats/commands/CommandToolStats.java b/src/main/java/lol/hyper/toolstats/commands/CommandToolStats.java index 00539ec..2d25178 100644 --- a/src/main/java/lol/hyper/toolstats/commands/CommandToolStats.java +++ b/src/main/java/lol/hyper/toolstats/commands/CommandToolStats.java @@ -158,7 +158,7 @@ public class CommandToolStats implements TabExecutor { } } - if (toolStats.checkConfig(original, "created-by")) { + if (toolStats.checkConfig(original.getType(), "created-by")) { if (container.has(toolStats.genericOwner, new UUIDDataType())) { container.set(toolStats.genericOwner, new UUIDDataType(), player.getUniqueId()); // show how the item was created based on the previous lore @@ -186,7 +186,7 @@ public class CommandToolStats implements TabExecutor { } } } - if (toolStats.checkConfig(original, "created-date")) { + if (toolStats.checkConfig(original.getType(), "created-date")) { if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) { Long time = container.get(toolStats.timeCreated, PersistentDataType.LONG); if (time != null) { @@ -216,7 +216,7 @@ public class CommandToolStats implements TabExecutor { } } } - if (toolStats.checkConfig(original, "player-kills")) { + if (toolStats.checkConfig(original.getType(), "player-kills")) { if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) { Integer kills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER); if (kills != null) { @@ -224,7 +224,7 @@ public class CommandToolStats implements TabExecutor { } } } - if (toolStats.checkConfig(original, "mob-kills")) { + if (toolStats.checkConfig(original.getType(), "mob-kills")) { if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) { Integer kills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER); if (kills != null) { @@ -232,7 +232,15 @@ public class CommandToolStats implements TabExecutor { } } } - if (toolStats.checkConfig(original, "blocks-mined")) { + if (toolStats.checkConfig(original.getType(), "blocks-mined")) { + if (original.getType().toString().toLowerCase(Locale.ROOT).contains("hoe")) { + if (container.has(toolStats.cropsHarvested, PersistentDataType.INTEGER)) { + Integer crops = container.get(toolStats.cropsHarvested, PersistentDataType.INTEGER); + if (crops != null) { + lore.add(toolStats.getLoreFromConfig("crops-harvested", true).replace("{crops}", toolStats.numberFormat.formatInt(crops))); + } + } + } if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) { Integer blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER); if (blocksMined != null) { diff --git a/src/main/java/lol/hyper/toolstats/events/BlocksMined.java b/src/main/java/lol/hyper/toolstats/events/BlocksMined.java index bbe404c..5f076d5 100644 --- a/src/main/java/lol/hyper/toolstats/events/BlocksMined.java +++ b/src/main/java/lol/hyper/toolstats/events/BlocksMined.java @@ -19,7 +19,10 @@ package lol.hyper.toolstats.events; import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.tools.ItemChecker; +import lol.hyper.toolstats.tools.UUIDDataType; import org.bukkit.GameMode; +import org.bukkit.block.Block; +import org.bukkit.block.data.Ageable; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -32,6 +35,8 @@ import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import java.util.List; +import java.util.Locale; +import java.util.UUID; public class BlocksMined implements Listener { @@ -50,15 +55,23 @@ public class BlocksMined implements Listener { if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { return; } - // if the player mines something with their fist PlayerInventory inventory = player.getInventory(); ItemStack heldItem = inventory.getItemInMainHand(); + Block block = event.getBlock(); // only check certain items if (!ItemChecker.isMineTool(heldItem.getType())) { return; } - // update the blocks mined - updateBlocksMined(heldItem); + + if (heldItem.getType().toString().toLowerCase(Locale.ROOT).contains("hoe")) { + // player is breaking crops with a hoe + if (block.getBlockData() instanceof Ageable) { + updateCropsMined(heldItem, (Ageable) block.getBlockData()); + } + } else { + // update the blocks mined + updateBlocksMined(heldItem); + } } private void updateBlocksMined(ItemStack playerTool) { @@ -87,7 +100,44 @@ public class BlocksMined implements Listener { List newLore = toolStats.itemLore.addItemLore(meta, "{blocks}", blocksMinedFormatted, "blocks-mined"); // do we add the lore based on the config? - if (toolStats.checkConfig(playerTool, "blocks-mined")) { + if (toolStats.checkConfig(playerTool.getType(), "blocks-mined")) { + meta.setLore(newLore); + } + playerTool.setItemMeta(meta); + } + + private void updateCropsMined(ItemStack playerTool, Ageable block) { + // ignore crops that are not fully grown + if (block.getAge() != block.getMaximumAge()) { + return; + } + + ItemMeta meta = playerTool.getItemMeta(); + if (meta == null) { + toolStats.logger.warning(playerTool + " does NOT have any meta! Unable to update stats."); + return; + } + // read the current stats from the item + // if they don't exist, then start from 0 + Integer cropsMined = 0; + PersistentDataContainer container = meta.getPersistentDataContainer(); + if (container.has(toolStats.cropsHarvested, PersistentDataType.INTEGER)) { + cropsMined = container.get(toolStats.cropsHarvested, PersistentDataType.INTEGER); + } + + if (cropsMined == null) { + cropsMined = 0; + toolStats.logger.warning(playerTool + " does not have valid crops-mined set! Resting to zero. This should NEVER happen."); + } + + cropsMined++; + container.set(toolStats.cropsHarvested, PersistentDataType.INTEGER, cropsMined); + + String cropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined); + List newLore = toolStats.itemLore.addItemLore(meta, "{crops}", cropsMinedFormatted, "crops-harvested"); + + // do we add the lore based on the config? + if (toolStats.checkConfig(playerTool.getType(), "blocks-mined")) { meta.setLore(newLore); } playerTool.setItemMeta(meta); diff --git a/src/main/java/lol/hyper/toolstats/events/CraftItem.java b/src/main/java/lol/hyper/toolstats/events/CraftItem.java index 51179e4..2c536bf 100644 --- a/src/main/java/lol/hyper/toolstats/events/CraftItem.java +++ b/src/main/java/lol/hyper/toolstats/events/CraftItem.java @@ -104,6 +104,9 @@ public class CraftItem implements Listener { return null; } + String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated); + + container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.originType, PersistentDataType.INTEGER, 0); @@ -128,10 +131,10 @@ public class CraftItem implements Listener { lore = new ArrayList<>(); } // do we add the lore based on the config? - if (toolStats.checkConfig(itemStack, "created-date")) { + if (toolStats.checkConfig(itemStack.getType(), "created-date")) { lore.add(createdOnRaw.replace("{date}", toolStats.numberFormat.formatDate(finalDate))); } - if (toolStats.checkConfig(itemStack, "created-by")) { + if (toolStats.checkConfig(itemStack.getType(), "created-by")) { lore.add(createdByRaw.replace("{player}", owner.getName())); } meta.setLore(lore); diff --git a/src/main/java/lol/hyper/toolstats/events/EntityDamage.java b/src/main/java/lol/hyper/toolstats/events/EntityDamage.java index 2b69500..52bc952 100644 --- a/src/main/java/lol/hyper/toolstats/events/EntityDamage.java +++ b/src/main/java/lol/hyper/toolstats/events/EntityDamage.java @@ -249,7 +249,7 @@ public class EntityDamage implements Listener { List newLore = toolStats.itemLore.addItemLore(meta, "{kills}", playerKillsFormatted, "kills.player"); // do we add the lore based on the config? - if (toolStats.checkConfig(itemStack, "player-kills")) { + if (toolStats.checkConfig(itemStack.getType(), "player-kills")) { meta.setLore(newLore); } itemStack.setItemMeta(meta); @@ -284,7 +284,7 @@ public class EntityDamage implements Listener { List newLore = toolStats.itemLore.addItemLore(meta, "{kills}", mobKillsFormatted, "kills.mob"); // do we add the lore based on the config? - if (toolStats.checkConfig(itemStack, "mob-kills")) { + if (toolStats.checkConfig(itemStack.getType(), "mob-kills")) { meta.setLore(newLore); } itemStack.setItemMeta(meta); @@ -356,7 +356,7 @@ public class EntityDamage implements Listener { List newLore = toolStats.itemLore.addItemLore(meta, "{kills}", mobKillsFormatted, "kills.mob"); // do we add the lore based on the config? - if (toolStats.checkConfig(newTrident, "mob-kills")) { + if (toolStats.checkConfig(newTrident.getType(), "mob-kills")) { meta.setLore(newLore); } newTrident.setItemMeta(meta); @@ -393,7 +393,7 @@ public class EntityDamage implements Listener { List newLore = toolStats.itemLore.addItemLore(meta, "{kills}", playerKillsFormatted, "kills.player"); // do we add the lore based on the config? - if (toolStats.checkConfig(newTrident, "player-kills")) { + if (toolStats.checkConfig(newTrident.getType(), "player-kills")) { meta.setLore(newLore); } newTrident.setItemMeta(meta); diff --git a/src/main/java/lol/hyper/toolstats/events/GenerateLoot.java b/src/main/java/lol/hyper/toolstats/events/GenerateLoot.java index 1e5b7de..66457de 100644 --- a/src/main/java/lol/hyper/toolstats/events/GenerateLoot.java +++ b/src/main/java/lol/hyper/toolstats/events/GenerateLoot.java @@ -144,6 +144,9 @@ public class GenerateLoot implements Listener { return null; } + String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated); + + container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.originType, PersistentDataType.INTEGER, 2); @@ -151,7 +154,7 @@ public class GenerateLoot implements Listener { String formattedDate = toolStats.numberFormat.formatDate(finalDate); List newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate); - if (toolStats.checkConfig(newItem, "looted-tag")) { + if (toolStats.checkConfig(newItem.getType(), "looted-tag")) { meta.setLore(newLore); } newItem.setItemMeta(meta); diff --git a/src/main/java/lol/hyper/toolstats/events/InventoryOpen.java b/src/main/java/lol/hyper/toolstats/events/InventoryOpen.java index 8992e3b..78e799e 100644 --- a/src/main/java/lol/hyper/toolstats/events/InventoryOpen.java +++ b/src/main/java/lol/hyper/toolstats/events/InventoryOpen.java @@ -19,6 +19,7 @@ package lol.hyper.toolstats.events; import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.tools.ItemChecker; +import lol.hyper.toolstats.tools.UUIDDataType; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -32,7 +33,7 @@ import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import org.bukkit.scheduler.BukkitRunnable; -import java.util.List; +import java.util.UUID; public class InventoryOpen implements Listener { @@ -49,36 +50,54 @@ public class InventoryOpen implements Listener { } Inventory inventory = event.getInventory(); + Location location = event.getInventory().getLocation(); for (ItemStack itemStack : inventory) { if (itemStack == null) { continue; } + // ignore items that are not the right type + if (!ItemChecker.isValidItem(itemStack.getType())) { + continue; + } ItemMeta itemMeta = itemStack.getItemMeta(); if (itemMeta == null) { continue; } PersistentDataContainer container = itemMeta.getPersistentDataContainer(); - // ignore any items that already have the origin tag - if (container.has(toolStats.originType, PersistentDataType.INTEGER)) { - continue; - } - // ignore items that are not the right type - if (!ItemChecker.isValidItem(itemStack.getType())) { - continue; + + // generate a hash if the item doesn't have one + if (!container.has(toolStats.hash, PersistentDataType.STRING)) { + // make sure the item has an owner + if (!container.has(toolStats.genericOwner, new UUIDDataType())) { + continue; + } + UUID owner = container.get(toolStats.genericOwner, new UUIDDataType()); + if (owner == null) { + continue; + } + Long timestamp = container.get(toolStats.timeCreated, PersistentDataType.LONG); + if (timestamp == null) { + continue; + } + String hash = toolStats.hashMaker.makeHash(itemStack.getType(), owner, timestamp); + toolStats.logger.info(hash); + container.set(toolStats.hash, PersistentDataType.STRING, hash); } - ItemMeta newMeta = toolStats.itemLore.getOrigin(itemMeta, itemStack.getType() == Material.ELYTRA); - if (newMeta == null) { - continue; + // add origin tag + if (!container.has(toolStats.originType, PersistentDataType.INTEGER)) { + itemMeta = toolStats.itemLore.getOrigin(itemMeta, itemStack.getType() == Material.ELYTRA); + if (itemMeta == null) { + continue; + } } + ItemMeta clone = itemMeta.clone(); BukkitRunnable runnable = new BukkitRunnable() { @Override public void run() { - itemStack.setItemMeta(newMeta); + itemStack.setItemMeta(clone); } }; - Location location = inventory.getLocation(); - // only run for actual inventories if (location != null) { toolStats.scheduleRegion(runnable, location.getWorld(), location.getChunk(), 1); } diff --git a/src/main/java/lol/hyper/toolstats/events/PlayerFish.java b/src/main/java/lol/hyper/toolstats/events/PlayerFish.java index b486962..29a7bf2 100644 --- a/src/main/java/lol/hyper/toolstats/events/PlayerFish.java +++ b/src/main/java/lol/hyper/toolstats/events/PlayerFish.java @@ -155,6 +155,9 @@ public class PlayerFish implements Listener { return null; } + String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated); + + container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.originType, PersistentDataType.INTEGER, 5); @@ -162,7 +165,7 @@ public class PlayerFish implements Listener { String formattedDate = toolStats.numberFormat.formatDate(finalDate); List newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate); - if (toolStats.checkConfig(newItem, "fished-tag")) { + if (toolStats.checkConfig(newItem.getType(), "fished-tag")) { meta.setLore(newLore); } newItem.setItemMeta(meta); diff --git a/src/main/java/lol/hyper/toolstats/events/PlayerJoin.java b/src/main/java/lol/hyper/toolstats/events/PlayerJoin.java index 08d754d..a693456 100644 --- a/src/main/java/lol/hyper/toolstats/events/PlayerJoin.java +++ b/src/main/java/lol/hyper/toolstats/events/PlayerJoin.java @@ -19,7 +19,7 @@ package lol.hyper.toolstats.events; import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.tools.ItemChecker; -import org.bukkit.Location; +import lol.hyper.toolstats.tools.UUIDDataType; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -32,6 +32,8 @@ import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import org.bukkit.scheduler.BukkitRunnable; +import java.util.UUID; + public class PlayerJoin implements Listener { private final ToolStats toolStats; @@ -49,35 +51,50 @@ public class PlayerJoin implements Listener { if (itemStack == null) { continue; } + // ignore items that are not the right type + if (!ItemChecker.isValidItem(itemStack.getType())) { + continue; + } ItemMeta itemMeta = itemStack.getItemMeta(); if (itemMeta == null) { continue; } PersistentDataContainer container = itemMeta.getPersistentDataContainer(); - // ignore any items that already have the origin tag - if (container.has(toolStats.originType, PersistentDataType.INTEGER)) { - continue; - } - // ignore items that are not the right type - if (!ItemChecker.isValidItem(itemStack.getType())) { - continue; + + // generate a hash if the item doesn't have one + if (!container.has(toolStats.hash, PersistentDataType.STRING)) { + // make sure the item has an owner + if (!container.has(toolStats.genericOwner, new UUIDDataType())) { + continue; + } + UUID owner = container.get(toolStats.genericOwner, new UUIDDataType()); + if (owner == null) { + continue; + } + Long timestamp = container.get(toolStats.timeCreated, PersistentDataType.LONG); + if (timestamp == null) { + continue; + } + String hash = toolStats.hashMaker.makeHash(itemStack.getType(), owner, timestamp); + toolStats.logger.info(hash); + container.set(toolStats.hash, PersistentDataType.STRING, hash); } - ItemMeta newMeta = toolStats.itemLore.getOrigin(itemMeta, itemStack.getType() == Material.ELYTRA); - if (newMeta == null) { - continue; + // add origin tag + if (!container.has(toolStats.originType, PersistentDataType.INTEGER)) { + itemMeta = toolStats.itemLore.getOrigin(itemMeta, itemStack.getType() == Material.ELYTRA); + if (itemMeta == null) { + continue; + } } + ItemMeta clone = itemMeta.clone(); BukkitRunnable runnable = new BukkitRunnable() { @Override public void run() { - itemStack.setItemMeta(newMeta); + itemStack.setItemMeta(clone); } }; - Location location = inventory.getLocation(); - // only run for actual inventories - if (location != null) { - toolStats.scheduleRegion(runnable, location.getWorld(), location.getChunk(), 1); - } + toolStats.scheduleEntity(runnable, player, 1); } } } diff --git a/src/main/java/lol/hyper/toolstats/events/VillagerTrade.java b/src/main/java/lol/hyper/toolstats/events/VillagerTrade.java index 76bc1e3..61b63ce 100644 --- a/src/main/java/lol/hyper/toolstats/events/VillagerTrade.java +++ b/src/main/java/lol/hyper/toolstats/events/VillagerTrade.java @@ -106,6 +106,9 @@ public class VillagerTrade implements Listener { return null; } + String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated); + + container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.originType, PersistentDataType.INTEGER, 3); @@ -113,7 +116,7 @@ public class VillagerTrade implements Listener { String formattedDate = toolStats.numberFormat.formatDate(finalDate); List newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate); - if (toolStats.checkConfig(newItem, "traded-tag")) { + if (toolStats.checkConfig(newItem.getType(), "traded-tag")) { meta.setLore(newLore); } newItem.setItemMeta(meta); diff --git a/src/main/java/lol/hyper/toolstats/tools/HashMaker.java b/src/main/java/lol/hyper/toolstats/tools/HashMaker.java new file mode 100644 index 0000000..671d14c --- /dev/null +++ b/src/main/java/lol/hyper/toolstats/tools/HashMaker.java @@ -0,0 +1,60 @@ +/* + * This file is part of ToolStats. + * + * ToolStats is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ToolStats is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ToolStats. If not, see . + */ + +package lol.hyper.toolstats.tools; + +import lol.hyper.toolstats.ToolStats; +import org.bukkit.Material; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.UUID; + +public class HashMaker { + + private final ToolStats toolStats; + + public HashMaker(ToolStats toolStats) { + this.toolStats = toolStats; + } + + public String makeHash(Material itemType, UUID player, long timestamp) { + String input = itemType.toString() + player.toString() + timestamp; + + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8)); + + StringBuilder hexString = new StringBuilder(); + for (byte b : hashBytes) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + + return hexString.toString(); + } catch (NoSuchAlgorithmException exception) { + toolStats.logger.warning("Unable to generate hash for " + player.toString() + "!"); + toolStats.logger.warning("Generating a random UUID instead."); + exception.printStackTrace(); + return java.util.UUID.randomUUID().toString(); + } + } +} diff --git a/src/main/java/lol/hyper/toolstats/tools/ItemChecker.java b/src/main/java/lol/hyper/toolstats/tools/ItemChecker.java index 72a378a..1b42a41 100644 --- a/src/main/java/lol/hyper/toolstats/tools/ItemChecker.java +++ b/src/main/java/lol/hyper/toolstats/tools/ItemChecker.java @@ -24,10 +24,10 @@ import java.util.Locale; public class ItemChecker { - private static final String[] validItems = { "pickaxe", "sword", "shovel", "axe", "hoe", "bow", "helmet", "chestplate", "leggings", "boots", "fishing", "elytra" }; - private static final String[] validArmor = { "helmet", "chestplate", "leggings", "boots" }; + private static final String[] validItems = {"pickaxe", "sword", "shovel", "axe", "hoe", "bow", "helmet", "chestplate", "leggings", "boots", "fishing", "elytra"}; + private static final String[] validArmor = {"helmet", "chestplate", "leggings", "boots"}; private static final String[] validMelee = {"sword", "trident", "axe"}; - private static final String[] validMine = { "pickaxe", "axe", "hoe", "shovel", "shear" }; + private static final String[] validMine = {"pickaxe", "axe", "hoe", "shovel", "shear", "hoe"}; /** * Check if item is an armor piece. diff --git a/src/main/java/lol/hyper/toolstats/tools/ItemLore.java b/src/main/java/lol/hyper/toolstats/tools/ItemLore.java index eba3c33..6923c1d 100644 --- a/src/main/java/lol/hyper/toolstats/tools/ItemLore.java +++ b/src/main/java/lol/hyper/toolstats/tools/ItemLore.java @@ -63,7 +63,8 @@ public class ItemLore { for (int x = 0; x < newLore.size(); x++) { // check to see if the line matches the config value // this means we update this line only! - if (newLore.get(x).contains(configLore)) { + String line = newLore.get(x); + if (line.contains(configLore)) { newLore.set(x, newLine); return newLore; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c439d2f..1227eee 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -91,6 +91,7 @@ messages: mob: "&7Mob kills: &8{kills}" player: "&7Player kills: &8{kills}" blocks-mined: "&7Blocks mined: &8{blocks}" + crops-harvested: "&7Crops harvested: &8{crops}" sheep-sheared: "&7Sheep sheared: &8{sheep}" dropped-by: "&7Dropped by: &8{name}" # name will be player/mob name damage-taken: "&7Damage taken: &8{damage}"