Compare commits

...

18 Commits
1.8.4 ... 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
20 changed files with 184 additions and 147 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

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

View File

@@ -1,14 +1,12 @@
<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.21--1.21.4-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 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. 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.
@@ -22,6 +20,7 @@ Here is everything it tracks:
* 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).

View File

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

View File

@@ -27,8 +27,6 @@ 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.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
@@ -205,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!");

View File

@@ -17,7 +17,6 @@
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 net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -35,11 +34,9 @@ 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;
import java.util.function.Consumer;
public class BlocksMined implements Listener { public class BlocksMined implements Listener {

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 net.kyori.adventure.text.Component; 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,7 +29,9 @@ 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;
@@ -35,6 +39,7 @@ import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
public class CraftItem implements Listener { public class CraftItem implements Listener {
@@ -53,23 +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()) {
Component component = toolStats.configTools.formatLore("shift-click-warning", null, null); // store the player inventory before they craft the items
event.getWhoClicked().sendMessage(component); ItemStack[] beforeCraft = player.getInventory().getContents();
// run a tick after to see the changes
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 // the player did not shift click
ItemStack newItem = addLore(itemStack, player); ItemStack newItem = addLore(craftedItem, player);
if (newItem != null) { if (newItem != null) {
// set the result // set the result
event.setCurrentItem(newItem); event.setCurrentItem(newItem);

View File

@@ -107,20 +107,16 @@ public class EntityDamage implements Listener {
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

View File

@@ -17,7 +17,6 @@
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.Bukkit; import org.bukkit.Bukkit;
@@ -30,10 +29,8 @@ 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;
import java.util.function.Consumer;
public class InventoryOpen implements Listener { public class InventoryOpen implements Listener {

View File

@@ -17,7 +17,6 @@
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 org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@@ -32,11 +31,9 @@ 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;
import java.util.function.Consumer;
public class PlayerInteract implements Listener { public class PlayerInteract implements Listener {

View File

@@ -17,7 +17,6 @@
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.entity.Player; import org.bukkit.entity.Player;
@@ -29,10 +28,8 @@ 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;
import java.util.function.Consumer;
public class PlayerJoin implements Listener { public class PlayerJoin implements Listener {

View File

@@ -59,9 +59,9 @@ public class SheepShear implements Listener {
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;
} }
@@ -71,27 +71,27 @@ public class SheepShear implements Listener {
} }
// 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;
} }
/** /**

View File

@@ -56,10 +56,8 @@ public class ShootBow implements Listener {
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) {

View File

@@ -20,8 +20,8 @@ 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 net.kyori.adventure.text.Component;
import org.bukkit.ChatColor;
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;
@@ -59,27 +59,55 @@ public class VillagerTrade implements Listener {
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);
} }
} }

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

@@ -50,10 +50,10 @@ public class ItemLore {
// 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++) {
Component line = itemLore.get(x); String line = PlainTextComponentSerializer.plainText().serialize(itemLore.get(x));
// find the old line to update, keeping index // find the old line to update, keeping index
// this means we update this line only! // this means we update this line only!
if (line.equals(oldLine)) { if (line.equals(PlainTextComponentSerializer.plainText().serialize(oldLine))) {
itemLore.set(x, newLine); itemLore.set(x, newLine);
return itemLore; return itemLore;
} }

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

@@ -100,6 +100,12 @@ public class ConfigTools {
public Component 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;
}
// if the config message is empty, don't send it
if (lore.isEmpty()) {
return null; return null;
} }
@@ -107,7 +113,9 @@ public class ConfigTools {
Component component; 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 // 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);

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

@@ -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