Compare commits

...

9 Commits

Author SHA1 Message Date
dependabot[bot]
2df9ecb4e5 Bump gradle-wrapper from 9.4.1 to 9.5.0
Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.4.1 to 9.5.0.
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](https://github.com/gradle/gradle/compare/v9.4.1...v9.5.0)

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-29 11:14:24 +00:00
hyperdefined
d1c5cd043b Merge pull request #123 from PurpleGale/item-model-support
Add item_model data component support for tokens
2026-04-24 18:24:12 -04:00
PurpleGale
70caa9e145 Add item_model data component support for tokens 2026-04-24 03:57:05 +03:00
hyperdefined
7b10ed61ae update README.md 2026-04-16 18:02:44 -04:00
hyperdefined
a881f60ed8 ok git just forget this file 2026-04-09 19:06:45 -04:00
hyperdefined
bdef9453c7 2.0.4 2026-04-09 19:06:22 -04:00
hyperdefined
11d6a5bf91 add new stuff to readme 2026-04-06 14:27:57 -04:00
hyperdefined
df4fadb1f0 remove dupe comment 2026-04-06 12:20:09 -04:00
hyperdefined
c5deb0f7fd config updater 17 2026-04-06 12:19:11 -04:00
15 changed files with 485 additions and 64 deletions

View File

@@ -10,11 +10,12 @@
<a href="https://patreon.com/hyperdefined"><img alt="patreon-singular" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/donate/patreon-singular_vector.svg"></a> <a href="https://patreon.com/hyperdefined"><img alt="patreon-singular" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/donate/patreon-singular_vector.svg"></a>
</p> </p>
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 either track all statistics by default, or a use a token system to add statistics to tool/armor. You can configure how each statistic is shown on the item, or disable it! ToolStats is a Paper plugin that displays various stats about tools. This plugin is inspired off of [GearStats](https://www.spigotmc.org/resources/gearstats.12960/). You can either track all statistics by default, or a use a token system to add statistics to tool/armor. You can configure how each statistic is shown on the item, or disable it!
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 harvested (hoes).
* Player/mob kills (swords, axes, tridents, bows/crossbows, mace). * Player/mob kills (swords, axes, tridents, bows/crossbows, mace).
* Ownership of items when crafted, looted (from chests/vaults/barrels), traded, spawned via creative, and caught from fishing. * Ownership of items when crafted, looted (from chests/vaults/barrels), traded, spawned via creative, and caught from fishing.
* Armor damage taken (shields too). * Armor damage taken (shields too).
@@ -25,25 +26,39 @@ Here is everything it tracks:
* Flight time with elytras. * Flight time with elytras.
* Critical strikes for melee weapons. * Critical strikes for melee weapons.
* Times trident thrown. * Times trident thrown.
* Logs stripped.
The best part is, this data is stored on the item itself. The best part is, this data is stored on the item itself.
If item lore is ever incorrect/missing, you can run `/toolstats reset`. This command fixes the lore on whatever item you are holding. This plugin also has compatibility for:
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image.png) * [RoseStacker](https://modrinth.com/plugin/rosestacker)
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image2.png)
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image3.png) You can see some of the stats below as examples:
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image4.png)
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image5.png) | Crafted Origin | Player/Mob Kills | Fish Caught |
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image6.png) |---|---|---|
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image7.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image2.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image3.png) |
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image8.png)
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image9.png) | Sheep Sheared | Dropped By | Damage Taken |
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image10.png) |---|---|---|
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image11.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image4.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image5.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image6.png) |
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image13.png)
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image14.png) | Mob Kills | Elytra | Looted Origin |
![Image](https://docs.hyper.lol/plugins/toolstats/assets/image12.png) |---|---|---|
| ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image7.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image8.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image9.png) |
| Traded Origin | Spawned Origin | Raw NBT Data |
|---|---|---|
| ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image10.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image11.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image12.png) |
| Crops Harvested | Flight Time | Arrows Shot |
|---|---|---|
| ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image13.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image14.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image15.png) |
| Critical Strikes | Trident Throws | Logs Stripped |
|---|---|---|
| ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image16.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image17.png) | ![Image](https://docs.hyper.lol/plugins/toolstats/assets/image18.png) |
## Documentation ## Documentation
Visit the [wiki](https://docs.hyper.lol/plugins/toolstats/about/) for help. Visit the [wiki](https://docs.hyper.lol/plugins/toolstats/about/) for help.

View File

@@ -20,7 +20,7 @@ dependencies {
} }
group = "lol.hyper" group = "lol.hyper"
version = "2.0.3" version = "2.0.4"
description = "ToolStats" description = "ToolStats"
java.sourceCompatibility = JavaVersion.VERSION_25 java.sourceCompatibility = JavaVersion.VERSION_25

Binary file not shown.

View File

@@ -1,7 +1,9 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
networkTimeout=10000 networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

2
gradlew vendored
View File

@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.

31
gradlew.bat vendored
View File

@@ -23,8 +23,8 @@
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables, and ensure extensions are enabled
if "%OS%"=="Windows_NT" setlocal setlocal EnableExtensions
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@@ -51,7 +51,7 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2 echo location of your Java installation. 1>&2
goto fail "%COMSPEC%" /c exit 1
:findJavaFromJavaHome :findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
@@ -65,7 +65,7 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2 echo location of your Java installation. 1>&2
goto fail "%COMSPEC%" /c exit 1
:execute :execute
@rem Setup the command line @rem Setup the command line
@@ -73,21 +73,10 @@ goto fail
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* @rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:end :exitWithErrorLevel
@rem End local scope for the variables with windows NT shell @rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
if %ERRORLEVEL% equ 0 goto mainEnd "%COMSPEC%" /c exit %ERRORLEVEL%
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -37,7 +37,7 @@ import java.io.File;
public final class ToolStats extends JavaPlugin { public final class ToolStats extends JavaPlugin {
public final int CONFIG_VERSION = 16; public final int CONFIG_VERSION = 18;
public final ComponentLogger logger = this.getComponentLogger(); public final ComponentLogger logger = this.getComponentLogger();
public final File configFile = new File(this.getDataFolder(), "config.yml"); public final File configFile = new File(this.getDataFolder(), "config.yml");
public boolean tokens = false; public boolean tokens = false;

View File

@@ -29,6 +29,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
@@ -227,6 +228,29 @@ public class CommandToolStats implements BasicCommand {
} }
return; return;
} }
case "add": {
if (!sender.hasPermission("toolstats.add")) {
sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
return;
}
if (sender instanceof ConsoleCommandSender) {
sender.sendMessage(Component.text("You must be a player for this command.", NamedTextColor.RED));
return;
}
// Make sure /toolstats add <stat> is present
if (args.length < 2) {
sender.sendMessage(Component.text("Invalid syntax. Usage: /toolstats add <stat>", NamedTextColor.RED));
return;
}
//Make sure they typed in a valid stat
String stat = args[1];
if (!toolStats.tokenData.getTokenTypes().contains(stat)) {
sender.sendMessage(Component.text("That is not a valid stat.", NamedTextColor.RED));
return;
}
addStat(stat, (Player) sender);
return;
}
default: { default: {
sender.sendMessage(Component.text("Invalid sub-command.", NamedTextColor.RED)); sender.sendMessage(Component.text("Invalid sub-command.", NamedTextColor.RED));
} }
@@ -449,6 +473,169 @@ public class CommandToolStats implements BasicCommand {
target.getInventory().addItem(token); target.getInventory().addItem(token);
} }
/**
* Add a stat to an item, setting it to zero.
* @param stat The stat to add.
* @param player The player running the command.
*/
private void addStat(String stat, Player player) {
PlayerInventory playerInventory = player.getInventory();
ItemStack heldItem = playerInventory.getItemInMainHand();
ItemMeta heldItemMeta = heldItem.getItemMeta();
if (heldItemMeta == null) {
return;
}
if (toolStats.itemChecker.checkTokens(heldItemMeta.getPersistentDataContainer(), stat)) {
player.sendMessage(Component.text("This item already has this stat.", NamedTextColor.RED));
return;
}
if (stat.equalsIgnoreCase("remove") || stat.equalsIgnoreCase("reset")) {
player.sendMessage(Component.text("That is not a valid stat.", NamedTextColor.RED));
return;
}
ItemStack newItem = toolStats.itemChecker.addToken(heldItem, stat);
switch (stat) {
case "crops-mined": {
if (toolStats.config.getBoolean("enabled.crops-harvested")) {
newItem.setItemMeta(toolStats.itemLore.updateCropsMined(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "blocks-mined": {
if (toolStats.configTools.checkConfig(newItem.getType(), "blocks-mined")) {
newItem.setItemMeta(toolStats.itemLore.updateBlocksMined(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "damage-taken": {
if (toolStats.config.getBoolean("enabled.armor-damage")) {
newItem.setItemMeta(toolStats.itemLore.updateArmorDamage(newItem, 0.0, false));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "damage-done": {
if (toolStats.configTools.checkConfig(newItem.getType(), "damage-done")) {
newItem.setItemMeta(toolStats.itemLore.updateWeaponDamage(newItem, 0.0, false));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "mob-kills": {
if (toolStats.configTools.checkConfig(newItem.getType(), "mob-kills")) {
newItem.setItemMeta(toolStats.itemLore.updateMobKills(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "player-kills": {
if (toolStats.configTools.checkConfig(newItem.getType(), "player-kills")) {
newItem.setItemMeta(toolStats.itemLore.updatePlayerKills(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "arrows-shot": {
if (toolStats.config.getBoolean("enabled.arrows-shot")) {
newItem.setItemMeta(toolStats.itemLore.updateArrowsShot(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "sheep-sheared": {
if (toolStats.config.getBoolean("enabled.sheep-sheared")) {
newItem.setItemMeta(toolStats.itemLore.updateSheepSheared(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "flight-time": {
if (toolStats.config.getBoolean("enabled.flight-time")) {
newItem.setItemMeta(toolStats.itemLore.updateFlightTime(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "fish-caught": {
if (toolStats.config.getBoolean("enabled.fish-caught")) {
newItem.setItemMeta(toolStats.itemLore.updateFishCaught(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "wither-kills": {
if (toolStats.config.getBoolean("enabled.bosses-killed.wither")) {
newItem.setItemMeta(toolStats.itemLore.updateBossesKilled(newItem, 0, "wither"));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "enderdragon-kills": {
if (toolStats.config.getBoolean("enabled.bosses-killed.enderdragon")) {
newItem.setItemMeta(toolStats.itemLore.updateBossesKilled(newItem, 0, "enderdragon"));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "critical-strikes": {
if (toolStats.config.getBoolean("enabled.critical-strikes")) {
newItem.setItemMeta(toolStats.itemLore.updateCriticalStrikes(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "trident-throws": {
if (toolStats.config.getBoolean("enabled.trident-throws")) {
newItem.setItemMeta(toolStats.itemLore.updateTridentThrows(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
case "logs-stripped": {
if (toolStats.config.getBoolean("enabled.logs-stripped")) {
newItem.setItemMeta(toolStats.itemLore.updateLogsStripped(newItem, 0));
} else {
player.sendMessage(Component.text("This stat is disabled.", NamedTextColor.RED));
return;
}
break;
}
}
player.sendMessage(Component.text(stat + " has been added!", NamedTextColor.GREEN));
}
/** /**
* Handle edit subcommand. * Handle edit subcommand.
* *
@@ -969,6 +1156,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -997,6 +1185,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1025,6 +1214,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1053,6 +1243,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1081,6 +1272,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1109,6 +1301,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1137,6 +1330,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1166,6 +1360,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1194,6 +1389,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1222,6 +1418,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1250,6 +1447,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1278,6 +1476,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1306,6 +1505,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1334,6 +1534,7 @@ public class CommandToolStats implements BasicCommand {
editedItemMeta.lore(newLore); editedItemMeta.lore(newLore);
} else { } else {
player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED)); player.sendMessage(Component.text("This item does not have that stat.", NamedTextColor.RED));
return;
} }
break; break;
} }
@@ -1347,6 +1548,8 @@ public class CommandToolStats implements BasicCommand {
player.sendMessage(Component.text("Removed stat " + stat + " for held item!", NamedTextColor.GREEN)); player.sendMessage(Component.text("Removed stat " + stat + " for held item!", NamedTextColor.GREEN));
} }
@Override @Override
public @NonNull Collection<String> suggest(@NonNull CommandSourceStack source, String[] args) { public @NonNull Collection<String> suggest(@NonNull CommandSourceStack source, String[] args) {
CommandSender sender = source.getSender(); CommandSender sender = source.getSender();
@@ -1371,6 +1574,9 @@ public class CommandToolStats implements BasicCommand {
if (sender.hasPermission("toolstats.purge")) { if (sender.hasPermission("toolstats.purge")) {
suggestions.add("purge"); suggestions.add("purge");
} }
if (sender.hasPermission("toolstats.add")) {
suggestions.add("add");
}
return suggestions; return suggestions;
} }
@@ -1392,6 +1598,15 @@ public class CommandToolStats implements BasicCommand {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
// suggest keys for add
if (args.length == 2 && args[0].equalsIgnoreCase("add") && sender.hasPermission("toolstats.add")) {
// yes I am lazy
return toolStats.tokenData.getTokenTypes().stream()
.filter(s -> !s.equals("remove") && !s.equals("reset"))
.map(s -> s.equals("crops-mined") ? "crops-harvested" : s)
.collect(Collectors.toList());
}
// suggest keys for remove // suggest keys for remove
if (args.length == 2 && args[0].equalsIgnoreCase("remove") && sender.hasPermission("toolstats.remove")) { if (args.length == 2 && args[0].equalsIgnoreCase("remove") && sender.hasPermission("toolstats.remove")) {
// yes I am lazy // yes I am lazy

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.support.rosestacker; package lol.hyper.toolstats.support.rosestacker;
import dev.rosewood.rosestacker.api.RoseStackerAPI; import dev.rosewood.rosestacker.api.RoseStackerAPI;
@@ -86,10 +69,6 @@ public class RoseStacker {
difference = before; difference = before;
} }
toolStats.logger.info("before: {}", before);
toolStats.logger.info("after: {}", after);
toolStats.logger.info("difference: {}", difference);
callback.accept(difference); callback.accept(difference);
}, 1); }, 1);
} }

View File

@@ -238,6 +238,21 @@ public class TokenData {
} }
} }
// set the item model
if (tokenConfig.getBoolean("item-model.enabled")) {
String itemModelValue = tokenConfig.getString("item-model.value");
if (itemModelValue == null || itemModelValue.isEmpty()) {
toolStats.logger.info("Could not find item model value for token {}", tokenType);
return null;
}
NamespacedKey itemModelKey = NamespacedKey.fromString(itemModelValue);
if (itemModelKey == null) {
toolStats.logger.info("{} is not a valid namespaced key!", itemModelValue);
return null;
}
token.setData(DataComponentTypes.ITEM_MODEL, itemModelKey);
}
return token; return token;
} }

View File

@@ -43,6 +43,8 @@ public class ConfigUpdater {
case 13 -> new Version14(toolStats).update(); // 13 to 14 case 13 -> new Version14(toolStats).update(); // 13 to 14
case 14 -> new Version15(toolStats).update(); // 14 to 15 case 14 -> new Version15(toolStats).update(); // 14 to 15
case 15 -> new Version16(toolStats).update(); // 15 to 16 case 15 -> new Version16(toolStats).update(); // 15 to 16
case 16 -> new Version17(toolStats).update(); // 16 to 17
case 17 -> new Version18(toolStats).update(); // 17 to 18
} }
} }
} }

View File

@@ -0,0 +1,82 @@
/*
* 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.versions;
import lol.hyper.toolstats.ToolStats;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class Version17 {
private final ToolStats toolStats;
/**
* Used for updating from version 16 to 17.
*
* @param toolStats ToolStats instance.
*/
public Version17(ToolStats toolStats) {
this.toolStats = toolStats;
}
/**
* Perform the config update.
*/
public void update() {
// save the old config first
try {
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config-16.yml");
} catch (IOException exception) {
toolStats.logger.error("Unable to save config-16.yml!", exception);
}
toolStats.logger.info("Updating config.yml to version 17.");
toolStats.config.set("config-version", 17);
toolStats.logger.info("Adding new token to config: logs-stripped");
toolStats.config.set("tokens.data.logs-stripped.title", "&7ToolStats: &8Logs Stripped Token");
toolStats.config.set("tokens.data.logs-stripped.lore", List.of(
"&8Combine with an axe in an anvil to track logs stripped.",
"&8Uses &7{levels} &8level."
));
toolStats.config.set("tokens.data.logs-stripped.levels", 1);
toolStats.config.set("tokens.data.logs-stripped.material", "PAPER");
toolStats.config.set("tokens.data.logs-stripped.custom-model-data.enabled", false);
toolStats.config.set("tokens.data.logs-stripped.custom-model-data.type", "float");
toolStats.config.set("tokens.data.logs-stripped.custom-model-data.value", 1001);
toolStats.logger.info("Adding enabled.logs-stripped");
toolStats.config.set("enabled.logs-stripped", true);
toolStats.logger.info("Adding messages.logs-stripped");
toolStats.config.set("messages.logs-stripped", "&7Logs stripped: &8{logs}");
// save the config and reload it
try {
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config.yml");
} catch (IOException exception) {
toolStats.logger.error("Unable to save config.yml!", exception);
}
toolStats.loadConfig();
toolStats.logger.info("Config has been updated to version 17. A copy of version 16 has been saved as config-16.yml");
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.versions;
import lol.hyper.toolstats.ToolStats;
import java.io.File;
import java.io.IOException;
public class Version18 {
private final ToolStats toolStats;
/**
* Used for updating from version 17 to 18.
*
* @param toolStats ToolStats instance.
*/
public Version18(ToolStats toolStats) {
this.toolStats = toolStats;
}
/**
* Perform the config update.
*/
public void update() {
// save the old config first
try {
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config-17.yml");
} catch (IOException exception) {
toolStats.logger.error("Unable to save config-17.yml!", exception);
}
toolStats.logger.info("Updating config.yml to version 18.");
toolStats.config.set("config-version", 18);
for (String key : toolStats.config.getConfigurationSection("tokens.data").getKeys(false)) {
toolStats.logger.info("Adding tokens.data.{}.item-model.enabled", key);
toolStats.config.set("tokens.data." + key + ".item-model.enabled", false);
toolStats.logger.info("Adding tokens.data.{}.item-model.value", key);
toolStats.config.set("tokens.data." + key + ".item-model.value", "minecraft:paper");
}
// save the config and reload it
try {
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config.yml");
} catch (IOException exception) {
toolStats.logger.error("Unable to save config.yml!", exception);
}
toolStats.loadConfig();
toolStats.logger.info("Config has been updated to version 18. A copy of version 17 has been saved as config-17.yml");
}
}

View File

@@ -15,6 +15,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
mob-kills: mob-kills:
title: "&7ToolStats: &8Mob Kills Token" title: "&7ToolStats: &8Mob Kills Token"
lore: lore:
@@ -26,6 +29,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
blocks-mined: blocks-mined:
title: "&7ToolStats: &8Blocks Mined Token" title: "&7ToolStats: &8Blocks Mined Token"
lore: lore:
@@ -37,6 +43,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
crops-mined: crops-mined:
title: "&7ToolStats: &8Crops Mined Token" title: "&7ToolStats: &8Crops Mined Token"
lore: lore:
@@ -48,6 +57,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
fish-caught: fish-caught:
title: "&7ToolStats: &8Fish Caught Token" title: "&7ToolStats: &8Fish Caught Token"
lore: lore:
@@ -59,6 +71,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
sheep-sheared: sheep-sheared:
title: "&7ToolStats: &8Sheep Sheared Token" title: "&7ToolStats: &8Sheep Sheared Token"
lore: lore:
@@ -70,6 +85,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
damage-taken: damage-taken:
title: "&7ToolStats: &8Damage Taken Token" title: "&7ToolStats: &8Damage Taken Token"
lore: lore:
@@ -81,6 +99,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
damage-done: damage-done:
title: "&7ToolStats: &8Damage Done Token" title: "&7ToolStats: &8Damage Done Token"
lore: lore:
@@ -92,6 +113,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
arrows-shot: arrows-shot:
title: "&7ToolStats: &8Arrows Shot Token" title: "&7ToolStats: &8Arrows Shot Token"
lore: lore:
@@ -103,6 +127,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
flight-time: flight-time:
title: "&7ToolStats: &8Flight Time Token" title: "&7ToolStats: &8Flight Time Token"
lore: lore:
@@ -114,6 +141,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
reset: reset:
title: "&7ToolStats: &8Reset Token" title: "&7ToolStats: &8Reset Token"
lore: lore:
@@ -125,6 +155,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
remove: remove:
title: "&7ToolStats: &8Remove Token" title: "&7ToolStats: &8Remove Token"
lore: lore:
@@ -136,6 +169,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
wither-kills: wither-kills:
title: "&7ToolStats: &8Wither Kills Token" title: "&7ToolStats: &8Wither Kills Token"
lore: lore:
@@ -147,6 +183,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
enderdragon-kills: enderdragon-kills:
title: "&7ToolStats: &8Ender Dragon Kills Token" title: "&7ToolStats: &8Ender Dragon Kills Token"
lore: lore:
@@ -158,6 +197,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
critical-strikes: critical-strikes:
title: "&7ToolStats: &8Critical Strikes Token" title: "&7ToolStats: &8Critical Strikes Token"
lore: lore:
@@ -169,6 +211,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
trident-throws: trident-throws:
title: "&7ToolStats: &8Trident Throws Token" title: "&7ToolStats: &8Trident Throws Token"
lore: lore:
@@ -180,6 +225,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
logs-stripped: logs-stripped:
title: "&7ToolStats: &8Logs Stripped Token" title: "&7ToolStats: &8Logs Stripped Token"
lore: lore:
@@ -191,6 +239,9 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
item-model:
enabled: false
value: "minecraft:paper"
enabled: enabled:
# Will show "Crafted by <player>" # Will show "Crafted by <player>"
@@ -437,4 +488,4 @@ world-limit:
- world_1 - world_1
- world_2 - world_2
config-version: 16 config-version: 18

View File

@@ -30,6 +30,9 @@ permissions:
toolstats.remove: toolstats.remove:
description: Allows the usage of /toolstats remove. description: Allows the usage of /toolstats remove.
default: op default: op
toolstats.add:
description: Allows the usage of /toolstats add.
default: op
dependencies: dependencies:
server: server: