Compare commits

...

11 Commits
1.2.2 ... 1.3

Author SHA1 Message Date
hyperdefined
adb1c637dc smh 2022-02-11 18:34:42 -05:00
hyperdefined
4b8f8061b4 Merge branch 'master' of https://github.com/hyperdefined/ToolStats 2022-02-11 15:09:49 -05:00
hyperdefined
464916e08b Update CommandToolStats.java 2022-02-11 15:09:32 -05:00
hyperdefined
6b6b65d1df Update README.md 2022-02-11 15:05:55 -05:00
hyperdefined
a1c39dffd0 Update pom.xml 2022-02-11 15:05:18 -05:00
hyperdefined
88eab81906 added tab completions to sub commands 2022-02-11 15:03:37 -05:00
hyperdefined
be233de90d fixed plugin.yml 2022-02-11 15:03:21 -05:00
hyperdefined
2437424e39 added reset lore command 2022-02-11 14:46:25 -05:00
hyperdefined
63b08062c8 Update CraftItem.java 2022-02-11 14:04:12 -05:00
hyperdefined
d23c2446dd fix fishing rods not updating lore correctly 2022-02-11 14:03:51 -05:00
hyperdefined
77b1be62d4 fixes 2022-02-10 21:41:23 -05:00
15 changed files with 276 additions and 13 deletions

View File

@@ -23,6 +23,8 @@ Here is everything it tracks:
The best part is, this data is stored on the item itself. You can also change how the lore is displayed on the items!
If item lore is ever incorrect, you can run `/toolstats reset` to reset the item lore so it's correct.
![Image](https://raw.githubusercontent.com/hyperdefined/ToolStats/master/images/image.png)
![Image](https://raw.githubusercontent.com/hyperdefined/ToolStats/master/images/image2.png)
![Image](https://raw.githubusercontent.com/hyperdefined/ToolStats/master/images/image3.png)

View File

@@ -23,7 +23,7 @@
<groupId>lol.hyper</groupId>
<artifactId>toolstats</artifactId>
<version>1.2.2</version>
<version>1.3</version>
<packaging>jar</packaging>
<name>ToolStats</name>

View File

@@ -74,7 +74,7 @@ public final class ToolStats extends JavaPlugin {
public final Logger logger = this.getLogger();
public final File configFile = new File(this.getDataFolder(), "config.yml");
public FileConfiguration config;
public final int CONFIG_VERSION = 2;
public final int CONFIG_VERSION = 3;
@Override
public void onEnable() {
@@ -235,6 +235,9 @@ public final class ToolStats extends JavaPlugin {
if (lore.contains("{damage}")) {
lore = lore.replace("{damage}", "");
}
if (lore.contains("{fish}")) {
lore = lore.replace("{fish}", "");
}
}
return lore;
}

View File

@@ -18,36 +18,232 @@
package lol.hyper.toolstats.commands;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.ChatColor;
import lol.hyper.toolstats.UUIDDataType;
import org.bukkit.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CommandToolStats implements CommandExecutor {
import java.text.SimpleDateFormat;
import java.util.*;
public class CommandToolStats implements TabExecutor {
private final ToolStats toolStats;
public CommandToolStats(ToolStats toolStats) {
this.toolStats = toolStats;
}
private final SimpleDateFormat format = new SimpleDateFormat("M/dd/yyyy", Locale.ENGLISH);
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!sender.hasPermission("toolstats.use")) {
sender.sendMessage(ChatColor.RED + "You do not have permission for this command.");
return true;
}
if (args.length == 0) {
sender.sendMessage(ChatColor.GREEN + "ToolStats version " + toolStats.getDescription().getVersion() + ". Created by hyperdefined.");
} else if (args.length == 1) {
if (args[0].equalsIgnoreCase("reload")) {
}
switch (args[0]) {
case "reload": {
if (sender.isOp() || sender.hasPermission("toolstats.reload")) {
toolStats.loadConfig();
sender.sendMessage(ChatColor.GREEN + "Configuration reloaded!");
} else {
sender.sendMessage(ChatColor.RED + "You do not have permission for this command.");
}
} else {
return true;
}
case "reset": {
if (args.length == 2 && args[1].equalsIgnoreCase("confirm")) {
Player player = (Player) sender;
ItemStack heldItem = player.getInventory().getItemInMainHand();
if (heldItem.getType() == Material.AIR) {
sender.sendMessage(ChatColor.RED + "You must hold an item!");
return true;
}
fixItemLore(heldItem, player);
sender.sendMessage(ChatColor.GREEN + "The lore was reset!");
return true;
}
sender.sendMessage(ChatColor.GREEN + "This will remove ALL current lore from the held item and replace it with the correct lore.");
sender.sendMessage(ChatColor.GREEN + "The item owner will be who ever is currently running this command.");
sender.sendMessage(ChatColor.GREEN + "Only use this if the tags on the tool are incorrect.");
sender.sendMessage(ChatColor.GREEN + "Type /toolstats reset confirm to confirm this.");
return true;
}
default: {
sender.sendMessage(ChatColor.RED + "Invalid sub-command.");
}
}
return true;
}
private ItemStack fixItemLore(ItemStack original, Player player) {
ItemStack finalItem = original.clone();
ItemMeta finalMeta = finalItem.getItemMeta();
if (finalMeta == null) {
return null;
}
PersistentDataContainer container = finalMeta.getPersistentDataContainer();
List<String> lore = new ArrayList<>();
String caughtByLore = toolStats.getLoreFromConfig("fished.caught-by", false);
String lootedByLore = toolStats.getLoreFromConfig("looted.found-by", false);
String tradedByLore = toolStats.getLoreFromConfig("traded.traded-by", false);
if (caughtByLore == null || lootedByLore == null || tradedByLore == null) {
return null;
}
String type = "DEFAULT";
if (finalMeta.hasLore()) {
if (finalMeta.getLore() != null) {
for (String line : finalMeta.getLore()) {
if (line.contains(caughtByLore)) {
type = "CAUGHT";
}
if (line.contains(lootedByLore)) {
type = "LOOTED";
}
if (line.contains(tradedByLore)) {
type = "TRADED";
}
}
}
}
if (toolStats.checkConfig(original, "created-by")) {
if (container.has(toolStats.genericOwner, new UUIDDataType())) {
container.set(toolStats.genericOwner, new UUIDDataType(), player.getUniqueId());
switch (type) {
case "DEFAULT": {
lore.add(toolStats.getLoreFromConfig("created.created-by", true).replace("{player}", player.getName()));
break;
}
case "CAUGHT": {
lore.add(toolStats.getLoreFromConfig("fished.caught-by", true).replace("{player}", player.getName()));
break;
}
case "LOOTED": {
lore.add(toolStats.getLoreFromConfig("looted.looted-by", true).replace("{player}", player.getName()));
break;
}
case "TRADED": {
lore.add(toolStats.getLoreFromConfig("traded.traded-by", true).replace("{player}", player.getName()));
break;
}
}
}
}
if (toolStats.checkConfig(original, "created-date")) {
if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) {
Long time = container.get(toolStats.timeCreated, PersistentDataType.LONG);
if (time == null) {
return null;
}
switch (type) {
case "DEFAULT": {
lore.add(toolStats.getLoreFromConfig("created.created-by", true).replace("{date}", format.format(new Date(time))));
break;
}
case "CAUGHT": {
lore.add(toolStats.getLoreFromConfig("fished.caught-on", true).replace("{date}", format.format(new Date(time))));
break;
}
case "LOOTED": {
lore.add(toolStats.getLoreFromConfig("looted.looted-on", true).replace("{date}", format.format(new Date(time))));
break;
}
case "TRADED": {
lore.add(toolStats.getLoreFromConfig("traded.traded-on", true).replace("{date}", format.format(new Date(time))));
break;
}
}
}
}
if (toolStats.checkConfig(original, "player-kills")) {
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
Integer kills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
if (kills == null) {
return null;
}
lore.add(toolStats.getLoreFromConfig("kills.player", true).replace("{kills}", Integer.toString(kills)));
}
}
if (toolStats.checkConfig(original, "mob-kills")) {
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
Integer kills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
if (kills == null) {
return null;
}
lore.add(toolStats.getLoreFromConfig("kills.mob", true).replace("{kills}", Integer.toString(kills)));
}
}
if (toolStats.checkConfig(original, "blocks-mined")) {
if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) {
Integer blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER);
if (blocksMined == null) {
return null;
}
lore.add(toolStats.getLoreFromConfig("blocks-mined", true).replace("{blocks}", Integer.toString(blocksMined)));
}
}
if (toolStats.config.getBoolean("enabled.fish-caught")) {
if (container.has(toolStats.fishingRodCaught, PersistentDataType.INTEGER)) {
Integer fish = container.get(toolStats.fishingRodCaught, PersistentDataType.INTEGER);
if (fish == null) {
return null;
}
lore.add(toolStats.getLoreFromConfig("fished.fish-caught", true).replace("{fish}", Integer.toString(fish)));
}
}
if (toolStats.config.getBoolean("enabled.sheep-sheared")) {
if (container.has(toolStats.shearsSheared, PersistentDataType.INTEGER)) {
Integer sheep = container.get(toolStats.shearsSheared, PersistentDataType.INTEGER);
if (sheep == null) {
return null;
}
lore.add(toolStats.getLoreFromConfig("sheep-sheared", true).replace("{sheep}", Integer.toString(sheep)));
}
}
if (toolStats.config.getBoolean("enabled.armor-damage")) {
if (container.has(toolStats.armorDamage, PersistentDataType.INTEGER)) {
Integer damage = container.get(toolStats.armorDamage, PersistentDataType.INTEGER);
if (damage == null) {
return null;
}
lore.add(toolStats.getLoreFromConfig("damage-taken", true).replace("{damage}", Integer.toString(damage)));
}
}
finalMeta.setLore(lore);
finalItem.setItemMeta(finalMeta);
return finalItem;
}
@Nullable
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
if (args.length == 1) {
if (sender.hasPermission("toolstats.reload")) {
return Arrays.asList("reset", "reload");
} else {
return Collections.singletonList("reset");
}
}
if (args.length == 2) {
if (args[0].equalsIgnoreCase("reset")) {
return Collections.singletonList("confirm");
}
}
return null;
}
}

View File

@@ -44,6 +44,9 @@ public class BlocksMined implements Listener {
@EventHandler
public void onBreak(BlockBreakEvent event) {
if (event.isCancelled()) {
return;
}
Player player = event.getPlayer();
if (player.getGameMode() != GameMode.SURVIVAL) {
return;

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.UUIDDataType;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -46,6 +47,9 @@ public class CraftItem implements Listener {
@EventHandler
public void onCraft(CraftItemEvent event) {
if (event.isCancelled()) {
return;
}
Player player = (Player) event.getWhoClicked();
ItemStack itemStack = event.getCurrentItem();
if (itemStack == null || itemStack.getType() == Material.AIR) {
@@ -54,6 +58,14 @@ public class CraftItem implements Listener {
String name = itemStack.getType().toString().toLowerCase(Locale.ROOT);
for (String x : validItems) {
if (name.contains(x)) {
if (event.isShiftClick()) {
String configMessage = toolStats.config.getString("messages.shift-click-warning.crafting");
if (configMessage != null) {
if (configMessage.length() != 0) {
event.getWhoClicked().sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage));
}
}
}
if (addLore(itemStack, player) == null) {
return;
}
@@ -71,6 +83,11 @@ public class CraftItem implements Listener {
long timeCreated = System.currentTimeMillis();
Date finalDate = new Date(timeCreated);
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.genericOwner, PersistentDataType.LONG)) {
return null;
}
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());

View File

@@ -49,6 +49,9 @@ public class EntityDamage implements Listener {
@EventHandler
public void onDamage(EntityDamageByEntityEvent event) {
if (event.isCancelled()) {
return;
}
if (!(event.getEntity() instanceof LivingEntity)) {
return;
}

View File

@@ -87,7 +87,7 @@ public class EntityDeath implements Listener {
lore = new ArrayList<>();
}
if (!hasTag) {
lore.add(droppedByLoreRaw.replace("X", mob));
lore.add(droppedByLoreRaw.replace("{name}", mob));
}
if (toolStats.config.getBoolean("enabled.dropped-by")) {
meta.setLore(lore);

View File

@@ -84,6 +84,11 @@ public class GenerateLoot implements Listener {
long timeCreated = System.currentTimeMillis();
Date finalDate = new Date(timeCreated);
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.genericOwner, PersistentDataType.LONG)) {
return null;
}
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());

View File

@@ -47,6 +47,9 @@ public class PickupItem implements Listener {
@EventHandler
public void onPickup(EntityPickupItemEvent event) {
if (event.isCancelled()) {
return;
}
Entity entity = event.getEntity();
if (entity instanceof Player) {
ItemStack itemStack = event.getItem().getItemStack();

View File

@@ -50,6 +50,9 @@ public class PlayerFish implements Listener {
@EventHandler
public void onFish(PlayerFishEvent event) {
if (event.isCancelled()) {
return;
}
// only listen to when a player catches a fish
if (event.getState() != PlayerFishEvent.State.CAUGHT_FISH) {
return;
@@ -134,6 +137,11 @@ public class PlayerFish implements Listener {
long timeCreated = System.currentTimeMillis();
Date finalDate = new Date(timeCreated);
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.genericOwner, PersistentDataType.LONG)) {
return;
}
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());

View File

@@ -43,6 +43,9 @@ public class SheepShear implements Listener {
@EventHandler
public void onShear(PlayerInteractEntityEvent event) {
if (event.isCancelled()) {
return;
}
Player player = event.getPlayer();
Entity entity = event.getRightClicked();
if (!(entity instanceof Sheep)) {

View File

@@ -20,6 +20,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.UUIDDataType;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -61,6 +62,12 @@ public class VillagerTrade implements Listener {
ItemStack item = event.getCurrentItem();
for (String x : validItems) {
if (item.getType().toString().toLowerCase(Locale.ROOT).contains(x)) {
if (event.isShiftClick()) {
String configMessage = toolStats.config.getString("messages.shift-click-warning.trading");
if (configMessage != null) {
event.getWhoClicked().sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage));
}
}
ItemStack newItem = addLore(item, (Player) event.getWhoClicked());
if (newItem == null) {
return;
@@ -80,6 +87,11 @@ public class VillagerTrade implements Listener {
long timeCreated = System.currentTimeMillis();
Date finalDate = new Date(timeCreated);
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.genericOwner, PersistentDataType.LONG)) {
return null;
}
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());

View File

@@ -92,5 +92,10 @@ messages:
sheep-sheared: "&7Sheep sheared: &8{sheep}"
dropped-by: "&7Dropped by: &8{name}" # name will be player/mob name
damage-taken: "&7Damage taken: &8{damage}"
# Display this message if the player shift click trades/crafts items. It's not really easy to get every single item
# that is crafted. The tag will only be added to the first item. If you don't want this message, simply replace them both with ""
shift-click-warning:
crafting: "&cCrafting items via shift clicking does not fully apply tags to each item. This is a limitation with the Bukkit API."
trading: "&cTrading items via shift clicking does not fully apply tags to each item. This is a limitation with the Bukkit API."
config-version: 2
config-version: 3

View File

@@ -8,8 +8,11 @@ commands:
toolstats:
usage: /toolstats
description: Main command.
permission: randomenchant.reload
permission: toolstats.main
permissions:
randomenchant.reload:
description: Allows the usage of /randomenchant reload
toolstats.main:
description: Allows the usage of /toolstats
default: true
toolstats.reload:
description: Allows the usage of /toolstats reload
default: op