improve compatibility with ValhallaMMO

fuck this plugin holy fuck
This commit is contained in:
hyperdefined
2026-01-20 20:14:18 -05:00
parent 6a994e4a82
commit e537286785
5 changed files with 242 additions and 134 deletions

View File

@@ -72,6 +72,7 @@ public final class ToolStats extends JavaPlugin {
public TextUtils textUtils; public TextUtils textUtils;
public ProjectileShoot projectileShoot; public ProjectileShoot projectileShoot;
public ToolStatsKeys toolStatsKeys; public ToolStatsKeys toolStatsKeys;
public InventoryClose inventoryClose;
@Override @Override
public void onEnable() { public void onEnable() {
@@ -124,6 +125,7 @@ public final class ToolStats extends JavaPlugin {
prepareCraft = new PrepareCraft(this); prepareCraft = new PrepareCraft(this);
blockDispenseEvent = new BlockDispenseEvent(this); blockDispenseEvent = new BlockDispenseEvent(this);
projectileShoot = new ProjectileShoot(this); projectileShoot = new ProjectileShoot(this);
inventoryClose = new InventoryClose(this);
Bukkit.getServer().getPluginManager().registerEvents(blockBreak, this); Bukkit.getServer().getPluginManager().registerEvents(blockBreak, this);
Bukkit.getServer().getPluginManager().registerEvents(chunkPopulate, this); Bukkit.getServer().getPluginManager().registerEvents(chunkPopulate, this);
@@ -145,6 +147,7 @@ public final class ToolStats extends JavaPlugin {
Bukkit.getServer().getPluginManager().registerEvents(prepareCraft, this); Bukkit.getServer().getPluginManager().registerEvents(prepareCraft, this);
Bukkit.getServer().getPluginManager().registerEvents(blockDispenseEvent, this); Bukkit.getServer().getPluginManager().registerEvents(blockDispenseEvent, this);
Bukkit.getServer().getPluginManager().registerEvents(projectileShoot, this); Bukkit.getServer().getPluginManager().registerEvents(projectileShoot, this);
Bukkit.getServer().getPluginManager().registerEvents(inventoryClose, this);
this.getCommand("toolstats").setExecutor(commandToolStats); this.getCommand("toolstats").setExecutor(commandToolStats);

View File

@@ -18,9 +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.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable; import org.bukkit.block.data.Ageable;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -55,11 +53,6 @@ public class BlockBreak implements Listener {
ItemStack heldItem = inventory.getItemInMainHand(); ItemStack heldItem = inventory.getItemInMainHand();
Block block = event.getBlock(); Block block = event.getBlock();
if (block.getType() == Material.CHEST) {
toolStats.playerInteract.openedChests.put(block, player);
Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> toolStats.playerInteract.openedChests.remove(block), 20);
}
// only check certain items // only check certain items
if (!toolStats.itemChecker.isMineTool(heldItem.getType())) { if (!toolStats.itemChecker.isMineTool(heldItem.getType())) {
return; return;

View File

@@ -17,32 +17,27 @@
package lol.hyper.toolstats.events; package lol.hyper.toolstats.events;
import lol.hyper.hyperlib.datatypes.UUIDDataType;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component; import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Chest; import org.bukkit.block.Container;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.StorageMinecart; import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.world.LootGenerateEvent; import org.bukkit.event.world.LootGenerateEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList; import java.util.HashMap;
import java.util.Date; import java.util.Map;
import java.util.List;
public class GenerateLoot implements Listener { public class GenerateLoot implements Listener {
private final ToolStats toolStats; private final ToolStats toolStats;
public Map<Inventory, Location> generatedInventory = new HashMap<>();
public GenerateLoot(ToolStats toolStats) { public GenerateLoot(ToolStats toolStats) {
this.toolStats = toolStats; this.toolStats = toolStats;
@@ -55,117 +50,34 @@ public class GenerateLoot implements Listener {
return; return;
} }
Location lootLocation = event.getLootContext().getLocation(); Location lootLocation = event.getLootContext().getLocation();
Chunk lootChunk = lootLocation.getChunk();
if (inventoryHolder instanceof Chest) { Bukkit.getRegionScheduler().runDelayed(toolStats, lootLocation.getWorld(), lootChunk.getX(), lootChunk.getZ(), scheduledTask -> {
Block openedChest = null; if (inventoryHolder instanceof Container) {
// look at the current list of opened chest and get the distance Block openedChest = null;
// between the LootContext location and chest location Location chestLocation = null;
// if the distance is less than 1, it's the same chest // look at the current list of opened chest and get the distance
for (Block chest : toolStats.playerInteract.openedChests.keySet()) { // between the LootContext location and chest location
Location chestLocation = chest.getLocation(); // if the distance is less than 1, it's the same chest
if (chest.getWorld() == lootLocation.getWorld()) { for (Block chest : toolStats.playerInteract.openedChests) {
double distance = lootLocation.distance(chestLocation); chestLocation = chest.getLocation();
if (distance <= 1.0) { if (chest.getWorld() == lootLocation.getWorld()) {
openedChest = chest; double distance = lootLocation.distance(chestLocation);
if (distance <= 1.0) {
openedChest = chest;
}
} }
} }
} // ignore if the chest is not in the same location
// ignore if the chest is not in the same location if (openedChest != null) {
if (openedChest == null) { generatedInventory.put(inventoryHolder.getInventory(), chestLocation);
return;
}
Player player = toolStats.playerInteract.openedChests.get(openedChest);
setLoot(event.getLoot(), player);
}
if (inventoryHolder instanceof StorageMinecart mineCart) {
if (toolStats.playerInteract.openedMineCarts.containsKey(mineCart)) {
Player player = toolStats.playerInteract.openedMineCarts.get(mineCart);
setLoot(event.getLoot(), player);
}
}
}
/**
* Adds lore to newly generated items.
*
* @param itemStack The item to add lore to.
* @param owner The player that found the item.
* @return The item with the lore.
*/
private ItemStack addLootedOrigin(ItemStack itemStack, Player owner) {
ItemStack newItem = itemStack.clone();
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return null;
}
long timeCreated = System.currentTimeMillis();
Date finalDate;
if (toolStats.config.getBoolean("normalize-time-creation")) {
finalDate = toolStats.numberFormat.normalizeTime(timeCreated);
timeCreated = finalDate.getTime();
}
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG) || container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
return null;
}
// get the current lore the item
List<Component> lore;
if (meta.hasLore()) {
lore = meta.lore();
} else {
lore = new ArrayList<>();
}
// if creation date is enabled, add it
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 2, newItem);
if (creationDate != null) {
container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 2);
lore.add(creationDate);
meta.lore(lore);
}
// if ownership is enabled, add it
Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 2, newItem);
if (itemOwner != null) {
container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 2);
lore.add(itemOwner);
meta.lore(lore);
}
// if hash is enabled, add it
if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated);
container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
}
newItem.setItemMeta(meta);
return newItem;
}
/**
* Add tags to the generated loot.
*
* @param loot The loot from the event.
* @param player The player triggering the event.
*/
private void setLoot(List<ItemStack> loot, Player player) {
for (int i = 0; i < loot.size(); i++) {
ItemStack itemStack = loot.get(i);
// ignore air
if (itemStack == null || itemStack.getType() == Material.AIR) {
continue;
}
if (toolStats.itemChecker.isValidItem(itemStack.getType())) {
ItemStack newItem = addLootedOrigin(itemStack, player);
if (newItem != null) {
loot.set(i, newItem);
} }
} }
} if (inventoryHolder instanceof StorageMinecart mineCart) {
if (toolStats.playerInteract.openedMineCarts.contains(mineCart)) {
Inventory mineCartInventory = mineCart.getInventory();
generatedInventory.put(mineCartInventory, mineCart.getLocation());
}
}
}, 5);
} }
} }

View File

@@ -0,0 +1,193 @@
/*
* 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.events;
import lol.hyper.hyperlib.datatypes.UUIDDataType;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.BlockState;
import org.bukkit.block.Container;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class InventoryClose implements Listener {
private final ToolStats toolStats;
public InventoryClose(ToolStats toolStats) {
this.toolStats = toolStats;
}
@EventHandler
public void onClose(InventoryCloseEvent event) {
if (toolStats.generateLoot.generatedInventory.isEmpty()) {
return;
}
Player player = (Player) event.getPlayer();
Inventory closedInventory = event.getInventory();
InventoryHolder holder = closedInventory.getHolder();
if (toolStats.generateLoot.generatedInventory.containsKey(closedInventory)) {
Location chestLocation = toolStats.generateLoot.generatedInventory.get(closedInventory);
toolStats.generateLoot.generatedInventory.remove(closedInventory);
player.getScheduler().runDelayed(toolStats, scheduledTask -> {
PlayerInventory playerInventory = player.getInventory();
for (int i = 0; i < playerInventory.getContents().length; i++) {
ItemStack item = playerInventory.getItem(i);
if (item == null) {
continue;
}
if (!toolStats.itemChecker.isValidItem(item.getType())) {
continue;
}
ItemStack newItem = addLootedOrigin(item, player);
if (newItem != null) {
playerInventory.setItem(i, newItem);
}
}
}, null, 1);
if (holder instanceof StorageMinecart mineCart) {
mineCart.getScheduler().runDelayed(toolStats, scheduledTask -> {
Inventory chestInventory = mineCart.getInventory();
for (int i = 0; i < chestInventory.getContents().length; i++) {
ItemStack item = chestInventory.getItem(i);
if (item == null) {
continue;
}
if (!toolStats.itemChecker.isValidItem(item.getType())) {
continue;
}
ItemStack newItem = addLootedOrigin(item, player);
if (newItem != null) {
chestInventory.setItem(i, newItem);
}
}
}, null, 1);
}
if (holder instanceof Container container) {
Chunk chestChunk = chestLocation.getChunk();
Bukkit.getRegionScheduler().runDelayed(toolStats, chestLocation.getWorld(), chestChunk.getX(), chestChunk.getZ(), scheduledTask -> {
BlockState blockState = chestLocation.getWorld().getBlockAt(chestLocation).getState();
if (blockState instanceof InventoryHolder chest) {
Inventory chestInventory = chest.getInventory();
for (int i = 0; i < chestInventory.getContents().length; i++) {
ItemStack item = chestInventory.getItem(i);
if (item == null) {
continue;
}
if (!toolStats.itemChecker.isValidItem(item.getType())) {
continue;
}
ItemStack newItem = addLootedOrigin(item, player);
if (newItem != null) {
chestInventory.setItem(i, newItem);
}
}
}
}, 1);
}
}
}
/**
* Adds lore to newly generated items.
*
* @param itemStack The item to add lore to.
* @param owner The player that found the item.
* @return The item with the lore.
*/
private ItemStack addLootedOrigin(ItemStack itemStack, Player owner) {
ItemStack newItem = itemStack.clone();
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return null;
}
long timeCreated = System.currentTimeMillis();
Date finalDate;
if (toolStats.config.getBoolean("normalize-time-creation")) {
finalDate = toolStats.numberFormat.normalizeTime(timeCreated);
timeCreated = finalDate.getTime();
}
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER) || container.has(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG) || container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
return null;
}
// get the current lore the item
List<Component> lore;
if (meta.hasLore()) {
lore = meta.lore();
} else {
lore = new ArrayList<>();
}
// if creation date is enabled, add it
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 2, newItem);
if (creationDate != null) {
container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 2);
lore.add(creationDate);
meta.lore(lore);
}
// if ownership is enabled, add it
Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 2, newItem);
if (itemOwner != null) {
container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 2);
lore.add(itemOwner);
meta.lore(lore);
}
// if hash is enabled, add it
if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated);
container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
}
newItem.setItemMeta(meta);
return newItem;
}
}

View File

@@ -31,17 +31,20 @@ 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.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
import java.util.HashMap; import java.util.ArrayList;
import java.util.Map; import java.util.List;
public class PlayerInteract implements Listener { public class PlayerInteract implements Listener {
private final ToolStats toolStats; private final ToolStats toolStats;
public final Map<Block, Player> openedChests = new HashMap<>(); public final List<Block> openedChests = new ArrayList<>();
public final Map<StorageMinecart, Player> openedMineCarts = new HashMap<>(); public final List<StorageMinecart> openedMineCarts = new ArrayList<>();
public final List<Inventory> chestInventories = new ArrayList<>();
public final List<Inventory> mineCartChestInventories = new ArrayList<>();
public PlayerInteract(ToolStats toolStats) { public PlayerInteract(ToolStats toolStats) {
this.toolStats = toolStats; this.toolStats = toolStats;
@@ -64,8 +67,10 @@ public class PlayerInteract implements Listener {
} }
// store when a player opens a chest // store when a player opens a chest
BlockState state = block.getState(); BlockState state = block.getState();
if (state instanceof InventoryHolder) { if (state instanceof InventoryHolder holder) {
openedChests.put(block, player); Inventory holderInventory = holder.getInventory();
openedChests.add(block);
chestInventories.add(holderInventory);
Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> openedChests.remove(block), 20); Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> openedChests.remove(block), 20);
} }
} }
@@ -80,7 +85,9 @@ public class PlayerInteract implements Listener {
// store when a player opens a minecart // store when a player opens a minecart
if (clicked.getType() == EntityType.CHEST_MINECART) { if (clicked.getType() == EntityType.CHEST_MINECART) {
StorageMinecart storageMinecart = (StorageMinecart) clicked; StorageMinecart storageMinecart = (StorageMinecart) clicked;
openedMineCarts.put(storageMinecart, player); Inventory mineCartInventory = storageMinecart.getInventory();
mineCartChestInventories.add(mineCartInventory);
openedMineCarts.add(storageMinecart);
Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> openedMineCarts.remove(storageMinecart), 20); Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> openedMineCarts.remove(storageMinecart), 20);
} }
} }