Compare commits

...

43 Commits
1.5.1 ... 1.6.3

Author SHA1 Message Date
hyperdefined
72e869d5e2 Update pom.xml 2023-05-22 20:22:02 -04:00
hyperdefined
300fe56c5a use continue here, not return
closes #33
2023-05-22 20:21:16 -04:00
hyperdefined
fe5e55d746 Update pom.xml 2023-05-22 00:05:00 -04:00
hyperdefined
0574fb61a6 fix traded-by tags :3333 2023-05-22 00:03:42 -04:00
hyperdefined
433ab547cb minor adjustments 2023-05-21 23:49:07 -04:00
hyperdefined
9746789f2b added int damage value 2023-04-21 15:31:54 -04:00
hyperdefined
fd3c3ca8ed Merge pull request #31 from hyperdefined/dependabot/maven/org.bstats-bstats-bukkit-3.0.2
Bump bstats-bukkit from 3.0.1 to 3.0.2
2023-04-10 16:38:20 -04:00
hyperdefined
c6dc2c3368 Merge pull request #32 from hyperdefined/dependabot/maven/net.kyori-adventure-text-minimessage-4.13.1
Bump adventure-text-minimessage from 4.13.0 to 4.13.1
2023-04-10 16:36:01 -04:00
dependabot[bot]
d11211b1c7 Bump adventure-text-minimessage from 4.13.0 to 4.13.1
Bumps [adventure-text-minimessage](https://github.com/KyoriPowered/adventure) from 4.13.0 to 4.13.1.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.13.0...v4.13.1)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-minimessage
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 12:02:00 +00:00
dependabot[bot]
e8c2296bd7 Bump bstats-bukkit from 3.0.1 to 3.0.2
Bumps [bstats-bukkit](https://github.com/Bastian/bStats-Metrics) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.1...v3.0.2)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-29 12:00:34 +00:00
hyperdefined
d8f296a085 Merge pull request #29 from hyperdefined/dependabot/maven/net.kyori-adventure-text-minimessage-4.13.0
Bump adventure-text-minimessage from 4.12.0 to 4.13.0
2023-03-16 10:42:18 -04:00
hyperdefined
58dee809f3 Merge pull request #30 from hyperdefined/dependabot/maven/net.kyori-adventure-platform-bukkit-4.3.0
Bump adventure-platform-bukkit from 4.2.0 to 4.3.0
2023-03-16 10:40:21 -04:00
dependabot[bot]
590cf6e8b0 Bump adventure-platform-bukkit from 4.2.0 to 4.3.0
Bumps [adventure-platform-bukkit](https://github.com/KyoriPowered/adventure-platform) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/KyoriPowered/adventure-platform/releases)
- [Commits](https://github.com/KyoriPowered/adventure-platform/compare/v4.2.0...v4.3.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-platform-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-16 12:00:42 +00:00
dependabot[bot]
a7cc8671bd Bump adventure-text-minimessage from 4.12.0 to 4.13.0
Bumps [adventure-text-minimessage](https://github.com/KyoriPowered/adventure) from 4.12.0 to 4.13.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.12.0...v4.13.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-minimessage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-14 12:00:26 +00:00
hyperdefined
37a7c642d3 Merge pull request #28 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.11.0
Bump maven-compiler-plugin from 3.10.1 to 3.11.0
2023-02-27 18:57:28 -05:00
dependabot[bot]
31acdd9527 Bump maven-compiler-plugin from 3.10.1 to 3.11.0
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.1 to 3.11.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.1...maven-compiler-plugin-3.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 12:10:48 +00:00
hyperdefined
9b0ac2d912 stfu deepsource 2023-02-20 22:28:33 -05:00
hyperdefined
4ea9e1600b return item lore back rather than nulling it 2023-02-20 22:02:48 -05:00
hyperdefined
72b8b31779 Merge pull request #27 from hyperdefined/dependabot/maven/org.bstats-bstats-bukkit-3.0.1
Bump bstats-bukkit from 3.0.0 to 3.0.1
2023-02-16 17:43:01 -05:00
dependabot[bot]
fce135f2f8 Bump bstats-bukkit from 3.0.0 to 3.0.1
Bumps [bstats-bukkit](https://github.com/Bastian/bStats-Metrics) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 12:09:50 +00:00
hyperdefined
425b315104 Revert "Update ToolStats.java"
This reverts commit f2739cf433.
2023-01-16 13:41:50 -05:00
hyperdefined
50a0bc800c small command changes 2022-12-12 17:05:46 -05:00
hyperdefined
583cd824f4 Update EntityDamage.java 2022-12-12 12:06:06 -05:00
hyperdefined
d63f00166d Update NumberFormat.java 2022-12-12 11:30:26 -05:00
hyperdefined
0bcb0c7370 added missing tracking for mobs 2022-12-12 11:21:06 -05:00
hyperdefined
e4859de614 Merge pull request #26 from hyperdefined/dependabot/maven/net.kyori-adventure-platform-bukkit-4.2.0
Bump adventure-platform-bukkit from 4.1.2 to 4.2.0
2022-12-11 23:41:50 -05:00
dependabot[bot]
f7c1af153f Bump adventure-platform-bukkit from 4.1.2 to 4.2.0
Bumps [adventure-platform-bukkit](https://github.com/KyoriPowered/adventure-platform) from 4.1.2 to 4.2.0.
- [Release notes](https://github.com/KyoriPowered/adventure-platform/releases)
- [Commits](https://github.com/KyoriPowered/adventure-platform/compare/v4.1.2...v4.2.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-platform-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-09 11:05:50 +00:00
hyperdefined
946dc591f5 Update pom.xml 2022-12-08 13:40:27 -05:00
hyperdefined
d279569199 Update EntityDamage.java 2022-12-08 13:40:12 -05:00
hyperdefined
f2739cf433 Update ToolStats.java 2022-12-07 16:21:14 -05:00
hyperdefined
bef854be14 removed logging 2022-12-07 15:19:32 -05:00
hyperdefined
2c971da1b9 unify lore management 2022-12-07 14:56:57 -05:00
hyperdefined
2e0ee18594 more possible plugin compatibility? 2022-12-01 17:56:41 -05:00
hyperdefined
98a5f20a86 better offhand/main hand detection 2022-11-30 14:41:34 -05:00
hyperdefined
dd8a0db3b6 fix using rods in offhand 2022-11-30 14:22:35 -05:00
hyperdefined
fee7d5cd99 Merge pull request #25 from hyperdefined/dependabot/maven/net.kyori-adventure-text-minimessage-4.12.0
Bump adventure-text-minimessage from 4.11.0 to 4.12.0
2022-11-29 23:21:12 -05:00
hyperdefined
70ebf49958 Merge branch 'master' of https://github.com/hyperdefined/ToolStats 2022-11-29 20:06:40 -05:00
dependabot[bot]
50d2ec0507 Bump adventure-text-minimessage from 4.11.0 to 4.12.0
Bumps [adventure-text-minimessage](https://github.com/KyoriPowered/adventure) from 4.11.0 to 4.12.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.11.0...v4.12.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-minimessage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-28 11:09:14 +00:00
hyperdefined
6428925e40 support for complete customization of numbers
closes #24
2022-11-24 00:44:59 -05:00
hyperdefined
1d4faa89a1 Merge branch 'master' of https://github.com/hyperdefined/ToolStats 2022-11-23 02:22:46 -05:00
hyperdefined
1ad650f42b Merge pull request #23 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.4.1
Bump maven-shade-plugin from 3.4.0 to 3.4.1
2022-11-06 19:20:20 -05:00
hyperdefined
fdb6626c42 update all items 1 tick later
this should fix #18
2022-11-04 20:26:55 -04:00
dependabot[bot]
cd80e6a675 Bump maven-shade-plugin from 3.4.0 to 3.4.1
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.4.0...maven-shade-plugin-3.4.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-27 11:23:52 +00:00
16 changed files with 564 additions and 478 deletions

12
pom.xml
View File

@@ -23,7 +23,7 @@
<groupId>lol.hyper</groupId> <groupId>lol.hyper</groupId>
<artifactId>toolstats</artifactId> <artifactId>toolstats</artifactId>
<version>1.5.1</version> <version>1.6.3</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ToolStats</name> <name>ToolStats</name>
@@ -51,7 +51,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version> <version>3.11.0</version>
<configuration> <configuration>
<source>${java.version}</source> <source>${java.version}</source>
<target>${java.version}</target> <target>${java.version}</target>
@@ -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.4.0</version> <version>3.4.1</version>
<configuration> <configuration>
<relocations> <relocations>
<relocation> <relocation>
@@ -115,7 +115,7 @@
<dependency> <dependency>
<groupId>org.bstats</groupId> <groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId> <artifactId>bstats-bukkit</artifactId>
<version>3.0.0</version> <version>3.0.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -127,13 +127,13 @@
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId> <artifactId>adventure-text-minimessage</artifactId>
<version>4.11.0</version> <version>4.13.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId> <artifactId>adventure-platform-bukkit</artifactId>
<version>4.1.2</version> <version>4.3.0</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -21,6 +21,8 @@ import lol.hyper.githubreleaseapi.GitHubRelease;
import lol.hyper.githubreleaseapi.GitHubReleaseAPI; import lol.hyper.githubreleaseapi.GitHubReleaseAPI;
import lol.hyper.toolstats.commands.CommandToolStats; import lol.hyper.toolstats.commands.CommandToolStats;
import lol.hyper.toolstats.events.*; import lol.hyper.toolstats.events.*;
import lol.hyper.toolstats.tools.ItemLore;
import lol.hyper.toolstats.tools.NumberFormat;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -33,10 +35,6 @@ 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.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.logging.Logger; import java.util.logging.Logger;
public final class ToolStats extends JavaPlugin { public final class ToolStats extends JavaPlugin {
@@ -57,10 +55,11 @@ public final class ToolStats extends JavaPlugin {
public final NamespacedKey shearsSheared = new NamespacedKey(this, "sheared"); public final NamespacedKey shearsSheared = new NamespacedKey(this, "sheared");
// stores how much damage armor has taken // stores how much damage armor has taken
public final NamespacedKey armorDamage = new NamespacedKey(this, "damage-taken"); public final NamespacedKey armorDamage = new NamespacedKey(this, "damage-taken");
// stores how much damage armor has taken (as int)
public final NamespacedKey armorDamageInt = new NamespacedKey(this, "damage-taken-int");
// 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 SimpleDateFormat dateFormat;
public BlocksMined blocksMined; public BlocksMined blocksMined;
public ChunkPopulate chunkPopulate; public ChunkPopulate chunkPopulate;
public CraftItem craftItem; public CraftItem craftItem;
@@ -73,14 +72,17 @@ public final class ToolStats extends JavaPlugin {
public SheepShear sheepShear; public SheepShear sheepShear;
public VillagerTrade villagerTrade; public VillagerTrade villagerTrade;
public CommandToolStats commandToolStats; public CommandToolStats commandToolStats;
public ItemLore itemLore;
public final Logger logger = this.getLogger(); public final Logger logger = this.getLogger();
public final File configFile = new File(this.getDataFolder(), "config.yml"); public final File configFile = new File(this.getDataFolder(), "config.yml");
public FileConfiguration config; public FileConfiguration config;
public final int CONFIG_VERSION = 3; public final int CONFIG_VERSION = 4;
private BukkitAudiences adventure; private BukkitAudiences adventure;
public NumberFormat numberFormat;
@Override @Override
public void onEnable() { public void onEnable() {
this.adventure = BukkitAudiences.create(this); this.adventure = BukkitAudiences.create(this);
@@ -101,6 +103,7 @@ public final class ToolStats extends JavaPlugin {
sheepShear = new SheepShear(this); sheepShear = new SheepShear(this);
villagerTrade = new VillagerTrade(this); villagerTrade = new VillagerTrade(this);
commandToolStats = new CommandToolStats(this); commandToolStats = new CommandToolStats(this);
itemLore = new ItemLore(this);
Bukkit.getServer().getPluginManager().registerEvents(blocksMined, this); Bukkit.getServer().getPluginManager().registerEvents(blocksMined, this);
Bukkit.getServer().getPluginManager().registerEvents(chunkPopulate, this); Bukkit.getServer().getPluginManager().registerEvents(chunkPopulate, this);
@@ -127,19 +130,7 @@ public final class ToolStats extends JavaPlugin {
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"); numberFormat = new NumberFormat(this);
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() {

View File

@@ -18,7 +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.ItemChecker;
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;
@@ -26,6 +26,7 @@ import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.TabExecutor; import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -72,6 +73,10 @@ public class CommandToolStats implements TabExecutor {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.").color(NamedTextColor.RED)); audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.").color(NamedTextColor.RED));
return true; return true;
} }
if (sender instanceof ConsoleCommandSender) {
audiences.sender(sender).sendMessage(Component.text("You must be a player for this command.").color(NamedTextColor.RED));
return true;
}
if (args.length == 2 && args[1].equalsIgnoreCase("confirm")) { if (args.length == 2 && args[1].equalsIgnoreCase("confirm")) {
if (!sender.hasPermission("toolstats.reset.confirm")) { if (!sender.hasPermission("toolstats.reset.confirm")) {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.").color(NamedTextColor.RED)); audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.").color(NamedTextColor.RED));
@@ -79,8 +84,8 @@ public class CommandToolStats implements TabExecutor {
} }
Player player = (Player) sender; Player player = (Player) sender;
ItemStack heldItem = player.getInventory().getItemInMainHand(); ItemStack heldItem = player.getInventory().getItemInMainHand();
if (heldItem.getType() == Material.AIR) { if (ItemChecker.isValidItem(heldItem.getType())) {
audiences.sender(sender).sendMessage(Component.text("You must hold an item!").color(NamedTextColor.RED)); audiences.sender(sender).sendMessage(Component.text("You must hold a valid item.").color(NamedTextColor.RED));
return true; return true;
} }
fixItemLore(heldItem, player); fixItemLore(heldItem, player);
@@ -151,7 +156,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) { if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) {
Long time = container.get(toolStats.timeCreated, PersistentDataType.LONG); Long time = container.get(toolStats.timeCreated, PersistentDataType.LONG);
if (time != null) { if (time != null) {
lore.add(toolStats.getLoreFromConfig("looted.found-on", true).replace("{date}", toolStats.dateFormat.format(new Date(time)))); lore.add(toolStats.getLoreFromConfig("looted.found-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
} }
} }
finalMeta.setLore(lore); finalMeta.setLore(lore);
@@ -193,19 +198,19 @@ public class CommandToolStats implements TabExecutor {
// show how when the item was created based on the previous lore // show how when the item was created based on the previous lore
switch (type) { switch (type) {
case "DEFAULT": { case "DEFAULT": {
lore.add(toolStats.getLoreFromConfig("created.created-on", true).replace("{date}", toolStats.dateFormat.format(new Date(time)))); lore.add(toolStats.getLoreFromConfig("created.created-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
break; break;
} }
case "CAUGHT": { case "CAUGHT": {
lore.add(toolStats.getLoreFromConfig("fished.caught-on", true).replace("{date}", toolStats.dateFormat.format(new Date(time)))); lore.add(toolStats.getLoreFromConfig("fished.caught-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
break; break;
} }
case "LOOTED": { case "LOOTED": {
lore.add(toolStats.getLoreFromConfig("looted.found-on", true).replace("{date}", toolStats.dateFormat.format(new Date(time)))); lore.add(toolStats.getLoreFromConfig("looted.found-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
break; break;
} }
case "TRADED": { case "TRADED": {
lore.add(toolStats.getLoreFromConfig("traded.traded-on", true).replace("{date}", toolStats.dateFormat.format(new Date(time)))); lore.add(toolStats.getLoreFromConfig("traded.traded-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
break; break;
} }
} }
@@ -216,7 +221,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}", NumberFormat.formatInt(kills))); lore.add(toolStats.getLoreFromConfig("kills.player", true).replace("{kills}", toolStats.numberFormat.formatInt(kills)));
} }
} }
} }
@@ -224,7 +229,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}", NumberFormat.formatInt(kills))); lore.add(toolStats.getLoreFromConfig("kills.mob", true).replace("{kills}", toolStats.numberFormat.formatInt(kills)));
} }
} }
} }
@@ -232,7 +237,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}", NumberFormat.formatInt(blocksMined))); lore.add(toolStats.getLoreFromConfig("blocks-mined", true).replace("{blocks}", toolStats.numberFormat.formatInt(blocksMined)));
} }
} }
} }
@@ -240,7 +245,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}", NumberFormat.formatInt(fish))); lore.add(toolStats.getLoreFromConfig("fished.fish-caught", true).replace("{fish}", toolStats.numberFormat.formatInt(fish)));
} }
} }
} }
@@ -248,7 +253,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}", NumberFormat.formatInt(sheep))); lore.add(toolStats.getLoreFromConfig("sheep-sheared", true).replace("{sheep}", toolStats.numberFormat.formatInt(sheep)));
} }
} }
} }
@@ -256,7 +261,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}", NumberFormat.formatDouble(damage))); lore.add(toolStats.getLoreFromConfig("damage-taken", true).replace("{damage}", toolStats.numberFormat.formatDouble(damage)));
} }
} }
} }

View File

@@ -19,20 +19,18 @@ 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.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.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;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class BlocksMined implements Listener { public class BlocksMined implements Listener {
@@ -43,7 +41,7 @@ public class BlocksMined implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler (priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.MONITOR)
public void onBreak(BlockBreakEvent event) { public void onBreak(BlockBreakEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -53,16 +51,13 @@ public class BlocksMined implements Listener {
return; return;
} }
// if the player mines something with their fist // if the player mines something with their fist
int heldItemSlot = player.getInventory().getHeldItemSlot(); PlayerInventory inventory = player.getInventory();
ItemStack heldItem = player.getInventory().getItem(heldItemSlot); ItemStack heldItem = inventory.getItemInMainHand();
if (heldItem == null || heldItem.getType() == Material.AIR) {
return;
}
// only check certain items // only check certain items
if (!ItemChecker.isMineTool(heldItem.getType())) { if (!ItemChecker.isMineTool(heldItem.getType())) {
return; return;
} }
// if it's an item we want, update the stats // update the blocks mined
updateBlocksMined(heldItem); updateBlocksMined(heldItem);
} }
@@ -88,40 +83,12 @@ public class BlocksMined implements Listener {
blocksMined++; blocksMined++;
container.set(toolStats.genericMined, PersistentDataType.INTEGER, blocksMined); container.set(toolStats.genericMined, PersistentDataType.INTEGER, blocksMined);
String configLore = toolStats.getLoreFromConfig("blocks-mined", false); String blocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined);
String configLoreRaw = toolStats.getLoreFromConfig("blocks-mined", true); List<String> newLore = toolStats.itemLore.addItemLore(meta, "{blocks}", blocksMinedFormatted, "blocks-mined");
if (configLore == null || configLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.blocks-mined!");
return;
}
List<String> lore;
String newLine = configLoreRaw.replace("{blocks}", NumberFormat.formatInt(blocksMined));
if (meta.hasLore()) {
lore = meta.getLore();
boolean hasLore = false;
// we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(configLore)) {
hasLore = true;
lore.set(x, newLine);
break;
}
}
// if the item has lore but doesn't have the tag, add it
if (!hasLore) {
lore.add(newLine);
}
} else {
// if the item has no lore, create a new list and add the string
lore = new ArrayList<>();
lore.add(newLine);
}
// do we add the lore based on the config? // do we add the lore based on the config?
if (toolStats.checkConfig(playerTool, "blocks-mined")) { if (toolStats.checkConfig(playerTool, "blocks-mined")) {
meta.setLore(lore); meta.setLore(newLore);
} }
playerTool.setItemMeta(meta); playerTool.setItemMeta(meta);
} }

View File

@@ -36,7 +36,7 @@ import org.bukkit.persistence.PersistentDataType;
public class ChunkPopulate implements Listener { public class ChunkPopulate implements Listener {
// this tags all elytras with a "new" tag // this tags all elytras with a "new" tag
// this let's us track any new elytras player loot // this lets us track any new elytras player loot
private final ToolStats toolStats; private final ToolStats toolStats;
@@ -55,21 +55,22 @@ public class ChunkPopulate implements Listener {
Chunk chunk = event.getChunk(); Chunk chunk = event.getChunk();
for (Entity entity : chunk.getEntities()) { for (Entity entity : chunk.getEntities()) {
// if there is a new item frame // if there is a new item frame
if (entity instanceof ItemFrame) { if (!(entity instanceof ItemFrame)) {
ItemFrame itemFrame = (ItemFrame) entity; continue;
// if the item frame has an elytra }
if (itemFrame.getItem().getType() == Material.ELYTRA) { ItemFrame itemFrame = (ItemFrame) entity;
ItemStack elytraCopy = itemFrame.getItem(); // if the item frame has an elytra
ItemMeta meta = elytraCopy.getItemMeta(); if (itemFrame.getItem().getType() == Material.ELYTRA) {
if (meta == null) { ItemStack elytraCopy = itemFrame.getItem();
return; ItemMeta meta = elytraCopy.getItemMeta();
} if (meta == null) {
// add the new tag so we know it's new continue;
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(toolStats.newElytra, PersistentDataType.INTEGER, 1);
elytraCopy.setItemMeta(meta);
itemFrame.setItem(elytraCopy);
} }
// add the new tag so we know it's new
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(toolStats.newElytra, PersistentDataType.INTEGER, 1);
elytraCopy.setItemMeta(meta);
itemFrame.setItem(elytraCopy);
} }
} }
}, 20); }, 20);

View File

@@ -128,7 +128,7 @@ public class CraftItem implements Listener {
} }
// do we add the lore based on the config? // do we add the lore based on the config?
if (toolStats.checkConfig(itemStack, "created-date")) { if (toolStats.checkConfig(itemStack, "created-date")) {
lore.add(createdOnRaw.replace("{date}", toolStats.dateFormat.format(finalDate))); lore.add(createdOnRaw.replace("{date}", toolStats.numberFormat.formatDate(finalDate)));
} }
if (toolStats.checkConfig(itemStack, "created-by")) { if (toolStats.checkConfig(itemStack, "created-by")) {
lore.add(createdByRaw.replace("{player}", owner.getName())); lore.add(createdByRaw.replace("{player}", owner.getName()));

View File

@@ -19,7 +19,7 @@ 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.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.*; import org.bukkit.entity.*;
@@ -47,7 +47,7 @@ public class EntityDamage implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.MONITOR)
public void onDamage(EntityDamageByEntityEvent event) { public void onDamage(EntityDamageByEntityEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -56,7 +56,7 @@ public class EntityDamage implements Listener {
if (!(event.getEntity() instanceof LivingEntity)) { if (!(event.getEntity() instanceof LivingEntity)) {
return; return;
} }
LivingEntity livingEntity = (LivingEntity) event.getEntity(); LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// ignore void and /kill damage // ignore void and /kill damage
EntityDamageEvent.DamageCause cause = event.getCause(); EntityDamageEvent.DamageCause cause = event.getCause();
@@ -65,89 +65,103 @@ public class EntityDamage implements Listener {
} }
// mob is going to die // mob is going to die
if (livingEntity.getHealth() - event.getFinalDamage() <= 0) { if (mobBeingAttacked.getHealth() - event.getFinalDamage() <= 0) {
// a player is killing something // a player is killing something
if (event.getDamager() instanceof Player) { if (event.getDamager() instanceof Player) {
Player player = (Player) event.getDamager(); Player attackingPlayer = (Player) event.getDamager();
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (attackingPlayer.getGameMode() == GameMode.CREATIVE || attackingPlayer.getGameMode() == GameMode.SPECTATOR) {
return;
}
// a player killed something with their fist
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot());
if (heldItem == null || heldItem.getType() == Material.AIR) {
return; return;
} }
PlayerInventory attackingPlayerInventory = attackingPlayer.getInventory();
ItemStack heldItem = attackingPlayerInventory.getItemInMainHand();
// only check certain items // only check certain items
if (!ItemChecker.isMeleeWeapon(heldItem.getType())) { if (!ItemChecker.isMeleeWeapon(heldItem.getType())) {
return; return;
} }
// a player is killing another player // a player is killing another player
if (livingEntity instanceof Player) { if (mobBeingAttacked instanceof Player) {
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), updatePlayerKills(heldItem)); updatePlayerKills(heldItem);
return; return;
} }
// player is killing regular mob // player is killing regular mob
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), updateMobKills(heldItem)); updateMobKills(heldItem);
trackedMobs.add(livingEntity.getUniqueId()); trackedMobs.add(mobBeingAttacked.getUniqueId());
} }
// trident is being thrown at something // trident is being thrown at something
if (event.getDamager() instanceof Trident) { if (event.getDamager() instanceof Trident) {
Trident trident = (Trident) event.getDamager(); Trident trident = (Trident) event.getDamager();
ItemStack clone; ItemStack newTrident;
// trident is killing player // trident is killing player
if (livingEntity instanceof Player) { if (mobBeingAttacked instanceof Player) {
clone = updatePlayerKills(trident.getItem()); newTrident = tridentPlayerKills(trident.getItem());
} else { } else {
clone = updateMobKills(trident.getItem()); // trident is killing a mob
newTrident = tridentMobKills(trident.getItem());
trackedMobs.add(mobBeingAttacked.getUniqueId());
} }
if (clone == null) { if (newTrident != null) {
return; trident.setItem(newTrident);
} }
trident.setItem(clone);
} }
// arrow is being shot // arrow is being shot
if (event.getDamager() instanceof Arrow) { if (event.getDamager() instanceof Arrow) {
Arrow arrow = (Arrow) event.getDamager(); Arrow arrow = (Arrow) event.getDamager();
// if the shooter is a player // if the shooter is a player
if (arrow.getShooter() instanceof Player) { if (arrow.getShooter() instanceof Player) {
Player player = (Player) arrow.getShooter(); Player shootingPlayer = (Player) arrow.getShooter();
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (shootingPlayer.getGameMode() == GameMode.CREATIVE || shootingPlayer.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot()); PlayerInventory inventory = shootingPlayer.getInventory();
if (heldItem == null) { boolean isMainHand = inventory.getItemInMainHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW;
ItemStack heldBow = null;
if (isMainHand) {
heldBow = inventory.getItemInMainHand();
}
if (isOffHand) {
heldBow = inventory.getItemInOffHand();
}
// if the player is hold a bow in both hands
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
heldBow = inventory.getItemInMainHand();
}
// player swapped
if (heldBow == null) {
return; return;
} }
// if the player is holding the bow/crossbow
// if they switch then oh well // player is shooting another player
if (heldItem.getType() == Material.BOW || heldItem.getType() == Material.CROSSBOW) { if (mobBeingAttacked instanceof Player) {
if (livingEntity instanceof Player) { updatePlayerKills(heldBow);
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), updatePlayerKills(heldItem)); } else {
} else { updateMobKills(heldBow);
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), updateMobKills(heldItem)); trackedMobs.add(mobBeingAttacked.getUniqueId());
}
} }
} }
} }
} }
// player is taken damage but not being killed // player is taken damage but not being killed
if (livingEntity instanceof Player) { if (mobBeingAttacked instanceof Player) {
Player player = (Player) livingEntity; Player playerTakingDamage = (Player) mobBeingAttacked;
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
PlayerInventory inventory = player.getInventory(); PlayerInventory playerInventory = playerTakingDamage.getInventory();
for (ItemStack armor : inventory.getArmorContents()) { for (ItemStack armorPiece : playerInventory.getArmorContents()) {
if (armor != null) { if (armorPiece != null) {
if (ItemChecker.isArmor(armor.getType())) { if (ItemChecker.isArmor(armorPiece.getType())) {
updateArmorDamage(armor, event.getFinalDamage()); updateDamage(armorPiece, event.getFinalDamage());
} }
} }
} }
} }
} }
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.MONITOR)
public void onDamage(EntityDamageEvent event) { public void onDamage(EntityDamageEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) { if (!(event.getEntity() instanceof LivingEntity)) {
return; return;
@@ -159,25 +173,25 @@ public class EntityDamage implements Listener {
return; return;
} }
LivingEntity livingEntity = (LivingEntity) event.getEntity(); LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// player is taken damage but not being killed // player is taken damage but not being killed
if (livingEntity instanceof Player) { if (mobBeingAttacked instanceof Player) {
Player player = (Player) livingEntity; Player playerTakingDamage = (Player) mobBeingAttacked;
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
PlayerInventory inventory = player.getInventory(); PlayerInventory playerInventory = playerTakingDamage.getInventory();
for (ItemStack armor : inventory.getArmorContents()) { for (ItemStack armorPiece : playerInventory.getArmorContents()) {
if (armor != null) { if (armorPiece != null) {
if (ItemChecker.isArmor(armor.getType())) { if (ItemChecker.isArmor(armorPiece.getType())) {
updateArmorDamage(armor, event.getFinalDamage()); updateDamage(armorPiece, event.getFinalDamage());
} }
} }
} }
} }
} }
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.MONITOR)
public void onDamage(EntityDamageByBlockEvent event) { public void onDamage(EntityDamageByBlockEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) { if (!(event.getEntity() instanceof LivingEntity)) {
return; return;
@@ -189,18 +203,18 @@ public class EntityDamage implements Listener {
return; return;
} }
LivingEntity livingEntity = (LivingEntity) event.getEntity(); LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// player is taken damage but not being killed // player is taken damage but not being killed
if (livingEntity instanceof Player) { if (mobBeingAttacked instanceof Player) {
Player player = (Player) livingEntity; Player playerTakingDamage = (Player) mobBeingAttacked;
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
PlayerInventory inventory = player.getInventory(); PlayerInventory playerInventory = playerTakingDamage.getInventory();
for (ItemStack armor : inventory.getArmorContents()) { for (ItemStack armorPiece : playerInventory.getArmorContents()) {
if (armor != null) { if (armorPiece != null) {
if (ItemChecker.isArmor(armor.getType())) { if (ItemChecker.isArmor(armorPiece.getType())) {
updateArmorDamage(armor, event.getFinalDamage()); updateDamage(armorPiece, event.getFinalDamage());
} }
} }
} }
@@ -211,14 +225,12 @@ public class EntityDamage implements Listener {
* Updates a weapon's player kills. * Updates a weapon's player kills.
* *
* @param itemStack The item to update. * @param itemStack The item to update.
* @return A copy of the item.
*/ */
private ItemStack updatePlayerKills(ItemStack itemStack) { private void updatePlayerKills(ItemStack itemStack) {
ItemStack finalItem = itemStack.clone(); ItemMeta meta = itemStack.getItemMeta();
ItemMeta meta = finalItem.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats."); toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return null; return;
} }
Integer playerKills = 0; Integer playerKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
@@ -234,57 +246,26 @@ public class EntityDamage implements Listener {
playerKills++; playerKills++;
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills); container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills);
String playerKillsLore = toolStats.getLoreFromConfig("kills.player", false); String playerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
String playerKillsLoreRaw = toolStats.getLoreFromConfig("kills.player", true); List<String> newLore = toolStats.itemLore.addItemLore(meta, "{kills}", playerKillsFormatted, "kills.player");
if (playerKillsLore == null || playerKillsLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.kills.player!");
return null;
}
List<String> lore;
String newLine = playerKillsLoreRaw.replace("{kills}", NumberFormat.formatInt(playerKills));
if (meta.hasLore()) {
lore = meta.getLore();
boolean hasLore = false;
// we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(playerKillsLore)) {
hasLore = true;
lore.set(x, newLine);
break;
}
}
// if the item has lore but doesn't have the tag, add it
if (!hasLore) {
lore.add(newLine);
}
} else {
// if the item has no lore, create a new list and add the string
lore = new ArrayList<>();
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")) {
meta.setLore(lore); meta.setLore(newLore);
} }
finalItem.setItemMeta(meta); itemStack.setItemMeta(meta);
return finalItem;
} }
/** /**
* Updates a weapon's mob kills. * Updates a weapon's mob kills.
* *
* @param itemStack The item to update. * @param itemStack The item to update.
* @return A copy of the item.
*/ */
private ItemStack updateMobKills(ItemStack itemStack) { private void updateMobKills(ItemStack itemStack) {
ItemStack finalItem = itemStack.clone(); ItemMeta meta = itemStack.getItemMeta();
ItemMeta meta = finalItem.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats."); toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return null; return;
} }
Integer mobKills = 0; Integer mobKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
@@ -300,43 +281,14 @@ public class EntityDamage implements Listener {
mobKills++; mobKills++;
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills); container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills);
String mobKillsLore = toolStats.getLoreFromConfig("kills.mob", false); String mobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
String mobKillsLoreRaw = toolStats.getLoreFromConfig("kills.mob", true); List<String> newLore = toolStats.itemLore.addItemLore(meta, "{kills}", mobKillsFormatted, "kills.mob");
if (mobKillsLore == null || mobKillsLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.kills.mob!");
return null;
}
List<String> lore;
String newLine = mobKillsLoreRaw.replace("{kills}", NumberFormat.formatInt(mobKills));
if (meta.hasLore()) {
lore = meta.getLore();
boolean hasLore = false;
// we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(mobKillsLore)) {
hasLore = true;
lore.set(x, newLine);
break;
}
}
// if the item has lore but doesn't have the tag, add it
if (!hasLore) {
lore.add(newLine);
}
} else {
// if the item has no lore, create a new list and add the string
lore = new ArrayList<>();
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")) {
meta.setLore(lore); meta.setLore(newLore);
} }
finalItem.setItemMeta(meta); itemStack.setItemMeta(meta);
return finalItem;
} }
/** /**
@@ -345,7 +297,7 @@ public class EntityDamage implements Listener {
* @param itemStack The armor piece. * @param itemStack The armor piece.
* @param damage How much damage is being added. * @param damage How much damage is being added.
*/ */
private void updateArmorDamage(ItemStack itemStack, double damage) { private void updateDamage(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."); toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
@@ -364,41 +316,88 @@ public class EntityDamage implements Listener {
damageTaken = damageTaken + damage; damageTaken = damageTaken + damage;
container.set(toolStats.armorDamage, PersistentDataType.DOUBLE, damageTaken); container.set(toolStats.armorDamage, PersistentDataType.DOUBLE, damageTaken);
container.set(toolStats.armorDamageInt, PersistentDataType.INTEGER, damageTaken.intValue());
String damageTakenLore = toolStats.getLoreFromConfig("damage-taken", false); String damageTakenFormatted = toolStats.numberFormat.formatDouble(damageTaken);
String damageTakenLoreRaw = toolStats.getLoreFromConfig("damage-taken", true); List<String> newLore = toolStats.itemLore.addItemLore(meta, "{damage}", damageTakenFormatted, "damage-taken");
if (damageTakenLore == null || damageTakenLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.damage-taken!");
return;
}
List<String> lore;
String newLine = damageTakenLoreRaw.replace("{damage}", NumberFormat.formatDouble(damageTaken));
if (meta.hasLore()) {
lore = meta.getLore();
boolean hasLore = false;
// we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(damageTakenLore)) {
hasLore = true;
lore.set(x, newLine);
break;
}
}
// if the item has lore but doesn't have the tag, add it
if (!hasLore) {
lore.add(newLine);
}
} else {
// if the item has no lore, create a new list and add the string
lore = new ArrayList<>();
lore.add(newLine);
}
if (toolStats.config.getBoolean("enabled.armor-damage")) { if (toolStats.config.getBoolean("enabled.armor-damage")) {
meta.setLore(lore); meta.setLore(newLore);
} }
itemStack.setItemMeta(meta); itemStack.setItemMeta(meta);
} }
/**
* Updates a trident's mob kills.
*
* @param trident The item to update.
*/
private ItemStack tridentMobKills(ItemStack trident) {
ItemStack newTrident = trident.clone();
ItemMeta meta = newTrident.getItemMeta();
if (meta == null) {
toolStats.logger.warning(newTrident + " does NOT have any meta! Unable to update stats.");
return null;
}
Integer mobKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
mobKills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
}
if (mobKills == null) {
mobKills = 0;
toolStats.logger.warning(newTrident + " does not have valid mob-kills set! Resting to zero. This should NEVER happen.");
}
mobKills++;
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills);
String mobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{kills}", mobKillsFormatted, "kills.mob");
// do we add the lore based on the config?
if (toolStats.checkConfig(newTrident, "mob-kills")) {
meta.setLore(newLore);
}
newTrident.setItemMeta(meta);
return newTrident;
}
/**
* Updates a trident's player kills.
*
* @param trident The item to update.
*/
private ItemStack tridentPlayerKills(ItemStack trident) {
ItemStack newTrident = trident.clone();
ItemMeta meta = newTrident.getItemMeta();
if (meta == null) {
toolStats.logger.warning(newTrident + " does NOT have any meta! Unable to update stats.");
return null;
}
Integer playerKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
playerKills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
}
if (playerKills == null) {
playerKills = 0;
toolStats.logger.warning(newTrident + " does not have valid player-kills set! Resting to zero. This should NEVER happen.");
}
playerKills++;
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills);
String playerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{kills}", playerKillsFormatted, "kills.player");
// do we add the lore based on the config?
if (toolStats.checkConfig(newTrident, "player-kills")) {
meta.setLore(newLore);
}
newTrident.setItemMeta(meta);
return newTrident;
}
} }

View File

@@ -74,7 +74,7 @@ public class EntityDeath implements Listener {
* Adds "drop by" tag to item. * Adds "drop by" tag to item.
* *
* @param oldItem 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 ItemStack addLore(ItemStack oldItem, String mob) { private ItemStack addLore(ItemStack oldItem, String mob) {
ItemStack newItem = oldItem.clone(); ItemStack newItem = oldItem.clone();
@@ -82,35 +82,11 @@ public class EntityDeath implements Listener {
if (meta == null) { if (meta == null) {
return null; return null;
} }
boolean hasTag = false;
String droppedByLore = toolStats.getLoreFromConfig("dropped-by", false); List<String> newLore = toolStats.itemLore.addItemLore(meta, "{name}", mob, "dropped-by");
String droppedByLoreRaw = toolStats.getLoreFromConfig("dropped-by", true);
if (droppedByLore == null || droppedByLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.dropped-by!");
return null;
}
List<String> lore;
if (meta.hasLore()) {
lore = meta.getLore();
for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(droppedByLore)) {
// replace existing tag
lore.set(x, droppedByLoreRaw.replace("{name}", mob));
hasTag = true;
}
}
} else {
// if the item has no lore, create a new list and add the string
lore = new ArrayList<>();
}
if (!hasTag) {
lore.add(droppedByLoreRaw.replace("{name}", mob));
}
if (toolStats.config.getBoolean("enabled.dropped-by")) { if (toolStats.config.getBoolean("enabled.dropped-by")) {
meta.setLore(lore); meta.setLore(newLore);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -38,7 +38,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -145,25 +144,12 @@ public class GenerateLoot implements Listener {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());
String foundByLoreRaw = toolStats.getLoreFromConfig("looted.found-by", true); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
String foundOnLoreRaw = toolStats.getLoreFromConfig("looted.found-on", true); List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate, "LOOTED");
if (foundByLoreRaw == null || foundOnLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.looted!");
return null;
}
List<String> lore;
if (meta.hasLore()) {
lore = meta.getLore();
} else {
lore = new ArrayList<>();
}
if (toolStats.checkConfig(newItem, "looted-tag")) { if (toolStats.checkConfig(newItem, "looted-tag")) {
lore.add(foundOnLoreRaw.replace("{date}", toolStats.dateFormat.format(finalDate))); meta.setLore(newLore);
lore.add(foundByLoreRaw.replace("{player}", owner.getName()));
} }
meta.setLore(lore);
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;
} }

View File

@@ -31,7 +31,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -94,25 +93,12 @@ public class PickupItem implements Listener {
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());
container.remove(toolStats.newElytra); container.remove(toolStats.newElytra);
String foundByLoreRaw = toolStats.getLoreFromConfig("looted.found-by", true); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
String foundOnLoreRaw = toolStats.getLoreFromConfig("looted.found-on", true); List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate, "LOOTED");
if (foundByLoreRaw == null || foundOnLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.looted!");
return null;
}
List<String> lore;
if (meta.hasLore()) {
lore = meta.getLore();
} else {
lore = new ArrayList<>();
}
if (toolStats.config.getBoolean("enabled.elytra-tag")) { if (toolStats.config.getBoolean("enabled.elytra-tag")) {
lore.add(foundOnLoreRaw.replace("{date}", toolStats.dateFormat.format(finalDate))); meta.setLore(newLore);
lore.add(foundByLoreRaw.replace("{player}", owner.getName()));
} }
meta.setLore(lore);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
return finalItem; return finalItem;
} }

View File

@@ -19,7 +19,6 @@ 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;
@@ -30,11 +29,11 @@ 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;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -46,7 +45,7 @@ public class PlayerFish implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.MONITOR)
public void onFish(PlayerFishEvent event) { public void onFish(PlayerFishEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -61,12 +60,32 @@ public class PlayerFish implements Listener {
return; return;
} }
// make sure the player is holding a fishing rod // make sure the player is holding a fishing rod
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot()); // player can fish with their offhand
if (heldItem == null || heldItem.getType() == Material.AIR || heldItem.getType() != Material.FISHING_ROD) { PlayerInventory inventory = player.getInventory();
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.FISHING_ROD;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.FISHING_ROD;
ItemStack fishingRod = null;
if (isMainHand) {
fishingRod = inventory.getItemInMainHand();
}
if (isOffHand) {
fishingRod = inventory.getItemInOffHand();
}
// if the player is hold fishing rods in both hands
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
fishingRod = inventory.getItemInMainHand();
}
// player swapped items?
if (fishingRod == null) {
return; return;
} }
// update the fishing rod to the new one
updateFishCount(heldItem); // update the fishing rod!
updateFishCount(fishingRod);
// check if the player caught an item // check if the player caught an item
if (event.getCaught() == null) { if (event.getCaught() == null) {
return; return;
@@ -83,6 +102,7 @@ public class PlayerFish implements Listener {
/** /**
* Update a fishing rod's fish count. * Update a fishing rod's fish count.
*
* @param fishingRod The fishing rod to update. * @param fishingRod The fishing rod to update.
*/ */
private void updateFishCount(ItemStack fishingRod) { private void updateFishCount(ItemStack fishingRod) {
@@ -105,60 +125,20 @@ public class PlayerFish implements Listener {
fishCaught++; fishCaught++;
container.set(toolStats.fishingRodCaught, PersistentDataType.INTEGER, fishCaught); container.set(toolStats.fishingRodCaught, PersistentDataType.INTEGER, fishCaught);
String fishCaughtLore = toolStats.getLoreFromConfig("fished.fish-caught", false); String fishCaughtFormatted = toolStats.numberFormat.formatInt(fishCaught);
String fishCaughtLoreRaw = toolStats.getLoreFromConfig("fished.fish-caught", true); List<String> newLore = toolStats.itemLore.addItemLore(meta, "{fish}", fishCaughtFormatted, "fished.fish-caught");
if (fishCaughtLore == null || fishCaughtLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.fish-caught!");
return;
}
List<String> lore;
String newLine = fishCaughtLoreRaw.replace("{fish}", NumberFormat.formatInt(fishCaught));
if (meta.hasLore()) {
lore = meta.getLore();
boolean hasLore = false;
// we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(fishCaughtLore)) {
hasLore = true;
lore.set(x, newLine);
break;
}
}
// if the item has lore but doesn't have the tag, add it
if (!hasLore) {
lore.add(newLine);
}
} else {
// if the item has no lore, create a new list and add the string
lore = new ArrayList<>();
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(newLore);
} }
fishingRod.setItemMeta(meta); fishingRod.setItemMeta(meta);
} }
/** /**
* Add lore to newly caught item. * Add lore to newly caught item.
*
* @param originalItem The original item to add lore. * @param originalItem The original item to add lore.
* @param owner The player who caught it. * @param owner The player who caught it.
* @return A copy of the new item with lore. * @return A copy of the new item with lore.
*/ */
private ItemStack addNewLore(ItemStack originalItem, Player owner) { private ItemStack addNewLore(ItemStack originalItem, Player owner) {
@@ -178,25 +158,11 @@ public class PlayerFish implements Listener {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());
String caughtByLoreRaw = toolStats.getLoreFromConfig("fished.caught-by", true); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
String caughtOnLoreRaw = toolStats.getLoreFromConfig("fished.caught-on", true); List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate, "FISHED");
if (caughtByLoreRaw == null || caughtOnLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.fished!");
return null;
}
List<String> lore;
if (meta.hasLore()) {
lore = meta.getLore();
assert lore != null;
} else {
lore = new ArrayList<>();
}
if (toolStats.checkConfig(newItem, "fished-tag")) { if (toolStats.checkConfig(newItem, "fished-tag")) {
lore.add(caughtOnLoreRaw.replace("{date}", toolStats.dateFormat.format(finalDate))); meta.setLore(newLore);
lore.add(caughtByLoreRaw.replace("{player}", owner.getName()));
meta.setLore(lore);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -18,7 +18,6 @@
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;
@@ -29,11 +28,11 @@ 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;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class SheepShear implements Listener { public class SheepShear implements Listener {
@@ -44,7 +43,7 @@ public class SheepShear implements Listener {
this.toolStats = toolStats; this.toolStats = toolStats;
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.MONITOR)
public void onShear(PlayerInteractEntityEvent event) { public void onShear(PlayerInteractEntityEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -57,34 +56,52 @@ public class SheepShear implements Listener {
if (!(entity instanceof Sheep)) { if (!(entity instanceof Sheep)) {
return; return;
} }
// check if the player is right-clicking with shears only
int heldItemSlot = player.getInventory().getHeldItemSlot(); // make sure the player is holding shears
ItemStack heldItem = player.getInventory().getItem(heldItemSlot); // player can shear with their offhand
if (heldItem == null || heldItem.getType() == Material.AIR || heldItem.getType() != Material.SHEARS) { PlayerInventory inventory = player.getInventory();
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.SHEARS;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.SHEARS;
ItemStack shears = null;
if (isMainHand) {
shears = inventory.getItemInMainHand();
}
if (isOffHand) {
shears = inventory.getItemInOffHand();
}
// if the player is hold fishing rods in both hands
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
shears = inventory.getItemInMainHand();
}
// player swapped items?
if (shears == null) {
return; return;
} }
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()) {
ItemStack newShears = addLore(heldItem); return;
if (newShears != null) {
player.getInventory().setItem(heldItemSlot, newShears);
}
} }
// update the stats
ItemStack finalShears = shears;
addLore(finalShears);
} }
/** /**
* Adds tags to shears. * Adds tags to shears.
* *
* @param oldShears The shears. * @param newShears The shears.
*/ */
private ItemStack addLore(ItemStack oldShears) { private void addLore(ItemStack newShears) {
ItemStack newShears = oldShears.clone();
ItemMeta meta = newShears.getItemMeta(); ItemMeta meta = newShears.getItemMeta();
if (meta == null) { if (meta == null) {
toolStats.logger.warning(newShears + " does NOT have any meta! Unable to update stats."); toolStats.logger.warning(newShears + " does NOT have any meta! Unable to update stats.");
return null; return;
} }
Integer sheepSheared = 0; Integer sheepSheared = 0;
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
@@ -100,41 +117,12 @@ public class SheepShear implements Listener {
sheepSheared++; sheepSheared++;
container.set(toolStats.shearsSheared, PersistentDataType.INTEGER, sheepSheared); container.set(toolStats.shearsSheared, PersistentDataType.INTEGER, sheepSheared);
String sheepShearedLore = toolStats.getLoreFromConfig("sheep-sheared", false); String sheepShearedFormatted = toolStats.numberFormat.formatInt(sheepSheared);
String sheepShearedLoreRaw = toolStats.getLoreFromConfig("sheep-sheared", true); List<String> newLore = toolStats.itemLore.addItemLore(meta, "{sheep}", sheepShearedFormatted, "sheep-sheared");
if (sheepShearedLore == null || sheepShearedLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.sheep-sheared!");
return null;
}
List<String> lore;
String newLine = sheepShearedLoreRaw.replace("{sheep}", NumberFormat.formatInt(sheepSheared));
if (meta.hasLore()) {
lore = meta.getLore();
boolean hasLore = false;
// we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items
for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(sheepShearedLore)) {
hasLore = true;
lore.set(x, newLine);
break;
}
}
// if the item has lore but doesn't have the tag, add it
if (!hasLore) {
lore.add(newLine);
}
} else {
// if the item has no lore, create a new list and add the string
lore = new ArrayList<>();
lore.add(newLine);
}
if (toolStats.config.getBoolean("enabled.sheep-sheared")) { if (toolStats.config.getBoolean("enabled.sheep-sheared")) {
meta.setLore(lore); meta.setLore(newLore);
} }
newShears.setItemMeta(meta); newShears.setItemMeta(meta);
return newShears;
} }
} }

View File

@@ -36,7 +36,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -67,20 +66,21 @@ public class VillagerTrade implements Listener {
if (event.getSlotType() == InventoryType.SlotType.RESULT) { if (event.getSlotType() == InventoryType.SlotType.RESULT) {
ItemStack item = event.getCurrentItem(); ItemStack item = event.getCurrentItem();
// only check items we want // only check items we want
if (ItemChecker.isValidItem(item.getType())) { if (!ItemChecker.isValidItem(item.getType())) {
// if the player shift clicks, show the warning return;
if (event.isShiftClick()) { }
String configMessage = toolStats.config.getString("messages.shift-click-warning.trading"); // if the player shift clicks, show the warning
if (configMessage != null) { if (event.isShiftClick()) {
event.getWhoClicked().sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage)); String configMessage = toolStats.config.getString("messages.shift-click-warning.trading");
} if (configMessage != null) {
} player.sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage));
ItemStack newItem = addLore(item, player);
if (newItem != null) {
// this gets delayed since villager inventories suck for no reason
Bukkit.getScheduler().runTaskLater(toolStats, () -> event.setCurrentItem(newItem), 5);
} }
} }
ItemStack newItem = addLore(item, player);
if (newItem != null) {
// set the new item
inventory.setItem(event.getSlot(), newItem);
}
} }
} }
} }
@@ -110,24 +110,11 @@ public class VillagerTrade implements Listener {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());
String tradedByLoreRaw = toolStats.getLoreFromConfig("traded.traded-by", true); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
String tradedOnLoreRaw = toolStats.getLoreFromConfig("traded.traded-on", true); List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate, "TRADED");
if (tradedByLoreRaw == null || tradedOnLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.traded!");
return null;
}
List<String> lore;
if (meta.hasLore()) {
lore = meta.getLore();
} else {
lore = new ArrayList<>();
}
if (toolStats.checkConfig(newItem, "traded-tag")) { if (toolStats.checkConfig(newItem, "traded-tag")) {
lore.add(tradedOnLoreRaw.replace("{date}", toolStats.dateFormat.format(finalDate))); meta.setLore(newLore);
lore.add(tradedByLoreRaw.replace("{player}", owner.getName()));
meta.setLore(lore);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -0,0 +1,137 @@
/*
* 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 lol.hyper.toolstats.ToolStats;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
public class ItemLore {
private final ToolStats toolStats;
public ItemLore(ToolStats toolStats) {
this.toolStats = toolStats;
}
/**
* Adds new lore to an item.
*
* @param placeholder The placeholder from the config. ex: {kills}
* @param placeholderValue The value to replace the placeholder.
* @param configLorePath The path to the config message.
* @return The item's new lore.
*/
public List<String> addItemLore(ItemMeta itemMeta, String placeholder, String placeholderValue, String configLorePath) {
String configLore = toolStats.getLoreFromConfig(configLorePath, false);
String configLoreRaw = toolStats.getLoreFromConfig(configLorePath, true);
if (configLore == null || configLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages." + configLorePath + "!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
}
List<String> newLore;
// replace the placeholder with the value
// ex: {kills} -> a number
String newLine = configLoreRaw.replace(placeholder, placeholderValue);
if (itemMeta.hasLore()) {
newLore = itemMeta.getLore();
boolean hasLore = false;
// keep track of line index
// this doesn't mess the lore of existing items
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)) {
hasLore = true;
newLore.set(x, newLine);
break;
}
}
// if the item has lore but doesn't have our line, add it
if (!hasLore) {
newLore.add(newLine);
}
} else {
// if the item has no lore, create a new list and add the line
newLore = new ArrayList<>();
newLore.add(newLine);
}
return newLore;
}
/**
* Adds new ownership tag to an item.
*
* @param itemMeta The item meta.
* @param playerName The new owner of item.
* @param formattedDate The date of the ownership.
* @param type The type of new ownership.
* @return The item's new lore.
*/
public List<String> addNewOwner(ItemMeta itemMeta, String playerName, String formattedDate, String type) {
String dateCreated = null;
String itemOwner = null;
switch (type) {
case "LOOTED": {
dateCreated = toolStats.getLoreFromConfig("looted.found-on", true);
itemOwner = toolStats.getLoreFromConfig("looted.found-by", true);
break;
}
case "CREATED": {
dateCreated = toolStats.getLoreFromConfig("created.created-on", true);
itemOwner = toolStats.getLoreFromConfig("created.created-by", true);
break;
}
case "FISHED": {
dateCreated = toolStats.getLoreFromConfig("fished.caught-on", true);
itemOwner = toolStats.getLoreFromConfig("fished.caught-by", true);
break;
}
case "TRADED": {
dateCreated = toolStats.getLoreFromConfig("traded.traded-on", true);
itemOwner = toolStats.getLoreFromConfig("traded.traded-by", true);
break;
}
}
if (dateCreated == null || itemOwner == null) {
toolStats.logger.warning("There is no lore message for messages." + type.toLowerCase(Locale.ENGLISH) + "!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
}
List<String> newLore;
if (itemMeta.hasLore()) {
newLore = itemMeta.getLore();
} else {
newLore = new ArrayList<>();
}
newLore.add(dateCreated.replace("{date}", formattedDate));
newLore.add(itemOwner.replace("{player}", playerName));
return newLore;
}
}

View File

@@ -17,21 +17,99 @@
package lol.hyper.toolstats.tools; package lol.hyper.toolstats.tools;
import lol.hyper.toolstats.ToolStats;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols; import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale; import java.util.Locale;
public class NumberFormat { public class NumberFormat {
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,###.00", new DecimalFormatSymbols(Locale.getDefault())); private DecimalFormat DECIMAL_FORMAT;
private static final DecimalFormat COMMA_FORMAT = new DecimalFormat("#,###", new DecimalFormatSymbols(Locale.getDefault())); private DecimalFormat COMMA_FORMAT;
private SimpleDateFormat DATE_FORMAT;
/**
* Utility class to format different numbers
* @param toolStats Plugin instance.
*/
public NumberFormat(ToolStats toolStats) {
String dateFormat = toolStats.config.getString("date-format");
String decimalSeparator = toolStats.config.getString("number-formats.decimal-separator");
String commaSeparator = toolStats.config.getString("number-formats.comma-separator");
String commaFormat = toolStats.config.getString("number-formats.comma-format");
String decimalFormat = toolStats.config.getString("number-formats.decimal-format");
// if these config values are missing, use the default ones
if (dateFormat == null) {
dateFormat = "M/dd/yyyy";
toolStats.logger.warning("date-format is missing! Using default American English format.");
}
if (decimalSeparator == null) {
decimalSeparator = ".";
toolStats.logger.warning("number-formats.decimal-separator is missing! Using default \".\" instead.");
}
if (commaSeparator == null) {
commaSeparator = ",";
toolStats.logger.warning("number-formats.comma-separator is missing! Using default \",\" instead.");
}
if (commaFormat == null) {
commaFormat = "#,###";
toolStats.logger.warning("number-formats.comma-format is missing! Using default #,### instead.");
}
if (decimalFormat == null) {
decimalFormat = "#,###.00";
toolStats.logger.warning("number-formats.comma-separator is missing! Using default #,###.00 instead.");
}
// test the date format
try {
DATE_FORMAT = new SimpleDateFormat(dateFormat, Locale.getDefault());
} catch (NullPointerException | IllegalArgumentException exception) {
toolStats.logger.warning("date-format is NOT a valid format! Using default American English format.");
exception.printStackTrace();
DATE_FORMAT = new SimpleDateFormat("M/dd/yyyy", Locale.ENGLISH);
}
// set the separators
DecimalFormatSymbols formatSymbols = new DecimalFormatSymbols(Locale.getDefault());
formatSymbols.setDecimalSeparator(decimalSeparator.charAt(0));
formatSymbols.setGroupingSeparator(commaSeparator.charAt(0));
// test the comma format
try {
COMMA_FORMAT = new DecimalFormat(commaFormat, formatSymbols);
} catch (NullPointerException | IllegalArgumentException exception) {
toolStats.logger.warning("number-formats.comma-format is NOT a valid format! Using default #,### instead.");
exception.printStackTrace();
COMMA_FORMAT = new DecimalFormat("#,###", formatSymbols);
}
// test the decimal format
try {
DECIMAL_FORMAT = new DecimalFormat(decimalFormat, formatSymbols);
} catch (NullPointerException | IllegalArgumentException exception) {
toolStats.logger.warning("number-formats.decimal-format is NOT a valid format! Using default #,###.00 instead.");
exception.printStackTrace();
DECIMAL_FORMAT = new DecimalFormat("#,###.00", formatSymbols);
}
}
/** /**
* Formats a number to make it pretty. Example: 4322 to 4,322 * Formats a number to make it pretty. Example: 4322 to 4,322
*
* @param number The number to format. * @param number The number to format.
* @return The formatted number. * @return The formatted number.
*/ */
public static String formatInt(int number) { public String formatInt(int number) {
String finalNumber = COMMA_FORMAT.format(number); String finalNumber = COMMA_FORMAT.format(number);
finalNumber = finalNumber.replaceAll("[\\x{202f}\\x{00A0}]", " "); finalNumber = finalNumber.replaceAll("[\\x{202f}\\x{00A0}]", " ");
return finalNumber; return finalNumber;
@@ -39,12 +117,23 @@ public class NumberFormat {
/** /**
* Formats a number to make it pretty. Example: 4322.33 to 4,322.33 * Formats a number to make it pretty. Example: 4322.33 to 4,322.33
*
* @param number The number to format. * @param number The number to format.
* @return The formatted number. * @return The formatted number.
*/ */
public static String formatDouble(double number) { public String formatDouble(double number) {
String finalNumber = DECIMAL_FORMAT.format(number); String finalNumber = DECIMAL_FORMAT.format(number);
finalNumber = finalNumber.replaceAll("[\\x{202f}\\x{00A0}]", " "); finalNumber = finalNumber.replaceAll("[\\x{202f}\\x{00A0}]", " ");
return finalNumber; return finalNumber;
} }
/**
* Formats a date into the readable format.
*
* @param date The date to format.
* @return The date into a readable format.
*/
public String formatDate(Date date) {
return DATE_FORMAT.format(date);
}
} }

View File

@@ -103,4 +103,12 @@ messages:
# Example: "dd/MM/yyyy" # Example: "dd/MM/yyyy"
date-format: "M/dd/yyyy" date-format: "M/dd/yyyy"
config-version: 3 # Change number formatting.
# You probably do not need to touch this.
number-formats:
comma-separator: ","
decimal-separator: "."
comma-format: "#,###"
decimal-format: "#,###.00"
config-version: 4