Compare commits

...

26 Commits
1.8.3 ... 1.8.7

Author SHA1 Message Date
hyperdefined
ff578e170e 1.8.7 2025-01-22 18:19:12 -05:00
hyperdefined
87aa26c7e9 Update ItemChecker.java 2025-01-22 18:17:49 -05:00
hyperdefined
2b5f784b93 Update config.yml 2025-01-22 18:17:33 -05:00
hyperdefined
94ff8f251d go back to text comparison
this broke something with another plugin
2025-01-22 18:10:35 -05:00
hyperdefined
f9fa15dbaf finally handle shift clicking
closes #89
2025-01-22 17:54:50 -05:00
hyperdefined
1a15fb94f4 misc cleanup 2025-01-22 17:02:31 -05:00
hyperdefined
44b70a8394 fix #90 2025-01-22 17:02:05 -05:00
hyperdefined
98ee84ad13 fix handling empty messages 2025-01-18 13:06:38 -05:00
hyperdefined
c68a04851b Update README.md 2024-12-31 13:21:41 -05:00
hyperdefined
06e063a072 Update hangar.yml 2024-12-30 23:29:24 -05:00
hyperdefined
c00c534d49 test complete 2024-12-30 23:28:35 -05:00
hyperdefined
d6f8176ce1 remove deprecated thing 2024-12-30 23:27:11 -05:00
hyperdefined
eb06dff0bc bro 2024-12-30 23:23:36 -05:00
hyperdefined
9a72c509ef hangar API test 2024-12-30 23:22:31 -05:00
hyperdefined
eaca8ac87d Update README.md 2024-12-23 19:24:04 -05:00
hyperdefined
44a2c5cd26 Update README.md 2024-12-23 19:16:29 -05:00
hyperdefined
0957a1c989 Update README.md 2024-12-23 19:07:03 -05:00
hyperdefined
7b12a130a0 1.8.5 2024-12-17 17:47:14 -05:00
hyperdefined
6b263be041 patience wizard 2024-12-15 18:31:38 -05:00
hyperdefined
aeaeee680b revert this since we can now 2024-12-15 18:31:09 -05:00
hyperdefined
d8c7425a5a 1.8.4 2024-12-15 18:29:46 -05:00
hyperdefined
86c92c9706 change these 2024-12-15 17:10:57 -05:00
hyperdefined
cd62f7309e update these 2024-12-14 18:31:14 -05:00
hyperdefined
e2b18cb5f1 Update README.md 2024-12-14 18:06:16 -05:00
hyperdefined
150956b2c9 Update pom.xml 2024-12-14 18:05:01 -05:00
hyperdefined
585e020baf migration to Paper API 2024-12-14 17:28:02 -05:00
31 changed files with 414 additions and 496 deletions

31
.github/workflows/hangar.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Update Hangar Description
on:
push:
branches: [ master ]
jobs:
update-hangar-page:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Authenticate with Hangar
id: authenticate
run: |
RESPONSE=$(curl -s -X POST "https://hangar.papermc.io/api/v1/authenticate?apiKey=${{ secrets.HANGAR }}" -H 'accept: application/json')
TOKEN=$(echo $RESPONSE | jq -r '.token')
if [[ "$TOKEN" == "null" ]]; then
echo "Error: Unable to fetch JWT token"
exit 1
fi
echo "::add-mask::$TOKEN"
echo "token=$TOKEN" >> $GITHUB_OUTPUT
- name: Update Project Description
run: |
README_CONTENT=$(cat README.md | jq -Rs .)
curl -s -X PATCH "https://hangar.papermc.io/api/v1/pages/editmain/ToolStats" \
-H "content-type: application/json" \
-H "Authorization: HangarAuth ${{ steps.authenticate.outputs.token }}" \
-d "{\"content\":$README_CONTENT}"

View File

@@ -15,10 +15,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Set up JDK 1.8 - name: Set up JDK 21
uses: actions/setup-java@v1 uses: actions/setup-java@v4
with: with:
java-version: 1.8 distribution: temurin
- name: Build with Maven java-version: 21
run: mvn -B package --file pom.xml - name: Build with Maven
run: mvn -B package --file pom.xml

View File

@@ -1,3 +1,4 @@
name: Update Modrinth Description
on: on:
push: push:
branches: [ master ] branches: [ master ]

View File

@@ -1,27 +1,26 @@
<h1 align="center">ToolStats</h1> <h1 align="center">ToolStats</h1>
<p align="center"> <p align="center">
<img src="https://img.shields.io/badge/Minecraft-1.15--1.21-orange" alt="Minecraft versions"> <a href="https://modrinth.com/plugin/ToolStats"><img alt="modrinth" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/available/modrinth_vector.svg"></a>
<img src="https://img.shields.io/github/v/release/hyperdefined/ToolStats" alt="GitHub release (latest by date)"> <a href="https://hangar.papermc.io/hyperdefined/ToolStats"><img alt="hangar" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/available/hangar_vector.svg"></a>
<a href="https://github.com/hyperdefined/ToolStats/releases"><img src="https://img.shields.io/github/downloads/hyperdefined/ToolStats/total?logo=github" alt="Downloads"></a> <a href="https://papermc.io"><img alt="paper" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/supported/paper_vector.svg"></a>
<img src="https://img.shields.io/badge/made%20with-love%20&%20fluff-red" alt="Made with love & fluff"> <a href="https://github.com/hyperdefined/ToolStats/wiki"><img alt="ghpages" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/documentation/ghpages_vector.svg"></a>
<a href="https://ko-fi.com/hyperdefined"><img src="https://img.shields.io/badge/Donate-Ko--fi-red" alt="Donate via Ko-fi"></a> <a href="https://discord.gg/rJuQXVcJz8"><img alt="discord-singular" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/social/discord-singular_vector.svg"></a>
<img alt="Discord" src="https://img.shields.io/discord/1267600843356639413?style=flat&logo=discord&label=Discord"> <a href="https://buymeacoffee.com/hyperdefined"><img alt="buymeacoffee-singular" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/donate/buymeacoffee-singular_vector.svg"></a>
<a href="https://www.gnu.org/licenses/gpl-3.0"><img src="https://img.shields.io/badge/License-GPLv3-blue.svg" alt="License: GPL v3"></a>
<a href="https://wakatime.com/badge/user/992a7647-176a-477c-8086-e1abfba87ff4/project/0200f07a-f303-4103-a5f2-34b38c9c1fa4"><img src="https://wakatime.com/badge/user/992a7647-176a-477c-8086-e1abfba87ff4/project/0200f07a-f303-4103-a5f2-34b38c9c1fa4.svg" alt="wakatime"></a>
</p> </p>
ToolStats is a small plugin that display various stats about tools. This plugin is inspired off of [GearStats](https://www.spigotmc.org/resources/gearstats.12960/). You can disable/enable which stats are shown on which tools via the config. Note: stats are tracked regardless of config setting. The config is to disable the lore on the item. ToolStats is a Paper plugin that display various stats about tools. This plugin is inspired off of [GearStats](https://www.spigotmc.org/resources/gearstats.12960/). You can disable/enable which stats are shown on which tools via the config. Note: stats are tracked regardless of config setting. The config is to disable the lore on the item.
Here is everything it tracks: Here is everything it tracks:
* Blocks mined (pickaxes, shovels, axes, hoes, shears) * Blocks mined (pickaxes, shovels, axes, hoes, shears)
* Crops mined (hoes) * Crops mined (hoes)
* Player/mob kills (swords, axes, tridents, bows/crossbows) * Player/mob kills (swords, axes, tridents, bows/crossbows, mace)
* Ownership of items when crafted, looted (from chests), traded, spawned via creative, and caught from fishing. * Ownership of items when crafted, looted (from chests), traded, spawned via creative, and caught from fishing.
* Armor damage taken. * Armor damage taken.
* Fish caught. * Fish caught.
* Sheep sheared. * Sheep sheared.
* Arrows shot (bows/crossbows) * Arrows shot (bows/crossbows)
* Flight time with elytras.
The best part is, this data is stored on the item itself. You can also change how the lore is displayed on the items! The best part is, this data is stored on the item itself. You can also change how the lore is displayed on the items!
@@ -43,8 +42,5 @@ If item lore is ever incorrect/missing, you can run `/toolstats reset`. This com
## Documentation ## Documentation
Visit the [wiki](https://github.com/hyperdefined/ToolStats/wiki) for help. Visit the [wiki](https://github.com/hyperdefined/ToolStats/wiki) for help.
## Support
You can join the [Discord](https://discord.gg/rJuQXVcJz8) for support.
## License ## License
This plugin is released under GNU General Public License v3. See [LICENSE](https://github.com/hyperdefined/ToolStats/blob/master/LICENSE). This plugin is released under GNU General Public License v3. See [LICENSE](https://github.com/hyperdefined/ToolStats/blob/master/LICENSE).

50
pom.xml
View File

@@ -23,13 +23,13 @@
<groupId>lol.hyper</groupId> <groupId>lol.hyper</groupId>
<artifactId>toolstats</artifactId> <artifactId>toolstats</artifactId>
<version>1.8.3</version> <version>1.8.7</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ToolStats</name> <name>ToolStats</name>
<properties> <properties>
<java.version>1.8</java.version> <java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
@@ -67,18 +67,10 @@
<pattern>org.bstats</pattern> <pattern>org.bstats</pattern>
<shadedPattern>lol.hyper.toolstats.bstats</shadedPattern> <shadedPattern>lol.hyper.toolstats.bstats</shadedPattern>
</relocation> </relocation>
<relocation>
<pattern>net.kyori.adventure</pattern>
<shadedPattern>lol.hyper.toolstats.adventure</shadedPattern>
</relocation>
<relocation> <relocation>
<pattern>lol.hyper.githubreleaseapi</pattern> <pattern>lol.hyper.githubreleaseapi</pattern>
<shadedPattern>lol.hyper.toolstats.updater</shadedPattern> <shadedPattern>lol.hyper.toolstats.updater</shadedPattern>
</relocation> </relocation>
<relocation>
<pattern>space.arim.morepaperlib</pattern>
<shadedPattern>lol.hyper.toolstats.morepaperlib</shadedPattern>
</relocation>
</relocations> </relocations>
</configuration> </configuration>
<executions> <executions>
@@ -104,20 +96,16 @@
<repositories> <repositories>
<repository> <repository>
<id>spigotmc-repo</id> <id>papermc</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> <url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>arim-mvn-lgpl3</id>
<url>https://mvn-repo.arim.space/lesser-gpl3/</url>
</repository> </repository>
</repositories> </repositories>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>io.papermc.paper</groupId>
<artifactId>spigot-api</artifactId> <artifactId>paper-api</artifactId>
<version>1.20.2-R0.1-SNAPSHOT</version> <version>1.21.4-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -132,29 +120,5 @@
<version>1.0.5</version> <version>1.0.5</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.17.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.3.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>space.arim.morepaperlib</groupId>
<artifactId>morepaperlib</artifactId>
<version>0.4.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-chat</artifactId>
<version>1.20-R0.2</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -27,17 +27,11 @@ import lol.hyper.toolstats.tools.ItemLore;
import lol.hyper.toolstats.tools.NumberFormat; import lol.hyper.toolstats.tools.NumberFormat;
import lol.hyper.toolstats.tools.config.ConfigTools; import lol.hyper.toolstats.tools.config.ConfigTools;
import lol.hyper.toolstats.tools.config.ConfigUpdater; import lol.hyper.toolstats.tools.config.ConfigUpdater;
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;
import org.bukkit.Chunk;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import space.arim.morepaperlib.MorePaperLib;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -81,10 +75,6 @@ public final class ToolStats extends JavaPlugin {
* Stores how much damage an armor piece has taken. * Stores how much damage an armor piece has taken.
*/ */
public final NamespacedKey armorDamage = new NamespacedKey(this, "damage-taken"); public final NamespacedKey armorDamage = new NamespacedKey(this, "damage-taken");
/**
* Stores how much damage an armor piece has taken (as an int).
*/
public final NamespacedKey armorDamageInt = new NamespacedKey(this, "damage-taken-int");
/** /**
* Key for tracking new elytras that spawn. * Key for tracking new elytras that spawn.
*/ */
@@ -134,8 +124,6 @@ public final class ToolStats extends JavaPlugin {
public PlayerJoin playerJoin; public PlayerJoin playerJoin;
public NumberFormat numberFormat; public NumberFormat numberFormat;
public YamlConfiguration config; public YamlConfiguration config;
private BukkitAudiences adventure;
public MorePaperLib morePaperLib;
public HashMaker hashMaker; public HashMaker hashMaker;
public CreativeEvent creativeEvent; public CreativeEvent creativeEvent;
public PlayerMove playerMove; public PlayerMove playerMove;
@@ -145,8 +133,6 @@ public final class ToolStats extends JavaPlugin {
@Override @Override
public void onEnable() { public void onEnable() {
this.adventure = BukkitAudiences.create(this);
morePaperLib = new MorePaperLib(this);
if (!configFile.exists()) { if (!configFile.exists()) {
this.saveResource("config.yml", true); this.saveResource("config.yml", true);
logger.info("Copying default config!"); logger.info("Copying default config!");
@@ -194,8 +180,7 @@ public final class ToolStats extends JavaPlugin {
this.getCommand("toolstats").setExecutor(commandToolStats); this.getCommand("toolstats").setExecutor(commandToolStats);
new Metrics(this, 14110); new Metrics(this, 14110);
Bukkit.getAsyncScheduler().runNow(this, scheduledTask -> checkForUpdates());
morePaperLib.scheduling().asyncScheduler().run(this::checkForUpdates);
} }
public void loadConfig() { public void loadConfig() {
@@ -218,7 +203,7 @@ public final class ToolStats extends JavaPlugin {
e.printStackTrace(); e.printStackTrace();
return; return;
} }
GitHubRelease current = api.getReleaseByTag(this.getDescription().getVersion()); GitHubRelease current = api.getReleaseByTag(this.getPluginMeta().getVersion());
GitHubRelease latest = api.getLatestVersion(); GitHubRelease latest = api.getLatestVersion();
if (current == null) { if (current == null) {
logger.warning("You are running a version that does not exist on GitHub. If you are in a dev environment, you can ignore this. Otherwise, this is a bug!"); logger.warning("You are running a version that does not exist on GitHub. If you are in a dev environment, you can ignore this. Otherwise, this is a bug!");
@@ -231,23 +216,4 @@ public final class ToolStats extends JavaPlugin {
logger.warning("A new version is available (" + latest.getTagVersion() + ")! You are running version " + current.getTagVersion() + ". You are " + buildsBehind + " version(s) behind."); logger.warning("A new version is available (" + latest.getTagVersion() + ")! You are running version " + current.getTagVersion() + ". You are " + buildsBehind + " version(s) behind.");
} }
} }
public BukkitAudiences getAdventure() {
if (this.adventure == null) {
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
}
return this.adventure;
}
public void scheduleEntity(BukkitRunnable runnable, Entity entity, int delay) {
morePaperLib.scheduling().entitySpecificScheduler(entity).runDelayed(runnable, null, delay);
}
public void scheduleGlobal(BukkitRunnable runnable, int delay) {
morePaperLib.scheduling().globalRegionalScheduler().runDelayed(runnable, delay);
}
public void scheduleRegion(BukkitRunnable runnable, World world, Chunk chunk, int delay) {
morePaperLib.scheduling().regionSpecificScheduler(world, chunk.getX(), chunk.getZ()).runDelayed(runnable, delay);
}
} }

View File

@@ -19,7 +19,6 @@ package lol.hyper.toolstats.commands;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -42,65 +41,63 @@ import java.util.*;
public class CommandToolStats implements TabExecutor { public class CommandToolStats implements TabExecutor {
private final ToolStats toolStats; private final ToolStats toolStats;
private final BukkitAudiences audiences;
public CommandToolStats(ToolStats toolStats) { public CommandToolStats(ToolStats toolStats) {
this.toolStats = toolStats; this.toolStats = toolStats;
this.audiences = toolStats.getAdventure();
} }
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!sender.hasPermission("toolstats.command")) { if (!sender.hasPermission("toolstats.command")) {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED)); sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
return true; return true;
} }
if (args.length == 0) { if (args.length == 0) {
audiences.sender(sender).sendMessage(Component.text("ToolStats version " + toolStats.getDescription().getVersion() + ". Created by hyperdefined.", NamedTextColor.GREEN)); sender.sendMessage(Component.text("ToolStats version " + toolStats.getPluginMeta().getVersion() + ". Created by hyperdefined.", NamedTextColor.GREEN));
return true; return true;
} }
switch (args[0]) { switch (args[0]) {
case "reload": { case "reload": {
if (sender.hasPermission("toolstats.reload")) { if (sender.hasPermission("toolstats.reload")) {
toolStats.loadConfig(); toolStats.loadConfig();
audiences.sender(sender).sendMessage(Component.text("Configuration reloaded!", NamedTextColor.GREEN)); sender.sendMessage(Component.text("Configuration reloaded!", NamedTextColor.GREEN));
} else { } else {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED)); sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
} }
return true; return true;
} }
case "reset": { case "reset": {
if (!sender.hasPermission("toolstats.reset")) { if (!sender.hasPermission("toolstats.reset")) {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED)); sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
return true; return true;
} }
if (sender instanceof ConsoleCommandSender) { if (sender instanceof ConsoleCommandSender) {
audiences.sender(sender).sendMessage(Component.text("You must be a player for this command.", NamedTextColor.RED)); sender.sendMessage(Component.text("You must be a player for this command.", NamedTextColor.RED));
return true; 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.", NamedTextColor.RED)); sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
return true; return true;
} }
Player player = (Player) sender; Player player = (Player) sender;
ItemStack heldItem = player.getInventory().getItemInMainHand(); ItemStack heldItem = player.getInventory().getItemInMainHand();
if (!toolStats.itemChecker.isValidItem(heldItem.getType())) { if (!toolStats.itemChecker.isValidItem(heldItem.getType())) {
audiences.sender(sender).sendMessage(Component.text("You must hold a valid item.", NamedTextColor.RED)); sender.sendMessage(Component.text("You must hold a valid item.", NamedTextColor.RED));
return true; return true;
} }
fixItemLore(heldItem, player); fixItemLore(heldItem, player);
audiences.sender(sender).sendMessage(Component.text("The lore was reset!", NamedTextColor.GREEN)); sender.sendMessage(Component.text("The lore was reset!", NamedTextColor.GREEN));
return true; return true;
} }
audiences.sender(sender).sendMessage(Component.text("This will remove ALL current lore from the held item and replace it with the correct lore.", NamedTextColor.GREEN)); sender.sendMessage(Component.text("This will remove ALL current lore from the held item and replace it with the correct lore.", NamedTextColor.GREEN));
audiences.sender(sender).sendMessage(Component.text("If the owner of the item is broken, it will reset to the person holding it.", NamedTextColor.GREEN)); sender.sendMessage(Component.text("If the owner of the item is broken, it will reset to the person holding it.", NamedTextColor.GREEN));
audiences.sender(sender).sendMessage(Component.text("Only use this if the tags on the tool are incorrect.", NamedTextColor.GREEN)); sender.sendMessage(Component.text("Only use this if the tags on the tool are incorrect.", NamedTextColor.GREEN));
audiences.sender(sender).sendMessage(Component.text("Type /toolstats reset confirm to confirm this.", NamedTextColor.GREEN)); sender.sendMessage(Component.text("Type /toolstats reset confirm to confirm this.", NamedTextColor.GREEN));
return true; return true;
} }
default: { default: {
audiences.sender(sender).sendMessage(Component.text("Invalid sub-command.", NamedTextColor.RED)); sender.sendMessage(Component.text("Invalid sub-command.", NamedTextColor.RED));
} }
} }
return true; return true;
@@ -119,7 +116,7 @@ public class CommandToolStats implements TabExecutor {
return; return;
} }
PersistentDataContainer container = finalMeta.getPersistentDataContainer(); PersistentDataContainer container = finalMeta.getPersistentDataContainer();
List<String> lore = new ArrayList<>(); List<Component> lore = new ArrayList<>();
// set how the item was obtained // set how the item was obtained
Integer origin = -1; Integer origin = -1;
@@ -145,19 +142,19 @@ public class CommandToolStats implements TabExecutor {
if (flightTime != null) { if (flightTime != null) {
if (toolStats.config.getBoolean("enabled.flight-time")) { if (toolStats.config.getBoolean("enabled.flight-time")) {
String line = toolStats.configTools.formatLore("flight-time", "{time}", toolStats.numberFormat.formatDouble((double) flightTime / 1000)); Component line = toolStats.configTools.formatLore("flight-time", "{time}", toolStats.numberFormat.formatDouble((double) flightTime / 1000));
lore.add(line); lore.add(line);
} }
} }
if (timeCreated != null) { if (timeCreated != null) {
String timeCreatedLine = toolStats.configTools.formatLore("looted.found-by", "{player}", player.getName()); Component timeCreatedLine = toolStats.configTools.formatLore("looted.found-by", "{player}", player.getName());
String playerOwnerLine = toolStats.configTools.formatLore("looted.found-on", "{date}", toolStats.numberFormat.formatDate(new Date(timeCreated))); Component playerOwnerLine = toolStats.configTools.formatLore("looted.found-on", "{date}", toolStats.numberFormat.formatDate(new Date(timeCreated)));
lore.add(timeCreatedLine); lore.add(timeCreatedLine);
lore.add(playerOwnerLine); lore.add(playerOwnerLine);
} }
finalMeta.setLore(lore); finalMeta.lore(lore);
finalItem.setItemMeta(finalMeta); finalItem.setItemMeta(finalMeta);
int slot = player.getInventory().getHeldItemSlot(); int slot = player.getInventory().getHeldItemSlot();
player.getInventory().setItem(slot, finalItem); player.getInventory().setItem(slot, finalItem);
@@ -176,7 +173,7 @@ public class CommandToolStats implements TabExecutor {
// if the owner's name is null for whatever reason, set the new owner // if the owner's name is null for whatever reason, set the new owner
// to the current player running the command // to the current player running the command
if (ownerName == null) { if (ownerName == null) {
audiences.player(player).sendMessage(Component.text("The owner of this item is null. Setting to " + player.getName() + ".", NamedTextColor.RED)); player.sendMessage(Component.text("The owner of this item is null. Setting to " + player.getName() + ".", NamedTextColor.RED));
ownerName = player.getName(); ownerName = player.getName();
container.set(toolStats.genericOwner, new UUIDDataType(), player.getUniqueId()); container.set(toolStats.genericOwner, new UUIDDataType(), player.getUniqueId());
} }
@@ -309,7 +306,7 @@ public class CommandToolStats implements TabExecutor {
} }
} }
} }
finalMeta.setLore(lore); finalMeta.lore(lore);
finalItem.setItemMeta(finalMeta); finalItem.setItemMeta(finalMeta);
int slot = player.getInventory().getHeldItemSlot(); int slot = player.getInventory().getHeldItemSlot();
player.getInventory().setItem(slot, finalItem); player.getInventory().setItem(slot, finalItem);

View File

@@ -18,6 +18,8 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@@ -32,7 +34,6 @@ 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 org.bukkit.scheduler.BukkitRunnable;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -60,13 +61,7 @@ public class BlocksMined implements Listener {
if (block.getType() == Material.CHEST) { if (block.getType() == Material.CHEST) {
toolStats.playerInteract.openedChests.put(block, player); toolStats.playerInteract.openedChests.put(block, player);
BukkitRunnable runnable = new BukkitRunnable() { Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> toolStats.playerInteract.openedChests.remove(block), 20);
@Override
public void run() {
toolStats.playerInteract.openedChests.remove(block);
}
};
toolStats.scheduleGlobal(runnable, 20);
} }
// only check certain items // only check certain items
@@ -110,13 +105,13 @@ public class BlocksMined implements Listener {
if (toolStats.configTools.checkConfig(playerTool.getType(), "blocks-mined")) { if (toolStats.configTools.checkConfig(playerTool.getType(), "blocks-mined")) {
String oldBlocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined); String oldBlocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined);
String newBlocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined + 1); String newBlocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined + 1);
String oldLine = toolStats.configTools.formatLore("blocks-mined", "{blocks}", oldBlocksMinedFormatted); Component oldLine = toolStats.configTools.formatLore("blocks-mined", "{blocks}", oldBlocksMinedFormatted);
String newLine = toolStats.configTools.formatLore("blocks-mined", "{blocks}", newBlocksMinedFormatted); Component newLine = toolStats.configTools.formatLore("blocks-mined", "{blocks}", newBlocksMinedFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
playerTool.setItemMeta(meta); playerTool.setItemMeta(meta);
} }
@@ -151,13 +146,13 @@ public class BlocksMined implements Listener {
if (toolStats.configTools.checkConfig(playerTool.getType(), "blocks-mined")) { if (toolStats.configTools.checkConfig(playerTool.getType(), "blocks-mined")) {
String oldCropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined); String oldCropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined);
String newCropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined + 1); String newCropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined + 1);
String oldLine = toolStats.configTools.formatLore("crops-harvested", "{crops}", oldCropsMinedFormatted); Component oldLine = toolStats.configTools.formatLore("crops-harvested", "{crops}", oldCropsMinedFormatted);
String newLine = toolStats.configTools.formatLore("crops-harvested", "{crops}", newCropsMinedFormatted); Component newLine = toolStats.configTools.formatLore("crops-harvested", "{crops}", newCropsMinedFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
playerTool.setItemMeta(meta); playerTool.setItemMeta(meta);
} }

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
@@ -31,7 +32,6 @@ import org.bukkit.inventory.ItemStack;
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 org.bukkit.scheduler.BukkitRunnable;
public class ChunkPopulate implements Listener { public class ChunkPopulate implements Listener {
@@ -49,34 +49,30 @@ public class ChunkPopulate implements Listener {
if (event.getChunk().getWorld().getEnvironment() != World.Environment.THE_END) { if (event.getChunk().getWorld().getEnvironment() != World.Environment.THE_END) {
return; return;
} }
World world = event.getChunk().getWorld();
// this is delayed because entities are not loaded instantly // this is delayed because entities are not loaded instantly
// we just check 1 second later // we just check 1 second later
Chunk chunk = event.getChunk(); Chunk chunk = event.getChunk();
BukkitRunnable runnable = new BukkitRunnable() { Bukkit.getRegionScheduler().runDelayed(toolStats, world, chunk.getX(), chunk.getZ(), scheduledTask -> {
@Override for (Entity entity : chunk.getEntities()) {
public void run() { // if there is a new item frame
for (Entity entity : chunk.getEntities()) { if (!(entity instanceof ItemFrame itemFrame)) {
// if there is a new item frame continue;
if (!(entity instanceof ItemFrame)) { }
// if the item frame has an elytra
if (itemFrame.getItem().getType() == Material.ELYTRA) {
ItemStack elytraCopy = itemFrame.getItem();
ItemMeta meta = elytraCopy.getItemMeta();
if (meta == null) {
continue; continue;
} }
ItemFrame itemFrame = (ItemFrame) entity; // add the new tag so we know it's new
// if the item frame has an elytra PersistentDataContainer container = meta.getPersistentDataContainer();
if (itemFrame.getItem().getType() == Material.ELYTRA) { container.set(toolStats.newElytra, PersistentDataType.INTEGER, 1);
ItemStack elytraCopy = itemFrame.getItem(); elytraCopy.setItemMeta(meta);
ItemMeta meta = elytraCopy.getItemMeta(); itemFrame.setItem(elytraCopy);
if (meta == null) {
continue;
}
// 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);
toolStats.scheduleRegion(runnable, chunk.getWorld(), chunk, 20);
} }
} }

View File

@@ -17,9 +17,11 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import org.bukkit.ChatColor; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
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;
@@ -27,12 +29,17 @@ 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.inventory.CraftItemEvent; import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.inventory.Inventory;
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.*; import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
public class CraftItem implements Listener { public class CraftItem implements Listener {
@@ -51,26 +58,51 @@ public class CraftItem implements Listener {
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
ItemStack itemStack = event.getCurrentItem(); ItemStack craftedItem = event.getCurrentItem();
if (itemStack == null || itemStack.getType() == Material.AIR) { if (craftedItem == null || craftedItem.getType() == Material.AIR) {
return; return;
} }
Material craftedMaterial = craftedItem.getType();
// only check certain items // only check certain items
if (!toolStats.itemChecker.isValidItem(itemStack.getType())) { if (!toolStats.itemChecker.isValidItem(craftedMaterial)) {
return; return;
} }
// if the player shift clicks, send them this warning // if the player shift clicks
if (event.isShiftClick()) { if (event.isShiftClick()) {
String configMessage = toolStats.config.getString("messages.shift-click-warning.crafting"); // store the player inventory before they craft the items
if (configMessage != null) { ItemStack[] beforeCraft = player.getInventory().getContents();
if (!configMessage.isEmpty()) { // run a tick after to see the changes
event.getWhoClicked().sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage)); player.getScheduler().runDelayed(toolStats, scheduledTask -> {
// get their inventory after the craft
ItemStack[] afterCraft = player.getInventory().getContents();
for (int i = 0; i < afterCraft.length; i++) {
ItemStack newSlotItem = afterCraft[i];
ItemStack oldSlotItem = beforeCraft[i];
// if this slot is empty after crafting, skip it
if (newSlotItem == null) {
continue;
}
// if the item matches what we crafted
if (newSlotItem.getType() == craftedMaterial) {
// if the slot was empty before we crafted, this means we just made it
if (oldSlotItem == null) {
// add the lore
ItemStack newItem = addLore(newSlotItem, player);
if (newItem != null) {
player.getInventory().setItem(i, newItem);
}
}
}
} }
} }, null, 1);
return;
} }
// test the item before setting it
ItemStack newItem = addLore(itemStack, player); // the player did not shift click
ItemStack newItem = addLore(craftedItem, player);
if (newItem != null) { if (newItem != null) {
// set the result // set the result
event.setCurrentItem(newItem); event.setCurrentItem(newItem);
@@ -113,30 +145,30 @@ public class CraftItem implements Listener {
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 0); container.set(toolStats.originType, PersistentDataType.INTEGER, 0);
List<String> lore; List<Component> lore;
// get the current lore the item // get the current lore the item
if (meta.hasLore()) { if (meta.hasLore()) {
lore = meta.getLore(); lore = meta.lore();
} else { } else {
lore = new ArrayList<>(); lore = new ArrayList<>();
} }
// do we add the lore based on the config? // do we add the lore based on the config?
if (toolStats.configTools.checkConfig(itemStack.getType(), "created-date")) { if (toolStats.configTools.checkConfig(itemStack.getType(), "created-date")) {
String date = toolStats.numberFormat.formatDate(finalDate); String date = toolStats.numberFormat.formatDate(finalDate);
String newLine = toolStats.configTools.formatLore("created.created-on", "{date}", date); Component newLine = toolStats.configTools.formatLore("created.created-on", "{date}", date);
if (newLine == null) { if (newLine == null) {
return null; return null;
} }
lore.add(newLine); lore.add(newLine);
meta.setLore(lore); meta.lore(lore);
} }
if (toolStats.configTools.checkConfig(itemStack.getType(), "created-by")) { if (toolStats.configTools.checkConfig(itemStack.getType(), "created-by")) {
String newLine = toolStats.configTools.formatLore("created.created-by", "{player}", owner.getName()); Component newLine = toolStats.configTools.formatLore("created.created-by", "{player}", owner.getName());
if (newLine == null) { if (newLine == null) {
return null; return null;
} }
lore.add(newLine); lore.add(newLine);
meta.setLore(lore); meta.lore(lore);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
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;
@@ -104,8 +105,8 @@ public class CreativeEvent implements Listener {
if (toolStats.configTools.checkConfig(newSpawnedItem.getType(), "spawned-in")) { if (toolStats.configTools.checkConfig(newSpawnedItem.getType(), "spawned-in")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate); List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore); meta.lore(newLore);
} }
newSpawnedItem.setItemMeta(meta); newSpawnedItem.setItemMeta(meta);

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.*; import org.bukkit.entity.*;
@@ -39,7 +40,7 @@ public class EntityDamage implements Listener {
private final ToolStats toolStats; private final ToolStats toolStats;
public final Set<UUID> trackedMobs = new HashSet<>(); public final Set<UUID> trackedMobs = new HashSet<>();
private final List<String> ignoredDamageCauses = Arrays.asList("SUICIDE", "VOID", "CUSTOM", "KILL"); private final List<EntityDamageEvent.DamageCause> ignoredCauses = Arrays.asList(EntityDamageEvent.DamageCause.SUICIDE, EntityDamageEvent.DamageCause.VOID, EntityDamageEvent.DamageCause.CUSTOM, EntityDamageEvent.DamageCause.KILL);
public EntityDamage(ToolStats toolStats) { public EntityDamage(ToolStats toolStats) {
this.toolStats = toolStats; this.toolStats = toolStats;
@@ -51,22 +52,20 @@ public class EntityDamage implements Listener {
return; return;
} }
if (!(event.getEntity() instanceof LivingEntity)) { if (!(event.getEntity() instanceof LivingEntity mobBeingAttacked)) {
return; return;
} }
LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// ignore void and /kill damage // ignore void and /kill damage
String cause = event.getCause().toString().toUpperCase(); EntityDamageEvent.DamageCause cause = event.getCause();
if (ignoredDamageCauses.contains(cause)) { if (ignoredCauses.contains(cause)) {
return; return;
} }
// mob is going to die // mob is going to die
if (mobBeingAttacked.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 attackingPlayer) {
Player attackingPlayer = (Player) event.getDamager();
if (attackingPlayer.getGameMode() == GameMode.CREATIVE || attackingPlayer.getGameMode() == GameMode.SPECTATOR) { if (attackingPlayer.getGameMode() == GameMode.CREATIVE || attackingPlayer.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
@@ -86,45 +85,38 @@ public class EntityDamage implements Listener {
trackedMobs.add(mobBeingAttacked.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 = (Trident) event.getDamager();
ItemStack newTrident; ItemStack newTrident;
// trident is killing player // trident is killing player
if (mobBeingAttacked instanceof Player) { if (mobBeingAttacked instanceof Player) {
newTrident = tridentPlayerKills(trident.getItem()); newTrident = tridentPlayerKills(trident.getItemStack());
} else { } else {
// trident is killing a mob // trident is killing a mob
newTrident = tridentMobKills(trident.getItem()); newTrident = tridentMobKills(trident.getItemStack());
trackedMobs.add(mobBeingAttacked.getUniqueId()); trackedMobs.add(mobBeingAttacked.getUniqueId());
} }
if (newTrident != null) { if (newTrident != null) {
trident.setItem(newTrident); trident.setItemStack(newTrident);
} }
} }
// arrow is being shot // arrow is being shot
if (event.getDamager() instanceof Arrow) { if (event.getDamager() instanceof Arrow arrow) {
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 shootingPlayer) {
Player shootingPlayer = (Player) arrow.getShooter();
if (shootingPlayer.getGameMode() == GameMode.CREATIVE || shootingPlayer.getGameMode() == GameMode.SPECTATOR) { if (shootingPlayer.getGameMode() == GameMode.CREATIVE || shootingPlayer.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
PlayerInventory inventory = shootingPlayer.getInventory(); PlayerInventory inventory = shootingPlayer.getInventory();
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW; ItemStack main = inventory.getItemInMainHand();
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW; ItemStack offHand = inventory.getItemInOffHand();
boolean isMain = main.getType() == Material.BOW || main.getType() == Material.CROSSBOW;
boolean isOffHand = offHand.getType() == Material.BOW || offHand.getType() == Material.CROSSBOW;
ItemStack heldBow = null; ItemStack heldBow = null;
if (isMainHand) { if (isMain) {
heldBow = inventory.getItemInMainHand(); heldBow = main;
} }
if (isOffHand) { if (isOffHand) {
heldBow = inventory.getItemInOffHand(); heldBow = offHand;
}
// if the player is holding a bow in both hands
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
heldBow = inventory.getItemInMainHand();
} }
// player swapped // player swapped
@@ -143,8 +135,7 @@ public class EntityDamage implements Listener {
} }
} }
// player is taken damage but not being killed // player is taken damage but not being killed
if (mobBeingAttacked instanceof Player) { if (mobBeingAttacked instanceof Player playerTakingDamage) {
Player playerTakingDamage = (Player) mobBeingAttacked;
if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) { if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
@@ -161,20 +152,18 @@ public class EntityDamage implements Listener {
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onDamage(EntityDamageEvent event) { public void onDamage(EntityDamageEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) { if (!(event.getEntity() instanceof LivingEntity mobBeingAttacked)) {
return; return;
} }
// ignore void and /kill damage // ignore void and /kill damage
String cause = event.getCause().toString().toUpperCase(); EntityDamageEvent.DamageCause cause = event.getCause();
if (ignoredDamageCauses.contains(cause)) { if (ignoredCauses.contains(cause)) {
return; return;
} }
LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// player is taken damage but not being killed // player is taken damage but not being killed
if (mobBeingAttacked instanceof Player) { if (mobBeingAttacked instanceof Player playerTakingDamage) {
Player playerTakingDamage = (Player) mobBeingAttacked;
if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) { if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
@@ -191,20 +180,18 @@ public class EntityDamage implements Listener {
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onDamage(EntityDamageByBlockEvent event) { public void onDamage(EntityDamageByBlockEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) { if (!(event.getEntity() instanceof LivingEntity mobBeingAttacked)) {
return; return;
} }
// ignore void and /kill damage // ignore void and /kill damage
String cause = event.getCause().toString().toUpperCase(); EntityDamageEvent.DamageCause cause = event.getCause();
if (ignoredDamageCauses.contains(cause)) { if (ignoredCauses.contains(cause)) {
return; return;
} }
LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// player is taken damage but not being killed // player is taken damage but not being killed
if (mobBeingAttacked instanceof Player) { if (mobBeingAttacked instanceof Player playerTakingDamage) {
Player playerTakingDamage = (Player) mobBeingAttacked;
if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) { if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
@@ -247,13 +234,13 @@ public class EntityDamage implements Listener {
if (toolStats.configTools.checkConfig(itemStack.getType(), "player-kills")) { if (toolStats.configTools.checkConfig(itemStack.getType(), "player-kills")) {
String oldPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills); String oldPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
String newPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills + 1); String newPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills + 1);
String oldLine = toolStats.configTools.formatLore("kills.player", "{kills}", oldPlayerKillsFormatted); Component oldLine = toolStats.configTools.formatLore("kills.player", "{kills}", oldPlayerKillsFormatted);
String newLine = toolStats.configTools.formatLore("kills.player", "{kills}", newPlayerKillsFormatted); Component newLine = toolStats.configTools.formatLore("kills.player", "{kills}", newPlayerKillsFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
itemStack.setItemMeta(meta); itemStack.setItemMeta(meta);
} }
@@ -286,13 +273,13 @@ public class EntityDamage implements Listener {
if (toolStats.configTools.checkConfig(itemStack.getType(), "mob-kills")) { if (toolStats.configTools.checkConfig(itemStack.getType(), "mob-kills")) {
String oldMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills); String oldMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
String newMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills + 1); String newMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills + 1);
String oldLine = toolStats.configTools.formatLore("kills.mob", "{kills}", oldMobKillsFormatted); Component oldLine = toolStats.configTools.formatLore("kills.mob", "{kills}", oldMobKillsFormatted);
String newLine = toolStats.configTools.formatLore("kills.mob", "{kills}", newMobKillsFormatted); Component newLine = toolStats.configTools.formatLore("kills.mob", "{kills}", newMobKillsFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
itemStack.setItemMeta(meta); itemStack.setItemMeta(meta);
} }
@@ -329,13 +316,13 @@ public class EntityDamage implements Listener {
if (toolStats.config.getBoolean("enabled.armor-damage")) { if (toolStats.config.getBoolean("enabled.armor-damage")) {
String oldDamageFormatted = toolStats.numberFormat.formatDouble(damageTaken); String oldDamageFormatted = toolStats.numberFormat.formatDouble(damageTaken);
String newDamageFormatted = toolStats.numberFormat.formatDouble(damageTaken + damage); String newDamageFormatted = toolStats.numberFormat.formatDouble(damageTaken + damage);
String oldLine = toolStats.configTools.formatLore("damage-taken", "{damage}", oldDamageFormatted); Component oldLine = toolStats.configTools.formatLore("damage-taken", "{damage}", oldDamageFormatted);
String newLine = toolStats.configTools.formatLore("damage-taken", "{damage}", newDamageFormatted); Component newLine = toolStats.configTools.formatLore("damage-taken", "{damage}", newDamageFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
itemStack.setItemMeta(meta); itemStack.setItemMeta(meta);
} }
@@ -369,13 +356,13 @@ public class EntityDamage implements Listener {
if (toolStats.configTools.checkConfig(newTrident.getType(), "mob-kills")) { if (toolStats.configTools.checkConfig(newTrident.getType(), "mob-kills")) {
String oldMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills); String oldMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
String newMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills + 1); String newMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills + 1);
String oldLine = toolStats.configTools.formatLore("kills.mob", "{kills}", oldMobKillsFormatted); Component oldLine = toolStats.configTools.formatLore("kills.mob", "{kills}", oldMobKillsFormatted);
String newLine = toolStats.configTools.formatLore("kills.mob", "{kills}", newMobKillsFormatted); Component newLine = toolStats.configTools.formatLore("kills.mob", "{kills}", newMobKillsFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return null; return null;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
newTrident.setItemMeta(meta); newTrident.setItemMeta(meta);
return newTrident; return newTrident;
@@ -410,13 +397,13 @@ public class EntityDamage implements Listener {
if (toolStats.configTools.checkConfig(newTrident.getType(), "player-kills")) { if (toolStats.configTools.checkConfig(newTrident.getType(), "player-kills")) {
String oldPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills); String oldPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
String newPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills + 1); String newPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills + 1);
String oldLine = toolStats.configTools.formatLore("kills.player", "{kills}", oldPlayerKillsFormatted); Component oldLine = toolStats.configTools.formatLore("kills.player", "{kills}", oldPlayerKillsFormatted);
String newLine = toolStats.configTools.formatLore("kills.player", "{kills}", newPlayerKillsFormatted); Component newLine = toolStats.configTools.formatLore("kills.player", "{kills}", newPlayerKillsFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return null; return null;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
newTrident.setItemMeta(meta); newTrident.setItemMeta(meta);
return newTrident; return newTrident;

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
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;
@@ -91,9 +92,9 @@ public class EntityDeath implements Listener {
if (mobName == null) { if (mobName == null) {
mobName = entity.getName(); mobName = entity.getName();
} }
String newLine = toolStats.configTools.formatLore("dropped-by", "{name}", mobName); Component newLine = toolStats.configTools.formatLore("dropped-by", "{name}", mobName);
List<String> newLore = toolStats.itemLore.addItemLore(meta, newLine); List<Component> newLore = toolStats.itemLore.addItemLore(meta, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@@ -76,8 +77,7 @@ public class GenerateLoot implements Listener {
Player player = toolStats.playerInteract.openedChests.get(openedChest); Player player = toolStats.playerInteract.openedChests.get(openedChest);
setLoot(event.getLoot(), player); setLoot(event.getLoot(), player);
} }
if (inventoryHolder instanceof StorageMinecart) { if (inventoryHolder instanceof StorageMinecart mineCart) {
StorageMinecart mineCart = (StorageMinecart) inventoryHolder;
if (toolStats.playerInteract.openedMineCarts.containsKey(mineCart)) { if (toolStats.playerInteract.openedMineCarts.containsKey(mineCart)) {
Player player = toolStats.playerInteract.openedMineCarts.get(mineCart); Player player = toolStats.playerInteract.openedMineCarts.get(mineCart);
setLoot(event.getLoot(), player); setLoot(event.getLoot(), player);
@@ -118,8 +118,8 @@ public class GenerateLoot implements Listener {
if (toolStats.configTools.checkConfig(newItem.getType(), "looted-tag")) { if (toolStats.configTools.checkConfig(newItem.getType(), "looted-tag")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate); List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore); meta.lore(newLore);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@@ -28,7 +29,6 @@ import org.bukkit.inventory.ItemStack;
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 org.bukkit.scheduler.BukkitRunnable;
import java.util.UUID; import java.util.UUID;
@@ -83,14 +83,8 @@ public class InventoryOpen implements Listener {
} }
} }
ItemMeta clone = itemMeta.clone(); ItemMeta clone = itemMeta.clone();
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
itemStack.setItemMeta(clone);
}
};
if (location != null) { if (location != null) {
toolStats.scheduleRegion(runnable, location.getWorld(), location.getChunk(), 1); Bukkit.getRegionScheduler().runDelayed(toolStats, location, scheduledTask -> itemStack.setItemMeta(clone), 1);
} }
} }
} }

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.*; import org.bukkit.entity.*;
@@ -48,13 +49,12 @@ public class PickupItem implements Listener {
return; return;
} }
Entity entity = event.getEntity(); Entity entity = event.getEntity();
if (entity instanceof Player) { if (entity instanceof Player player) {
Player player = (Player) entity;
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
Item item = event.getItem(); Item item = event.getItem();
if (item.getType() == EntityType.DROPPED_ITEM) { if (item.getType() == EntityType.ITEM) {
ItemStack itemStack = event.getItem().getItemStack(); ItemStack itemStack = event.getItem().getItemStack();
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = itemStack.getItemMeta();
if (meta == null) { if (meta == null) {
@@ -103,8 +103,8 @@ public class PickupItem implements Listener {
if (toolStats.config.getBoolean("enabled.elytra-tag")) { if (toolStats.config.getBoolean("enabled.elytra-tag")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate); List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore); meta.lore(newLore);
} }
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
return finalItem; return finalItem;

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
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;
@@ -130,13 +131,13 @@ public class PlayerFish implements Listener {
if (toolStats.config.getBoolean("enabled.fish-caught")) { if (toolStats.config.getBoolean("enabled.fish-caught")) {
String oldFishFormatted = toolStats.numberFormat.formatInt(fishCaught); String oldFishFormatted = toolStats.numberFormat.formatInt(fishCaught);
String newFishFormatted = toolStats.numberFormat.formatInt(fishCaught + 1); String newFishFormatted = toolStats.numberFormat.formatInt(fishCaught + 1);
String oldLine = toolStats.configTools.formatLore("fished.fish-caught", "{fish}", oldFishFormatted); Component oldLine = toolStats.configTools.formatLore("fished.fish-caught", "{fish}", oldFishFormatted);
String newLine = toolStats.configTools.formatLore("fished.fish-caught", "{fish}", newFishFormatted); Component newLine = toolStats.configTools.formatLore("fished.fish-caught", "{fish}", newFishFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
fishingRod.setItemMeta(meta); fishingRod.setItemMeta(meta);
} }
@@ -171,8 +172,8 @@ public class PlayerFish implements Listener {
if (toolStats.configTools.checkConfig(newItem.getType(), "fished-tag")) { if (toolStats.configTools.checkConfig(newItem.getType(), "fished-tag")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate); List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore); meta.lore(newLore);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@@ -30,7 +31,6 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -64,13 +64,7 @@ public class PlayerInteract implements Listener {
// store when a player opens a chest // store when a player opens a chest
if (block.getType() != Material.AIR && block.getType() == Material.CHEST) { if (block.getType() != Material.AIR && block.getType() == Material.CHEST) {
openedChests.put(block, player); openedChests.put(block, player);
BukkitRunnable runnable = new BukkitRunnable() { Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> openedChests.remove(block), 20);
@Override
public void run() {
openedChests.remove(block);
}
};
toolStats.scheduleGlobal(runnable, 20);
} }
} }
@@ -82,16 +76,10 @@ public class PlayerInteract implements Listener {
return; return;
} }
// store when a player opens a minecart // store when a player opens a minecart
if (clicked.getType() == EntityType.MINECART_CHEST) { if (clicked.getType() == EntityType.CHEST_MINECART) {
StorageMinecart storageMinecart = (StorageMinecart) clicked; StorageMinecart storageMinecart = (StorageMinecart) clicked;
openedMineCarts.put(storageMinecart, player); openedMineCarts.put(storageMinecart, player);
BukkitRunnable runnable = new BukkitRunnable() { Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> openedMineCarts.remove(storageMinecart), 20);
@Override
public void run() {
openedMineCarts.remove(storageMinecart);
}
};
toolStats.scheduleGlobal(runnable, 20);
} }
} }
} }

View File

@@ -28,7 +28,6 @@ import org.bukkit.inventory.ItemStack;
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 org.bukkit.scheduler.BukkitRunnable;
import java.util.UUID; import java.util.UUID;
@@ -77,13 +76,7 @@ public class PlayerJoin implements Listener {
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.hash, PersistentDataType.STRING, hash);
} }
ItemMeta clone = itemMeta.clone(); ItemMeta clone = itemMeta.clone();
BukkitRunnable runnable = new BukkitRunnable() { player.getScheduler().runDelayed(toolStats, scheduledTask -> itemStack.setItemMeta(clone), null, 1);
@Override
public void run() {
itemStack.setItemMeta(clone);
}
};
toolStats.scheduleEntity(runnable, player, 1);
} }
} }
} }

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
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;
@@ -94,13 +95,13 @@ public class PlayerMove implements Listener {
if (toolStats.config.getBoolean("enabled.flight-time")) { if (toolStats.config.getBoolean("enabled.flight-time")) {
String oldFlightFormatted = toolStats.numberFormat.formatDouble((double) flightTime / 1000); String oldFlightFormatted = toolStats.numberFormat.formatDouble((double) flightTime / 1000);
String newFlightFormatted = toolStats.numberFormat.formatDouble(newDuration / 1000); String newFlightFormatted = toolStats.numberFormat.formatDouble(newDuration / 1000);
String oldLine = toolStats.configTools.formatLore("flight-time", "{time}", oldFlightFormatted); Component oldLine = toolStats.configTools.formatLore("flight-time", "{time}", oldFlightFormatted);
String newLine = toolStats.configTools.formatLore("flight-time", "{time}", newFlightFormatted); Component newLine = toolStats.configTools.formatLore("flight-time", "{time}", newFlightFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
chest.setItemMeta(meta); chest.setItemMeta(meta);
} }

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
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;
@@ -54,44 +55,43 @@ public class SheepShear implements Listener {
return; return;
} }
Entity entity = event.getRightClicked(); Entity entity = event.getRightClicked();
if (!(entity instanceof Sheep)) { if (!(entity instanceof Sheep sheep)) {
return; return;
} }
ItemStack shears = getShears(player); ItemStack heldShears = getShears(player.getInventory());
// player swapped items? // player swapped or we can't get the shears
if (shears == null) { if (heldShears == null) {
return; return;
} }
// make sure the sheep is not sheared // make sure the sheep is not sheared
Sheep sheep = (Sheep) entity;
if (sheep.isSheared()) { if (sheep.isSheared()) {
return; return;
} }
// update the stats // update the stats
addLore(shears); addLore(heldShears);
} }
private static @Nullable ItemStack getShears(Player player) { private static @Nullable ItemStack getShears(PlayerInventory inventory) {
PlayerInventory inventory = player.getInventory(); ItemStack main = inventory.getItemInMainHand();
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.SHEARS; ItemStack offHand = inventory.getItemInOffHand();
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.SHEARS;
ItemStack shears = null; boolean isMain = main.getType() == Material.SHEARS;
if (isMainHand) { boolean isOffHand = offHand.getType() == Material.SHEARS;
shears = inventory.getItemInMainHand();
// if the player is holding shears in their main hand, use that one
// if the shears are in their offhand instead, use that one after checking main hand
// Minecraft prioritizes main hand if the player holds in both hands
if (isMain) {
return main;
} }
if (isOffHand) { if (isOffHand) {
shears = inventory.getItemInOffHand(); return offHand;
} }
// if the player is hold shears in both hands return null;
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
shears = inventory.getItemInMainHand();
}
return shears;
} }
/** /**
@@ -121,13 +121,13 @@ public class SheepShear implements Listener {
if (toolStats.config.getBoolean("enabled.sheep-sheared")) { if (toolStats.config.getBoolean("enabled.sheep-sheared")) {
String oldSheepFormatted = toolStats.numberFormat.formatInt(sheepSheared); String oldSheepFormatted = toolStats.numberFormat.formatInt(sheepSheared);
String newSheepFormatted = toolStats.numberFormat.formatInt(sheepSheared + 1); String newSheepFormatted = toolStats.numberFormat.formatInt(sheepSheared + 1);
String oldLine = toolStats.configTools.formatLore("sheep-sheared", "{sheep}", oldSheepFormatted); Component oldLine = toolStats.configTools.formatLore("sheep-sheared", "{sheep}", oldSheepFormatted);
String newLine = toolStats.configTools.formatLore("sheep-sheared", "{sheep}", newSheepFormatted); Component newLine = toolStats.configTools.formatLore("sheep-sheared", "{sheep}", newSheepFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
newShears.setItemMeta(meta); newShears.setItemMeta(meta);
} }

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
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;
@@ -47,19 +48,16 @@ public class ShootBow implements Listener {
public void onShoot(EntityShootBowEvent event) { public void onShoot(EntityShootBowEvent event) {
Entity shooter = event.getEntity(); Entity shooter = event.getEntity();
// only listen for players // only listen for players
if (!(shooter instanceof Player)) { if (!(shooter instanceof Player player)) {
return; return;
} }
Player player = (Player) shooter;
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.ADVENTURE) { if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.ADVENTURE) {
return; return;
} }
PlayerInventory inventory = player.getInventory(); ItemStack heldBow = getBow(player.getInventory());
ItemStack heldBow = getBow(inventory); // player swapped or we can't get the bow
// player swapped
if (heldBow == null) { if (heldBow == null) {
return; return;
} }
@@ -68,22 +66,23 @@ public class ShootBow implements Listener {
} }
private static @Nullable ItemStack getBow(PlayerInventory inventory) { private static @Nullable ItemStack getBow(PlayerInventory inventory) {
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW; ItemStack main = inventory.getItemInMainHand();
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW; ItemStack offHand = inventory.getItemInOffHand();
ItemStack heldBow = null;
if (isMainHand) { boolean isMain = main.getType() == Material.BOW || main.getType() == Material.CROSSBOW;
heldBow = inventory.getItemInMainHand(); boolean isOffHand = offHand.getType() == Material.BOW || offHand.getType() == Material.CROSSBOW;
// if the player is holding a bow in their main hand, use that one
// if the bow is in their offhand instead, use that one after checking main hand
// Minecraft prioritizes main hand if the player holds in both hands
if (isMain) {
return main;
} }
if (isOffHand) { if (isOffHand) {
heldBow = inventory.getItemInOffHand(); return offHand;
} }
// if the player is holding a bow in both hands return null;
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
heldBow = inventory.getItemInMainHand();
}
return heldBow;
} }
private void updateArrowsShot(ItemStack bow) { private void updateArrowsShot(ItemStack bow) {
@@ -111,13 +110,13 @@ public class ShootBow implements Listener {
if (toolStats.config.getBoolean("enabled.arrows-shot")) { if (toolStats.config.getBoolean("enabled.arrows-shot")) {
String oldArrowsFormatted = toolStats.numberFormat.formatInt(arrowsShot); String oldArrowsFormatted = toolStats.numberFormat.formatInt(arrowsShot);
String newArrowsFormatted = toolStats.numberFormat.formatInt(arrowsShot + 1); String newArrowsFormatted = toolStats.numberFormat.formatInt(arrowsShot + 1);
String oldLine = toolStats.configTools.formatLore("arrows-shot", "{arrows}", oldArrowsFormatted); Component oldLine = toolStats.configTools.formatLore("arrows-shot", "{arrows}", oldArrowsFormatted);
String newLine = toolStats.configTools.formatLore("arrows-shot", "{arrows}", newArrowsFormatted); Component newLine = toolStats.configTools.formatLore("arrows-shot", "{arrows}", newArrowsFormatted);
if (oldLine == null || newLine == null) { if (oldLine == null || newLine == null) {
return; return;
} }
List<String> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.setLore(newLore); meta.lore(newLore);
} }
bow.setItemMeta(meta); bow.setItemMeta(meta);
} }

View File

@@ -19,8 +19,9 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType; import lol.hyper.toolstats.tools.UUIDDataType;
import org.bukkit.ChatColor; import net.kyori.adventure.text.Component;
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;
@@ -51,35 +52,62 @@ public class VillagerTrade implements Listener {
return; return;
} }
Inventory inventory = event.getClickedInventory(); Inventory inventory = event.getClickedInventory();
if (!(event.getWhoClicked() instanceof Player)) { if (!(event.getWhoClicked() instanceof Player player)) {
return; return;
} }
Player player = (Player) event.getWhoClicked();
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
// only check villager inventories // only check villager inventories
if (inventory instanceof MerchantInventory) { if (!(inventory instanceof MerchantInventory)) {
// only check the result slot (the item you receive) return;
if (event.getSlotType() == InventoryType.SlotType.RESULT) { }
ItemStack item = event.getCurrentItem(); // only check the result slot (the item you receive)
// only check items we want if (event.getSlotType() != InventoryType.SlotType.RESULT) {
if (!toolStats.itemChecker.isValidItem(item.getType())) { return;
return; }
} ItemStack tradedItem = event.getCurrentItem();
// if the player shift clicks, show the warning Material tradedMaterial = tradedItem.getType();
if (event.isShiftClick()) { // only check items we want
String configMessage = toolStats.config.getString("messages.shift-click-warning.trading"); if (!toolStats.itemChecker.isValidItem(tradedMaterial)) {
if (configMessage != null) { return;
player.sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage)); }
// if the player shift clicks
if (event.isShiftClick()) {
// store the player inventory before they trade the items
ItemStack[] beforeTrade = player.getInventory().getContents();
// run a tick after to see the changes
player.getScheduler().runDelayed(toolStats, scheduledTask -> {
// get their inventory after the trade
ItemStack[] afterTrade = player.getInventory().getContents();
for (int i = 0; i < afterTrade.length; i++) {
ItemStack newSlotItem = afterTrade[i];
ItemStack oldSlotItem = beforeTrade[i];
// if this slot is empty after trading, skip it
if (newSlotItem == null) {
continue;
}
// if the item matches what we traded
if (newSlotItem.getType() == tradedMaterial) {
// if the slot was empty before we traded, this means we just traded it
if (oldSlotItem == null) {
// add the lore
ItemStack newItem = addLore(newSlotItem, player);
if (newItem != null) {
player.getInventory().setItem(i, newItem);
}
}
} }
} }
ItemStack newItem = addLore(item, player); }, null, 1);
if (newItem != null) { return;
// set the new item }
inventory.setItem(event.getSlot(), newItem); ItemStack newItem = addLore(tradedItem, player);
} if (newItem != null) {
} // set the new item
inventory.setItem(event.getSlot(), newItem);
} }
} }
@@ -117,8 +145,8 @@ public class VillagerTrade implements Listener {
if (toolStats.configTools.checkConfig(newItem.getType(), "traded-tag")) { if (toolStats.configTools.checkConfig(newItem.getType(), "traded-tag")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate); String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate); List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore); meta.lore(newLore);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -47,9 +47,6 @@ public class ItemChecker {
if (lowerCase.contains("_helmet") || lowerCase.contains("_chestplate") || lowerCase.contains("_leggings") || lowerCase.contains("_boots")) { if (lowerCase.contains("_helmet") || lowerCase.contains("_chestplate") || lowerCase.contains("_leggings") || lowerCase.contains("_boots")) {
armorItems.add(material); armorItems.add(material);
} }
if (lowerCase.equalsIgnoreCase("mace")) {
meleeItems.add(material);
}
} }
// hardcode these // hardcode these
@@ -59,6 +56,7 @@ public class ItemChecker {
validItems.add(Material.FISHING_ROD); validItems.add(Material.FISHING_ROD);
validItems.add(Material.CROSSBOW); validItems.add(Material.CROSSBOW);
validItems.add(Material.ELYTRA); validItems.add(Material.ELYTRA);
validItems.add(Material.MACE);
// combine the lists // combine the lists
validItems.addAll(armorItems); validItems.addAll(armorItems);

View File

@@ -18,6 +18,8 @@
package lol.hyper.toolstats.tools; package lol.hyper.toolstats.tools;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
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;
@@ -41,18 +43,17 @@ public class ItemLore {
* @param newLine The new line to replace oldLine. * @param newLine The new line to replace oldLine.
* @return The item's new lore. * @return The item's new lore.
*/ */
public List<String> updateItemLore(ItemMeta itemMeta, String oldLine, String newLine) { public List<Component> updateItemLore(ItemMeta itemMeta, Component oldLine, Component newLine) {
List<String> itemLore; List<Component> itemLore;
oldLine = toolStats.configTools.removeColor(oldLine);
if (itemMeta.hasLore()) { if (itemMeta.hasLore()) {
itemLore = itemMeta.getLore(); itemLore = itemMeta.lore();
// keep track of line index // keep track of line index
// this doesn't mess the lore of existing items // this doesn't mess the lore of existing items
for (int x = 0; x < itemLore.size(); x++) { for (int x = 0; x < itemLore.size(); x++) {
// check to see if the line matches the config value String line = PlainTextComponentSerializer.plainText().serialize(itemLore.get(x));
// find the old line to update, keeping index
// this means we update this line only! // this means we update this line only!
String line = toolStats.configTools.removeColor(itemLore.get(x)); if (line.equals(PlainTextComponentSerializer.plainText().serialize(oldLine))) {
if (line.equals(oldLine)) {
itemLore.set(x, newLine); itemLore.set(x, newLine);
return itemLore; return itemLore;
} }
@@ -67,10 +68,10 @@ public class ItemLore {
return itemLore; return itemLore;
} }
public List<String> addItemLore(ItemMeta itemMeta, String newLine) { public List<Component> addItemLore(ItemMeta itemMeta, Component newLine) {
List<String> itemLore; List<Component> itemLore;
if (itemMeta.hasLore()) { if (itemMeta.hasLore()) {
itemLore = itemMeta.getLore(); itemLore = itemMeta.lore();
itemLore.add(newLine); itemLore.add(newLine);
} else { } else {
itemLore = new ArrayList<>(); itemLore = new ArrayList<>();
@@ -87,9 +88,9 @@ public class ItemLore {
* @param formattedDate The date of the ownership. * @param formattedDate The date of the ownership.
* @return The item's new lore. * @return The item's new lore.
*/ */
public List<String> addNewOwner(ItemMeta itemMeta, String playerName, String formattedDate) { public List<Component> addNewOwner(ItemMeta itemMeta, String playerName, String formattedDate) {
String dateCreatedLore; Component dateCreatedLore;
String itemOwnerLore; Component itemOwnerLore;
Integer origin = null; Integer origin = null;
PersistentDataContainer container = itemMeta.getPersistentDataContainer(); PersistentDataContainer container = itemMeta.getPersistentDataContainer();
if (container.has(toolStats.originType, PersistentDataType.INTEGER)) { if (container.has(toolStats.originType, PersistentDataType.INTEGER)) {
@@ -100,7 +101,7 @@ public class ItemLore {
if (origin == null) { if (origin == null) {
toolStats.logger.info("Unable to determine origin for item " + itemMeta.getAsString()); toolStats.logger.info("Unable to determine origin for item " + itemMeta.getAsString());
toolStats.logger.info("This IS a bug, please report this to the GitHub."); toolStats.logger.info("This IS a bug, please report this to the GitHub.");
return itemMeta.getLore(); return itemMeta.lore();
} }
// set the lore based on the origin // set the lore based on the origin
@@ -112,12 +113,12 @@ public class ItemLore {
if (dateCreatedLore == null) { if (dateCreatedLore == null) {
toolStats.logger.warning("messages.looted.looted-on is not set in your config!"); toolStats.logger.warning("messages.looted.looted-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
if (itemOwnerLore == null) { if (itemOwnerLore == null) {
toolStats.logger.warning("messages.looted.looted-by is not set in your config!"); toolStats.logger.warning("messages.looted.looted-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
break; break;
} }
@@ -128,12 +129,12 @@ public class ItemLore {
if (dateCreatedLore == null) { if (dateCreatedLore == null) {
toolStats.logger.warning("messages.traded.traded-on is not set in your config!"); toolStats.logger.warning("messages.traded.traded-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
if (itemOwnerLore == null) { if (itemOwnerLore == null) {
toolStats.logger.warning("messages.traded.traded-by is not set in your config!"); toolStats.logger.warning("messages.traded.traded-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
break; break;
} }
@@ -144,12 +145,12 @@ public class ItemLore {
if (dateCreatedLore == null) { if (dateCreatedLore == null) {
toolStats.logger.warning("messages.looted.found-on is not set in your config!"); toolStats.logger.warning("messages.looted.found-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
if (itemOwnerLore == null) { if (itemOwnerLore == null) {
toolStats.logger.warning("messages.looted.found-by is not set in your config!"); toolStats.logger.warning("messages.looted.found-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
break; break;
} }
@@ -160,12 +161,12 @@ public class ItemLore {
if (dateCreatedLore == null) { if (dateCreatedLore == null) {
toolStats.logger.warning("messages.fished.caught-on is not set in your config!"); toolStats.logger.warning("messages.fished.caught-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
if (itemOwnerLore == null) { if (itemOwnerLore == null) {
toolStats.logger.warning("messages.fished.caught-by is not set in your config!"); toolStats.logger.warning("messages.fished.caught-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
break; break;
} }
@@ -176,31 +177,31 @@ public class ItemLore {
if (dateCreatedLore == null) { if (dateCreatedLore == null) {
toolStats.logger.warning("messages.spawned-in.spawned-on is not set in your config!"); toolStats.logger.warning("messages.spawned-in.spawned-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
if (itemOwnerLore == null) { if (itemOwnerLore == null) {
toolStats.logger.warning("messages.spawned-in.spawned-by is not set in your config!"); toolStats.logger.warning("messages.spawned-in.spawned-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item."); toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore(); return itemMeta.lore();
} }
break; break;
} }
default: { default: {
toolStats.logger.warning("Origin " + origin + " was found. Data was modified OR something REALLY broke."); toolStats.logger.warning("Origin " + origin + " was found. Data was modified OR something REALLY broke.");
toolStats.logger.warning(itemMeta.getAsString()); toolStats.logger.warning(itemMeta.getAsString());
return itemMeta.getLore(); return itemMeta.lore();
} }
} }
List<String> newLore; List<Component> newLore;
if (itemMeta.hasLore()) { if (itemMeta.hasLore()) {
newLore = itemMeta.getLore(); newLore = itemMeta.lore();
} else { } else {
newLore = new ArrayList<>(); newLore = new ArrayList<>();
} }
newLore.add(dateCreatedLore.replace("{date}", formattedDate)); newLore.add(dateCreatedLore);
newLore.add(itemOwnerLore.replace("{player}", playerName)); newLore.add(itemOwnerLore);
return newLore; return newLore;
} }
} }

View File

@@ -15,23 +15,6 @@
* along with ToolStats. If not, see <https://www.gnu.org/licenses/>. * along with ToolStats. If not, see <https://www.gnu.org/licenses/>.
*/ */
/*
* 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; package lol.hyper.toolstats.tools;
import org.bukkit.persistence.PersistentDataAdapterContext; import org.bukkit.persistence.PersistentDataAdapterContext;

View File

@@ -18,7 +18,9 @@
package lol.hyper.toolstats.tools.config; package lol.hyper.toolstats.tools.config;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import org.bukkit.ChatColor; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Material; import org.bukkit.Material;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@@ -70,46 +72,21 @@ public class ConfigTools {
itemType = itemName.substring(itemName.indexOf('_') + 1); itemType = itemName.substring(itemName.indexOf('_') + 1);
} }
switch (itemType) { return switch (itemType) {
case "pickaxe": { case "pickaxe" -> toolStats.config.getBoolean("enabled." + configName + ".pickaxe");
return toolStats.config.getBoolean("enabled." + configName + ".pickaxe"); case "sword" -> toolStats.config.getBoolean("enabled." + configName + ".sword");
} case "shovel" -> toolStats.config.getBoolean("enabled." + configName + ".shovel");
case "sword": { case "axe" -> toolStats.config.getBoolean("enabled." + configName + ".axe");
return toolStats.config.getBoolean("enabled." + configName + ".sword"); case "hoe" -> toolStats.config.getBoolean("enabled." + configName + ".hoe");
} case "shears" -> toolStats.config.getBoolean("enabled." + configName + ".shears");
case "shovel": { case "crossbow", "bow" -> toolStats.config.getBoolean("enabled." + configName + ".bow");
return toolStats.config.getBoolean("enabled." + configName + ".shovel"); case "trident" -> toolStats.config.getBoolean("enabled." + configName + ".trident");
} case "fishing-rod" -> toolStats.config.getBoolean("enabled." + configName + ".fishing-rod");
case "axe": { case "mace" -> toolStats.config.getBoolean("enabled." + configName + ".mace");
return toolStats.config.getBoolean("enabled." + configName + ".axe"); case "helmet", "chestplate", "leggings", "boots" ->
} toolStats.config.getBoolean("enabled." + configName + ".armor");
case "hoe": { default -> false;
return toolStats.config.getBoolean("enabled." + configName + ".hoe"); };
}
case "shears": {
return toolStats.config.getBoolean("enabled." + configName + ".shears");
}
case "crossbow":
case "bow": {
return toolStats.config.getBoolean("enabled." + configName + ".bow");
}
case "trident": {
return toolStats.config.getBoolean("enabled." + configName + ".trident");
}
case "fishing-rod": {
return toolStats.config.getBoolean("enabled." + configName + ".fishing-rod");
}
case "mace": {
return toolStats.config.getBoolean("enabled." + configName + ".mace");
}
case "helmet":
case "chestplate":
case "leggings":
case "boots": {
return toolStats.config.getBoolean("enabled." + configName + ".armor");
}
}
return false;
} }
/** /**
@@ -120,28 +97,37 @@ public class ConfigTools {
* @param value The value to set the placeholder. * @param value The value to set the placeholder.
* @return Formatted string, null if the configName doesn't exist. * @return Formatted string, null if the configName doesn't exist.
*/ */
public String formatLore(String configName, String placeHolder, Object value) { public Component formatLore(String configName, String placeHolder, Object value) {
String lore = toolStats.config.getString("messages." + configName); String lore = toolStats.config.getString("messages." + configName);
if (lore == null) { if (lore == null) {
toolStats.logger.warning("Unable to find config message for: messages." + configName);
return null; return null;
} }
// if the config message is empty, don't send it
if (lore.isEmpty()) {
return null;
}
// the final component for this lore
Component component;
// set the placeholder to the value // set the placeholder to the value
lore = lore.replace(placeHolder, String.valueOf(value)); if (placeHolder != null && value != null) {
lore = lore.replace(placeHolder, String.valueOf(value));
}
// if we match the old color codes, then format them as so
Matcher hexMatcher = CONFIG_HEX_PATTERN.matcher(lore); Matcher hexMatcher = CONFIG_HEX_PATTERN.matcher(lore);
while (hexMatcher.find()) {
String hexCode = hexMatcher.group(1);
lore = lore.replaceAll(hexMatcher.group(), net.md_5.bungee.api.ChatColor.of("#" + hexCode).toString());
}
Matcher colorMatcher = COLOR_CODES.matcher(lore); Matcher colorMatcher = COLOR_CODES.matcher(lore);
while (colorMatcher.find()) { if (hexMatcher.find() || colorMatcher.find()) {
String colorCode = colorMatcher.group(1); component = LegacyComponentSerializer.legacyAmpersand().deserialize(lore);
lore = lore.replaceAll("&" + colorCode, ChatColor.getByChar(colorCode).toString()); } else {
// otherwise format them normally
component = Component.text(lore);
} }
return ChatColor.translateAlternateColorCodes('§', lore); return component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE);
} }
/** /**

View File

@@ -15,23 +15,6 @@
* along with ToolStats. If not, see <https://www.gnu.org/licenses/>. * along with ToolStats. If not, see <https://www.gnu.org/licenses/>.
*/ */
/*
* 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.config; package lol.hyper.toolstats.tools.config;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;

View File

@@ -18,7 +18,6 @@
package lol.hyper.toolstats.tools.config.versions; package lol.hyper.toolstats.tools.config.versions;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import org.bukkit.configuration.ConfigurationSection;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;

View File

@@ -117,11 +117,6 @@ messages:
damage-taken: "&7Damage taken: &8{damage}" damage-taken: "&7Damage taken: &8{damage}"
arrows-shot: "&7Arrows shot: &8{arrows}" arrows-shot: "&7Arrows shot: &8{arrows}"
flight-time: "&7Flight time: &8{time}" flight-time: "&7Flight time: &8{time}"
# Display this message if the player shift click trades/crafts items. It's not really easy to get every single item
# that is crafted. The tag will only be added to the first item. If you don't want this message, simply replace them both with ""
shift-click-warning:
crafting: "&cCrafting items via shift clicking does not fully apply tags to each item. This is a limitation with the Bukkit API."
trading: "&cTrading items via shift clicking does not fully apply tags to each item. This is a limitation with the Bukkit API."
# Set display name for mobs. See: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html # Set display name for mobs. See: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html
mobs: mobs:
ZOMBIE: "Zombie" ZOMBIE: "Zombie"
@@ -144,4 +139,4 @@ number-formats:
# This has no use currently, but can be used for future features for dupe detection. # This has no use currently, but can be used for future features for dupe detection.
generate-hash-for-items: true generate-hash-for-items: true
config-version: 7 config-version: 8

View File

@@ -1,9 +1,10 @@
name: ToolStats name: ToolStats
version: '${project.version}' version: '${project.version}'
main: lol.hyper.toolstats.ToolStats main: lol.hyper.toolstats.ToolStats
api-version: 1.15 api-version: 1.21
author: hyperdefined author: hyperdefined
description: Track various tool stats! description: Track various tool stats!
website: https://github.com/hyperdefined/ToolStats
folia-supported: true folia-supported: true
commands: commands:
toolstats: toolstats: