Compare commits

...

11 Commits
1.4.5 ... 1.5

Author SHA1 Message Date
hyperdefined
24d30f6059 fix deepsource problems 2022-10-13 18:09:19 -04:00
hyperdefined
bea7e52347 Update pom.xml 2022-10-13 18:05:00 -04:00
hyperdefined
1b1b45ef6d even BETTER number formatting?!?!
closes #19
2022-10-13 17:58:40 -04:00
hyperdefined
2de2ae82a7 config for date formatting
closes #20
2022-10-12 13:21:54 -04:00
hyperdefined
7639943fea better formatting for numbers 2022-10-12 13:04:35 -04:00
hyperdefined
2b75ea094d maybe not do this? 2022-10-09 16:51:26 -04:00
hyperdefined
bc8496fad4 changed event priorities 2022-10-05 20:46:19 -04:00
hyperdefined
1cef74311e big cleanup 2022-10-05 16:20:36 -04:00
hyperdefined
cbbdb4e9c4 remove dumb stuff 2022-10-04 12:59:16 -04:00
hyperdefined
f6d35c459c Merge pull request #17 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.4.0
Bump maven-shade-plugin from 3.3.0 to 3.4.0
2022-09-19 22:32:43 -04:00
dependabot[bot]
4624d7a847 Bump maven-shade-plugin from 3.3.0 to 3.4.0
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.3.0...maven-shade-plugin-3.4.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-15 11:29:08 +00:00
15 changed files with 246 additions and 108 deletions

View File

@@ -23,7 +23,7 @@
<groupId>lol.hyper</groupId> <groupId>lol.hyper</groupId>
<artifactId>toolstats</artifactId> <artifactId>toolstats</artifactId>
<version>1.4.5</version> <version>1.5</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ToolStats</name> <name>ToolStats</name>
@@ -60,7 +60,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version> <version>3.4.0</version>
<configuration> <configuration>
<relocations> <relocations>
<relocation> <relocation>

View File

@@ -34,6 +34,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Locale; import java.util.Locale;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -59,10 +60,7 @@ public final class ToolStats extends JavaPlugin {
// used for tracking new elytras // used for tracking new elytras
public final NamespacedKey newElytra = new NamespacedKey(this, "new"); public final NamespacedKey newElytra = new NamespacedKey(this, "new");
public final SimpleDateFormat dateFormat = new SimpleDateFormat("M/dd/yyyy", Locale.ENGLISH); public SimpleDateFormat dateFormat;
public final DecimalFormat decimalFormat = new DecimalFormat("#,###.00");
public final DecimalFormat commaFormat = new DecimalFormat("#,###");
public BlocksMined blocksMined; public BlocksMined blocksMined;
public ChunkPopulate chunkPopulate; public ChunkPopulate chunkPopulate;
public CraftItem craftItem; public CraftItem craftItem;
@@ -128,6 +126,20 @@ public final class ToolStats extends JavaPlugin {
if (config.getInt("config-version") != CONFIG_VERSION) { if (config.getInt("config-version") != CONFIG_VERSION) {
logger.warning("Your config file is outdated! Please regenerate the config."); logger.warning("Your config file is outdated! Please regenerate the config.");
} }
String dateFormatConfig = config.getString("date-format");
if (dateFormatConfig != null) {
try {
dateFormat = new SimpleDateFormat(dateFormatConfig, Locale.getDefault());
} catch (IllegalArgumentException exception) {
logger.severe("date-format is NOT a valid format! Using default American English format.");
exception.printStackTrace();
dateFormat = new SimpleDateFormat("M/dd/yyyy", Locale.ENGLISH);
}
} else {
logger.warning("date-format is missing from your config! Using default American English format.");
dateFormat = new SimpleDateFormat("M/dd/yyyy", Locale.ENGLISH);
}
} }
public void checkForUpdates() { public void checkForUpdates() {
@@ -174,7 +186,7 @@ public final class ToolStats extends JavaPlugin {
itemType = "trident"; itemType = "trident";
} }
} else { } else {
itemType = itemName.substring(itemName.indexOf("_") + 1); itemType = itemName.substring(itemName.indexOf('_') + 1);
} }
if (itemType == null) { if (itemType == null) {
@@ -264,7 +276,7 @@ public final class ToolStats extends JavaPlugin {
} }
public BukkitAudiences getAdventure() { public BukkitAudiences getAdventure() {
if(this.adventure == null) { if (this.adventure == null) {
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!"); throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
} }
return this.adventure; return this.adventure;

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.commands; package lol.hyper.toolstats.commands;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.NumberFormat;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@@ -215,7 +216,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) { if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
Integer kills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER); Integer kills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
if (kills != null) { if (kills != null) {
lore.add(toolStats.getLoreFromConfig("kills.player", true).replace("{kills}", toolStats.commaFormat.format(kills))); lore.add(toolStats.getLoreFromConfig("kills.player", true).replace("{kills}", NumberFormat.formatInt(kills)));
} }
} }
} }
@@ -223,7 +224,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) { if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
Integer kills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER); Integer kills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
if (kills != null) { if (kills != null) {
lore.add(toolStats.getLoreFromConfig("kills.mob", true).replace("{kills}", toolStats.commaFormat.format(kills))); lore.add(toolStats.getLoreFromConfig("kills.mob", true).replace("{kills}", NumberFormat.formatInt(kills)));
} }
} }
} }
@@ -231,7 +232,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) { if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) {
Integer blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER); Integer blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER);
if (blocksMined != null) { if (blocksMined != null) {
lore.add(toolStats.getLoreFromConfig("blocks-mined", true).replace("{blocks}", toolStats.commaFormat.format(blocksMined))); lore.add(toolStats.getLoreFromConfig("blocks-mined", true).replace("{blocks}", NumberFormat.formatInt(blocksMined)));
} }
} }
} }
@@ -239,7 +240,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.fishingRodCaught, PersistentDataType.INTEGER)) { if (container.has(toolStats.fishingRodCaught, PersistentDataType.INTEGER)) {
Integer fish = container.get(toolStats.fishingRodCaught, PersistentDataType.INTEGER); Integer fish = container.get(toolStats.fishingRodCaught, PersistentDataType.INTEGER);
if (fish != null) { if (fish != null) {
lore.add(toolStats.getLoreFromConfig("fished.fish-caught", true).replace("{fish}", toolStats.commaFormat.format(fish))); lore.add(toolStats.getLoreFromConfig("fished.fish-caught", true).replace("{fish}", NumberFormat.formatInt(fish)));
} }
} }
} }
@@ -247,7 +248,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.shearsSheared, PersistentDataType.INTEGER)) { if (container.has(toolStats.shearsSheared, PersistentDataType.INTEGER)) {
Integer sheep = container.get(toolStats.shearsSheared, PersistentDataType.INTEGER); Integer sheep = container.get(toolStats.shearsSheared, PersistentDataType.INTEGER);
if (sheep != null) { if (sheep != null) {
lore.add(toolStats.getLoreFromConfig("sheep-sheared", true).replace("{sheep}", toolStats.commaFormat.format(sheep))); lore.add(toolStats.getLoreFromConfig("sheep-sheared", true).replace("{sheep}", NumberFormat.formatInt(sheep)));
} }
} }
} }
@@ -255,7 +256,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.armorDamage, PersistentDataType.DOUBLE)) { if (container.has(toolStats.armorDamage, PersistentDataType.DOUBLE)) {
Double damage = container.get(toolStats.armorDamage, PersistentDataType.DOUBLE); Double damage = container.get(toolStats.armorDamage, PersistentDataType.DOUBLE);
if (damage != null) { if (damage != null) {
lore.add(toolStats.getLoreFromConfig("damage-taken", true).replace("{damage}", toolStats.commaFormat.format(damage))); lore.add(toolStats.getLoreFromConfig("damage-taken", true).replace("{damage}", NumberFormat.formatDouble(damage)));
} }
} }
} }

View File

@@ -19,10 +19,12 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.ItemChecker; import lol.hyper.toolstats.tools.ItemChecker;
import lol.hyper.toolstats.tools.NumberFormat;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -41,7 +43,7 @@ public class BlocksMined implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler (priority = EventPriority.HIGHEST)
public void onBreak(BlockBreakEvent event) { public void onBreak(BlockBreakEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -51,7 +53,8 @@ public class BlocksMined implements Listener {
return; return;
} }
// if the player mines something with their fist // if the player mines something with their fist
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot()); int heldItemSlot = player.getInventory().getHeldItemSlot();
ItemStack heldItem = player.getInventory().getItem(heldItemSlot);
if (heldItem == null || heldItem.getType() == Material.AIR) { if (heldItem == null || heldItem.getType() == Material.AIR) {
return; return;
} }
@@ -63,20 +66,23 @@ public class BlocksMined implements Listener {
updateBlocksMined(heldItem); updateBlocksMined(heldItem);
} }
private void updateBlocksMined(ItemStack itemStack) { private void updateBlocksMined(ItemStack playerTool) {
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = playerTool.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(playerTool + " does NOT have any meta! Unable to update stats.");
return; return;
} }
// read the current stats from the item // read the current stats from the item
// if they don't exist, then start from 0 // if they don't exist, then start from 0
Integer blocksMined = null; Integer blocksMined = 0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) { if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) {
blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER); blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER);
} }
if (blocksMined == null) { if (blocksMined == null) {
blocksMined = 0; blocksMined = 0;
toolStats.logger.warning(playerTool + " does not have valid generic-mined set! Resting to zero. This should NEVER happen.");
} }
blocksMined++; blocksMined++;
@@ -91,32 +97,32 @@ public class BlocksMined implements Listener {
} }
List<String> lore; List<String> lore;
String newLine = configLoreRaw.replace("{blocks}", NumberFormat.formatInt(blocksMined));
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
boolean hasLore = false; boolean hasLore = false;
// we do a for loop like this, we can keep track of index // we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items // this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) { for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(configLore)) { if (lore.get(x).contains(configLore)) {
hasLore = true; hasLore = true;
lore.set(x, configLoreRaw.replace("{blocks}", toolStats.commaFormat.format(blocksMined))); lore.set(x, newLine);
break; break;
} }
} }
// if the item has lore but doesn't have the tag, add it // if the item has lore but doesn't have the tag, add it
if (!hasLore) { if (!hasLore) {
lore.add(configLoreRaw.replace("{blocks}", toolStats.commaFormat.format(blocksMined))); lore.add(newLine);
} }
} else { } else {
// if the item has no lore, create a new list and add the string // if the item has no lore, create a new list and add the string
lore = new ArrayList<>(); lore = new ArrayList<>();
lore.add(configLoreRaw.replace("{blocks}", toolStats.commaFormat.format(blocksMined))); lore.add(newLine);
} }
// do we add the lore based on the config? // do we add the lore based on the config?
if (toolStats.checkConfig(itemStack, "blocks-mined")) { if (toolStats.checkConfig(playerTool, "blocks-mined")) {
meta.setLore(lore); meta.setLore(lore);
} }
itemStack.setItemMeta(meta); playerTool.setItemMeta(meta);
} }
} }

View File

@@ -25,6 +25,7 @@ import org.bukkit.World;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame; import org.bukkit.entity.ItemFrame;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkPopulateEvent; import org.bukkit.event.world.ChunkPopulateEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -43,7 +44,7 @@ public class ChunkPopulate implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST)
public void onPopulate(ChunkPopulateEvent event) { public void onPopulate(ChunkPopulateEvent event) {
if (event.getChunk().getWorld().getEnvironment() != World.Environment.THE_END) { if (event.getChunk().getWorld().getEnvironment() != World.Environment.THE_END) {
return; return;

View File

@@ -25,6 +25,7 @@ import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent; import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -42,7 +43,7 @@ public class CraftItem implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST)
public void onCraft(CraftItemEvent event) { public void onCraft(CraftItemEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -89,6 +90,7 @@ public class CraftItem implements Listener {
ItemStack newItem = itemStack.clone(); ItemStack newItem = itemStack.clone();
ItemMeta meta = newItem.getItemMeta(); ItemMeta meta = newItem.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return null; return null;
} }
// get the current time // get the current time
@@ -121,7 +123,6 @@ public class CraftItem implements Listener {
// get the current lore the item // get the current lore the item
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
} else { } else {
lore = new ArrayList<>(); lore = new ArrayList<>();
} }

View File

@@ -19,10 +19,12 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.ItemChecker; import lol.hyper.toolstats.tools.ItemChecker;
import lol.hyper.toolstats.tools.NumberFormat;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.*; import org.bukkit.entity.*;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByBlockEvent; import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
@@ -45,7 +47,7 @@ public class EntityDamage implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST)
public void onDamage(EntityDamageByEntityEvent event) { public void onDamage(EntityDamageByEntityEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -145,7 +147,7 @@ public class EntityDamage implements Listener {
} }
} }
@EventHandler @EventHandler(priority = EventPriority.LOWEST)
public void onDamage(EntityDamageEvent event) { public void onDamage(EntityDamageEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) { if (!(event.getEntity() instanceof LivingEntity)) {
return; return;
@@ -175,7 +177,7 @@ public class EntityDamage implements Listener {
} }
} }
@EventHandler @EventHandler(priority = EventPriority.LOWEST)
public void onDamage(EntityDamageByBlockEvent event) { public void onDamage(EntityDamageByBlockEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) { if (!(event.getEntity() instanceof LivingEntity)) {
return; return;
@@ -215,15 +217,18 @@ public class EntityDamage implements Listener {
ItemStack finalItem = itemStack.clone(); ItemStack finalItem = itemStack.clone();
ItemMeta meta = finalItem.getItemMeta(); ItemMeta meta = finalItem.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return null; return null;
} }
Integer playerKills = null; Integer playerKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) { if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
playerKills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER); playerKills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
} }
if (playerKills == null) { if (playerKills == null) {
playerKills = 0; playerKills = 0;
toolStats.logger.warning(itemStack + " does not have valid player-kills set! Resting to zero. This should NEVER happen.");
} }
playerKills++; playerKills++;
@@ -238,27 +243,27 @@ public class EntityDamage implements Listener {
} }
List<String> lore; List<String> lore;
String newLine = playerKillsLoreRaw.replace("{kills}", NumberFormat.formatInt(playerKills));
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
boolean hasLore = false; boolean hasLore = false;
// we do a for loop like this, we can keep track of index // we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items // this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) { for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(playerKillsLore)) { if (lore.get(x).contains(playerKillsLore)) {
hasLore = true; hasLore = true;
lore.set(x, playerKillsLoreRaw.replace("{kills}", toolStats.commaFormat.format(playerKills))); lore.set(x, newLine);
break; break;
} }
} }
// if the item has lore but doesn't have the tag, add it // if the item has lore but doesn't have the tag, add it
if (!hasLore) { if (!hasLore) {
lore.add(playerKillsLoreRaw.replace("{kills}", toolStats.commaFormat.format(playerKills))); lore.add(newLine);
} }
} else { } else {
// if the item has no lore, create a new list and add the string // if the item has no lore, create a new list and add the string
lore = new ArrayList<>(); lore = new ArrayList<>();
lore.add(playerKillsLoreRaw.replace("{kills}", toolStats.commaFormat.format(playerKills))); lore.add(newLine);
} }
// do we add the lore based on the config? // do we add the lore based on the config?
if (toolStats.checkConfig(itemStack, "player-kills")) { if (toolStats.checkConfig(itemStack, "player-kills")) {
@@ -278,15 +283,18 @@ public class EntityDamage implements Listener {
ItemStack finalItem = itemStack.clone(); ItemStack finalItem = itemStack.clone();
ItemMeta meta = finalItem.getItemMeta(); ItemMeta meta = finalItem.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return null; return null;
} }
Integer mobKills = null; Integer mobKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) { if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
mobKills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER); mobKills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
} }
if (mobKills == null) { if (mobKills == null) {
mobKills = 0; mobKills = 0;
toolStats.logger.warning(itemStack + " does not have valid mob-kills set! Resting to zero. This should NEVER happen.");
} }
mobKills++; mobKills++;
@@ -301,27 +309,27 @@ public class EntityDamage implements Listener {
} }
List<String> lore; List<String> lore;
String newLine = mobKillsLoreRaw.replace("{kills}", NumberFormat.formatInt(mobKills));
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
boolean hasLore = false; boolean hasLore = false;
// we do a for loop like this, we can keep track of index // we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items // this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) { for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(mobKillsLore)) { if (lore.get(x).contains(mobKillsLore)) {
hasLore = true; hasLore = true;
lore.set(x, mobKillsLoreRaw.replace("{kills}", toolStats.commaFormat.format(mobKills))); lore.set(x, newLine);
break; break;
} }
} }
// if the item has lore but doesn't have the tag, add it // if the item has lore but doesn't have the tag, add it
if (!hasLore) { if (!hasLore) {
lore.add(mobKillsLoreRaw.replace("{kills}", toolStats.commaFormat.format(mobKills))); lore.add(newLine);
} }
} else { } else {
// if the item has no lore, create a new list and add the string // if the item has no lore, create a new list and add the string
lore = new ArrayList<>(); lore = new ArrayList<>();
lore.add(mobKillsLoreRaw.replace("{kills}", toolStats.commaFormat.format(mobKills))); lore.add(newLine);
} }
// do we add the lore based on the config? // do we add the lore based on the config?
if (toolStats.checkConfig(itemStack, "mob-kills")) { if (toolStats.checkConfig(itemStack, "mob-kills")) {
@@ -340,15 +348,18 @@ public class EntityDamage implements Listener {
private void updateArmorDamage(ItemStack itemStack, double damage) { private void updateArmorDamage(ItemStack itemStack, double damage) {
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = itemStack.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return; return;
} }
Double damageTaken = null; Double damageTaken = 0.0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.armorDamage, PersistentDataType.DOUBLE)) { if (container.has(toolStats.armorDamage, PersistentDataType.DOUBLE)) {
damageTaken = container.get(toolStats.armorDamage, PersistentDataType.DOUBLE); damageTaken = container.get(toolStats.armorDamage, PersistentDataType.DOUBLE);
} }
if (damageTaken == null) { if (damageTaken == null) {
damageTaken = 0.0; damageTaken = 0.0;
toolStats.logger.warning(itemStack + " does not have valid damage-taken set! Resting to zero. This should NEVER happen.");
} }
damageTaken = damageTaken + damage; damageTaken = damageTaken + damage;
@@ -363,27 +374,27 @@ public class EntityDamage implements Listener {
} }
List<String> lore; List<String> lore;
String newLine = damageTakenLoreRaw.replace("{damage}", NumberFormat.formatDouble(damageTaken));
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
boolean hasLore = false; boolean hasLore = false;
// we do a for loop like this, we can keep track of index // we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items // this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) { for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(damageTakenLore)) { if (lore.get(x).contains(damageTakenLore)) {
hasLore = true; hasLore = true;
lore.set(x, damageTakenLoreRaw.replace("{damage}", toolStats.decimalFormat.format(damageTaken))); lore.set(x, newLine);
break; break;
} }
} }
// if the item has lore but doesn't have the tag, add it // if the item has lore but doesn't have the tag, add it
if (!hasLore) { if (!hasLore) {
lore.add(damageTakenLoreRaw.replace("{damage}", toolStats.decimalFormat.format(damageTaken))); lore.add(newLine);
} }
} else { } else {
// if the item has no lore, create a new list and add the string // if the item has no lore, create a new list and add the string
lore = new ArrayList<>(); lore = new ArrayList<>();
lore.add(damageTakenLoreRaw.replace("{damage}", toolStats.decimalFormat.format(damageTaken))); lore.add(newLine);
} }
if (toolStats.config.getBoolean("enabled.armor-damage")) { if (toolStats.config.getBoolean("enabled.armor-damage")) {
meta.setLore(lore); meta.setLore(lore);

View File

@@ -22,6 +22,7 @@ import lol.hyper.toolstats.tools.ItemChecker;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -37,7 +38,7 @@ public class EntityDeath implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST)
public void onDeath(EntityDeathEvent event) { public void onDeath(EntityDeathEvent event) {
LivingEntity livingEntity = event.getEntity(); LivingEntity livingEntity = event.getEntity();
if (livingEntity instanceof Player) { if (livingEntity instanceof Player) {
@@ -46,9 +47,13 @@ public class EntityDeath implements Listener {
UUID livingEntityUUID = event.getEntity().getUniqueId(); UUID livingEntityUUID = event.getEntity().getUniqueId();
// if it's a mob we are tracking that matters // if it's a mob we are tracking that matters
if (toolStats.mobKill.trackedMobs.contains(livingEntityUUID)) { if (toolStats.mobKill.trackedMobs.contains(livingEntityUUID)) {
for (ItemStack current : event.getDrops()) { for (int i = 0; i < event.getDrops().size(); i++) {
ItemStack current = event.getDrops().get(i);
if (ItemChecker.isValidItem(current.getType())) { if (ItemChecker.isValidItem(current.getType())) {
addLore(current, livingEntity.getName()); ItemStack newItem = addLore(current, livingEntity.getName());
if (newItem != null) {
event.getDrops().set(i, newItem);
}
} }
} }
toolStats.mobKill.trackedMobs.remove(livingEntityUUID); toolStats.mobKill.trackedMobs.remove(livingEntityUUID);
@@ -58,13 +63,14 @@ public class EntityDeath implements Listener {
/** /**
* Adds "drop by" tag to item. * Adds "drop by" tag to item.
* *
* @param itemStack The item to add lore to. * @param oldItem The item to add lore to.
* @param mob The mob or player name. * @param mob The mob or player name.
*/ */
private void addLore(ItemStack itemStack, String mob) { private ItemStack addLore(ItemStack oldItem, String mob) {
ItemMeta meta = itemStack.getItemMeta(); ItemStack newItem = oldItem.clone();
ItemMeta meta = newItem.getItemMeta();
if (meta == null) { if (meta == null) {
return; return null;
} }
boolean hasTag = false; boolean hasTag = false;
@@ -73,13 +79,12 @@ public class EntityDeath implements Listener {
if (droppedByLore == null || droppedByLoreRaw == null) { if (droppedByLore == null || droppedByLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.dropped-by!"); toolStats.logger.warning("There is no lore message for messages.dropped-by!");
return; return null;
} }
List<String> lore; List<String> lore;
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
for (int x = 0; x < lore.size(); x++) { for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(droppedByLore)) { if (lore.get(x).contains(droppedByLore)) {
// replace existing tag // replace existing tag
@@ -97,6 +102,7 @@ public class EntityDeath implements Listener {
if (toolStats.config.getBoolean("enabled.dropped-by")) { if (toolStats.config.getBoolean("enabled.dropped-by")) {
meta.setLore(lore); meta.setLore(lore);
} }
itemStack.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem;
} }
} }

View File

@@ -28,6 +28,7 @@ import org.bukkit.block.Chest;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.StorageMinecart; import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.world.LootGenerateEvent; import org.bukkit.event.world.LootGenerateEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
@@ -49,7 +50,7 @@ public class GenerateLoot implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST)
public void onGenerateLoot(LootGenerateEvent event) { public void onGenerateLoot(LootGenerateEvent event) {
InventoryHolder inventoryHolder = event.getInventoryHolder(); InventoryHolder inventoryHolder = event.getInventoryHolder();
if (inventoryHolder == null) { if (inventoryHolder == null) {
@@ -155,7 +156,6 @@ public class GenerateLoot implements Listener {
List<String> lore; List<String> lore;
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
} else { } else {
lore = new ArrayList<>(); lore = new ArrayList<>();
} }

View File

@@ -23,6 +23,7 @@ import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.*; import org.bukkit.entity.*;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -42,7 +43,7 @@ public class PickupItem implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST)
public void onPickup(EntityPickupItemEvent event) { public void onPickup(EntityPickupItemEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -104,7 +105,6 @@ public class PickupItem implements Listener {
List<String> lore; List<String> lore;
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
} else { } else {
lore = new ArrayList<>(); lore = new ArrayList<>();
} }

View File

@@ -19,12 +19,14 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.ItemChecker; import lol.hyper.toolstats.tools.ItemChecker;
import lol.hyper.toolstats.tools.NumberFormat;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -44,7 +46,7 @@ public class PlayerFish implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGH)
public void onFish(PlayerFishEvent event) { public void onFish(PlayerFishEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -58,37 +60,46 @@ public class PlayerFish implements Listener {
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
// make sure the player is holding a fishing rod
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot()); ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot());
if (heldItem == null || heldItem.getType() == Material.AIR || heldItem.getType() != Material.FISHING_ROD) { if (heldItem == null || heldItem.getType() == Material.AIR || heldItem.getType() != Material.FISHING_ROD) {
return; return;
} }
// update the fishing rod to the new one
updateFishCount(heldItem); updateFishCount(heldItem);
// check if the player caught an item
if (event.getCaught() == null) { if (event.getCaught() == null) {
return; return;
} }
ItemStack caughtItem = ((Item) event.getCaught()).getItemStack(); ItemStack caughtItem = ((Item) event.getCaught()).getItemStack();
Item caughtItemEntity = (Item) event.getCaught();
if (ItemChecker.isValidItem(caughtItem.getType())) { if (ItemChecker.isValidItem(caughtItem.getType())) {
addNewLore(caughtItem, player); ItemStack newItem = addNewLore(caughtItem, player);
if (newItem != null) {
caughtItemEntity.setItemStack(newItem);
}
} }
} }
/** /**
* Updates a fishing rod's count. * Update a fishing rod's fish count.
* * @param fishingRod The fishing rod to update.
* @param itemStack The fishing rod to update.
*/ */
private void updateFishCount(ItemStack itemStack) { private void updateFishCount(ItemStack fishingRod) {
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = fishingRod.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(fishingRod + " does NOT have any meta! Unable to update stats.");
return; return;
} }
Integer fishCaught = null; Integer fishCaught = 0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.fishingRodCaught, PersistentDataType.INTEGER)) { if (container.has(toolStats.fishingRodCaught, PersistentDataType.INTEGER)) {
fishCaught = container.get(toolStats.fishingRodCaught, PersistentDataType.INTEGER); fishCaught = container.get(toolStats.fishingRodCaught, PersistentDataType.INTEGER);
} }
if (fishCaught == null) { if (fishCaught == null) {
fishCaught = 0; fishCaught = 0;
toolStats.logger.warning(fishingRod + " does not have valid fish-caught set! Resting to zero. This should NEVER happen.");
} }
fishCaught++; fishCaught++;
@@ -103,51 +114,65 @@ public class PlayerFish implements Listener {
} }
List<String> lore; List<String> lore;
String newLine = fishCaughtLoreRaw.replace("{fish}", NumberFormat.formatInt(fishCaught));
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
boolean hasLore = false; boolean hasLore = false;
// we do a for loop like this, we can keep track of index // we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items // this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) { for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(fishCaughtLore)) { if (lore.get(x).contains(fishCaughtLore)) {
hasLore = true; hasLore = true;
lore.set(x, fishCaughtLoreRaw.replace("{fish}", toolStats.commaFormat.format(fishCaught))); lore.set(x, newLine);
break; break;
} }
} }
// if the item has lore but doesn't have the tag, add it // if the item has lore but doesn't have the tag, add it
if (!hasLore) { if (!hasLore) {
lore.add(fishCaughtLoreRaw.replace("{fish}", toolStats.commaFormat.format(fishCaught))); lore.add(newLine);
} }
} else { } else {
// if the item has no lore, create a new list and add the string // if the item has no lore, create a new list and add the string
lore = new ArrayList<>(); lore = new ArrayList<>();
lore.add(fishCaughtLoreRaw.replace("{fish}", toolStats.commaFormat.format(fishCaught))); lore.add(newLine);
} }
/*
if (Bukkit.getPluginManager().isPluginEnabled("EvenMoreFish")) {
ListIterator<String> iterator = lore.listIterator();
while (iterator.hasNext()) {
String line = iterator.next();
toolStats.logger.info(line);
if (line.equalsIgnoreCase("§f")) {
iterator.remove();
}
}
}*/
if (toolStats.config.getBoolean("enabled.fish-caught")) { if (toolStats.config.getBoolean("enabled.fish-caught")) {
meta.setLore(lore); meta.setLore(lore);
} }
itemStack.setItemMeta(meta); fishingRod.setItemMeta(meta);
} }
/** /**
* Adds "caught by" tags to newly fished items. * Add lore to newly caught item.
* * @param originalItem The original item to add lore.
* @param itemStack The item to add lore to. * @param owner The player who caught it.
* @param owner The player who caught the item. * @return A copy of the new item with lore.
*/ */
private void addNewLore(ItemStack itemStack, Player owner) { private ItemStack addNewLore(ItemStack originalItem, Player owner) {
ItemMeta meta = itemStack.getItemMeta(); ItemStack newItem = originalItem.clone();
ItemMeta meta = originalItem.getItemMeta();
if (meta == null) { if (meta == null) {
return; return null;
} }
long timeCreated = System.currentTimeMillis(); long timeCreated = System.currentTimeMillis();
Date finalDate = new Date(timeCreated); Date finalDate = new Date(timeCreated);
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.genericOwner, PersistentDataType.LONG)) { if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.genericOwner, PersistentDataType.LONG)) {
return; return null;
} }
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
@@ -158,7 +183,7 @@ public class PlayerFish implements Listener {
if (caughtByLoreRaw == null || caughtOnLoreRaw == null) { if (caughtByLoreRaw == null || caughtOnLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.fished!"); toolStats.logger.warning("There is no lore message for messages.fished!");
return; return null;
} }
List<String> lore; List<String> lore;
@@ -168,11 +193,12 @@ public class PlayerFish implements Listener {
} else { } else {
lore = new ArrayList<>(); lore = new ArrayList<>();
} }
if (toolStats.checkConfig(itemStack, "fished-tag")) { if (toolStats.checkConfig(newItem, "fished-tag")) {
lore.add(caughtOnLoreRaw.replace("{date}", toolStats.dateFormat.format(finalDate))); lore.add(caughtOnLoreRaw.replace("{date}", toolStats.dateFormat.format(finalDate)));
lore.add(caughtByLoreRaw.replace("{player}", owner.getName())); lore.add(caughtByLoreRaw.replace("{player}", owner.getName()));
meta.setLore(lore);
} }
meta.setLore(lore); newItem.setItemMeta(meta);
itemStack.setItemMeta(meta); return newItem;
} }
} }

View File

@@ -18,12 +18,14 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.NumberFormat;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Sheep; import org.bukkit.entity.Sheep;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -42,7 +44,7 @@ public class SheepShear implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST)
public void onShear(PlayerInteractEntityEvent event) { public void onShear(PlayerInteractEntityEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -56,7 +58,8 @@ public class SheepShear implements Listener {
return; return;
} }
// check if the player is right-clicking with shears only // check if the player is right-clicking with shears only
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot()); int heldItemSlot = player.getInventory().getHeldItemSlot();
ItemStack heldItem = player.getInventory().getItem(heldItemSlot);
if (heldItem == null || heldItem.getType() == Material.AIR || heldItem.getType() != Material.SHEARS) { if (heldItem == null || heldItem.getType() == Material.AIR || heldItem.getType() != Material.SHEARS) {
return; return;
} }
@@ -64,27 +67,34 @@ public class SheepShear implements Listener {
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
// make sure the sheep is not sheared // make sure the sheep is not sheared
if (!sheep.isSheared()) { if (!sheep.isSheared()) {
addLore(heldItem); ItemStack newShears = addLore(heldItem);
if (newShears != null) {
player.getInventory().setItem(heldItemSlot, newShears);
}
} }
} }
/** /**
* Adds tags to shears. * Adds tags to shears.
* *
* @param itemStack The shears. * @param oldShears The shears.
*/ */
private void addLore(ItemStack itemStack) { private ItemStack addLore(ItemStack oldShears) {
ItemMeta meta = itemStack.getItemMeta(); ItemStack newShears = oldShears.clone();
ItemMeta meta = newShears.getItemMeta();
if (meta == null) { if (meta == null) {
return; toolStats.logger.warning(newShears + " does NOT have any meta! Unable to update stats.");
return null;
} }
Integer sheepSheared = 0; Integer sheepSheared = 0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.shearsSheared, PersistentDataType.INTEGER)) { if (container.has(toolStats.shearsSheared, PersistentDataType.INTEGER)) {
sheepSheared = container.get(toolStats.shearsSheared, PersistentDataType.INTEGER); sheepSheared = container.get(toolStats.shearsSheared, PersistentDataType.INTEGER);
} }
if (sheepSheared == null) { if (sheepSheared == null) {
sheepSheared = 0; sheepSheared = 0;
toolStats.logger.warning(newShears + " does not have valid sheared set! Resting to zero. This should NEVER happen.");
} }
sheepSheared++; sheepSheared++;
@@ -95,35 +105,36 @@ public class SheepShear implements Listener {
if (sheepShearedLore == null || sheepShearedLoreRaw == null) { if (sheepShearedLore == null || sheepShearedLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.sheep-sheared!"); toolStats.logger.warning("There is no lore message for messages.sheep-sheared!");
return; return null;
} }
List<String> lore; List<String> lore;
String newLine = sheepShearedLoreRaw.replace("{sheep}", NumberFormat.formatInt(sheepSheared));
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
boolean hasLore = false; boolean hasLore = false;
// we do a for loop like this, we can keep track of index // we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items // this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) { for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(sheepShearedLore)) { if (lore.get(x).contains(sheepShearedLore)) {
hasLore = true; hasLore = true;
lore.set(x, sheepShearedLoreRaw.replace("{sheep}", toolStats.commaFormat.format(sheepSheared))); lore.set(x, newLine);
break; break;
} }
} }
// if the item has lore but doesn't have the tag, add it // if the item has lore but doesn't have the tag, add it
if (!hasLore) { if (!hasLore) {
lore.add(sheepShearedLoreRaw.replace("{sheep}", toolStats.commaFormat.format(sheepSheared))); lore.add(newLine);
} }
} else { } else {
// if the item has no lore, create a new list and add the string // if the item has no lore, create a new list and add the string
lore = new ArrayList<>(); lore = new ArrayList<>();
lore.add(sheepShearedLoreRaw.replace("{sheep}", toolStats.commaFormat.format(sheepSheared))); lore.add(newLine);
} }
if (toolStats.config.getBoolean("enabled.sheep-sheared")) { if (toolStats.config.getBoolean("enabled.sheep-sheared")) {
meta.setLore(lore); meta.setLore(lore);
} }
itemStack.setItemMeta(meta); newShears.setItemMeta(meta);
return newShears;
} }
} }

View File

@@ -25,6 +25,7 @@ import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
@@ -47,7 +48,7 @@ public class VillagerTrade implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST)
public void onTrade(InventoryClickEvent event) { public void onTrade(InventoryClickEvent event) {
if (event.isCancelled() || event.getCurrentItem() == null) { if (event.isCancelled() || event.getCurrentItem() == null) {
return; return;
@@ -87,13 +88,15 @@ public class VillagerTrade implements Listener {
/** /**
* Adds "traded by" tags to item. * Adds "traded by" tags to item.
* *
* @param itemStack The item to add lore. * @param oldItem The item to add lore.
* @param owner The player who traded. * @param owner The player who traded.
* @return The item with lore. * @return The item with lore.
*/ */
private ItemStack addLore(ItemStack itemStack, Player owner) { private ItemStack addLore(ItemStack oldItem, Player owner) {
ItemMeta meta = itemStack.getItemMeta(); ItemStack newItem = oldItem.clone();
ItemMeta meta = newItem.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(newItem + " does NOT have any meta! Unable to update stats.");
return null; return null;
} }
long timeCreated = System.currentTimeMillis(); long timeCreated = System.currentTimeMillis();
@@ -118,16 +121,15 @@ public class VillagerTrade implements Listener {
List<String> lore; List<String> lore;
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.getLore();
assert lore != null;
} else { } else {
lore = new ArrayList<>(); lore = new ArrayList<>();
} }
if (toolStats.checkConfig(itemStack, "traded-tag")) { if (toolStats.checkConfig(newItem, "traded-tag")) {
lore.add(tradedOnLoreRaw.replace("{date}", toolStats.dateFormat.format(finalDate))); lore.add(tradedOnLoreRaw.replace("{date}", toolStats.dateFormat.format(finalDate)));
lore.add(tradedByLoreRaw.replace("{player}", owner.getName())); lore.add(tradedByLoreRaw.replace("{player}", owner.getName()));
meta.setLore(lore);
} }
meta.setLore(lore); newItem.setItemMeta(meta);
itemStack.setItemMeta(meta); return newItem;
return itemStack;
} }
} }

View File

@@ -0,0 +1,56 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package lol.hyper.toolstats.tools;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
public class NumberFormat {
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,###.00", new DecimalFormatSymbols(Locale.getDefault()));
private static final DecimalFormat COMMA_FORMAT = new DecimalFormat("#,###", new DecimalFormatSymbols(Locale.getDefault()));
/**
* Formats a number to make it pretty. Example: 4322 to 4,322
* @param number The number to format.
* @return The formatted number.
*/
public static String formatInt(int number) {
String finalNumber = COMMA_FORMAT.format(number);
// hardcode French system because Minecraft bad
if (Locale.getDefault() == Locale.FRANCE || Locale.getDefault() == Locale.FRENCH) {
finalNumber = finalNumber.replaceAll("[\\x{202f}\\x{00A0}]", " ");
}
return finalNumber;
}
/**
* Formats a number to make it pretty. Example: 4322.33 to 4,322.33
* @param number The number to format.
* @return The formatted number.
*/
public static String formatDouble(double number) {
String finalNumber = DECIMAL_FORMAT.format(number);
// hardcode French system because Minecraft bad
if (Locale.getDefault() == Locale.FRANCE || Locale.getDefault() == Locale.FRENCH) {
finalNumber = finalNumber.replaceAll("[\\x{202f}\\x{00A0}]", " ");
}
return finalNumber;
}
}

View File

@@ -98,4 +98,9 @@ messages:
crafting: "&cCrafting items via shift clicking does not fully apply tags to each item. This is a limitation with the Bukkit API." 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." trading: "&cTrading items via shift clicking does not fully apply tags to each item. This is a limitation with the Bukkit API."
# Change the default formatting for dates.
# See: https://www.digitalocean.com/community/tutorials/java-simpledateformat-java-date-format
# Example: "dd/mm/yyyy"
date-format: "M/dd/yyyy"
config-version: 3 config-version: 3