Compare commits

...

27 Commits

Author SHA1 Message Date
hyperdefined
7e9a62a8f1 fix OpenInv compatibility
closes #116
2026-03-04 18:15:07 -05:00
hyperdefined
bf4e2af631 fix pom for paper plugin 2026-03-04 17:47:57 -05:00
hyperdefined
870b086a94 migrate into paper plugin 2026-03-04 17:45:57 -05:00
hyperdefined
58042980eb Merge pull request #117 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.15.0
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.1 to 3.15.0
2026-02-02 16:33:04 -05:00
dependabot[bot]
1157a4312f Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.14.1 to 3.15.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.14.1...maven-compiler-plugin-3.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-02 12:16:23 +00:00
hyperdefined
5c4b212390 forgot to update 2026-01-26 16:33:30 -05:00
hyperdefined
e321e9066c omg???? 2026-01-26 16:31:24 -05:00
hyperdefined
a0b64e0499 handle edge case
player drops new item from a looted chest onto ground, add origin to it
2026-01-26 16:29:17 -05:00
hyperdefined
6204a3e22b properly handle breaking chest gen 2026-01-26 16:19:00 -05:00
hyperdefined
9e9482067d typo in updater 2026-01-26 15:36:32 -05:00
hyperdefined
58a74a0cdd properly do black/whitelist feature based on feedback 2026-01-26 15:23:20 -05:00
hyperdefined
9755ac2035 check all inventories 2026-01-26 13:38:17 -05:00
hyperdefined
06232f1dc4 sigh I am dumb 2026-01-26 13:32:28 -05:00
hyperdefined
a21fbf7a95 add blacklist-worlds feature 2026-01-26 13:23:28 -05:00
hyperdefined
96dd3ccd89 Update README.md 2026-01-25 17:51:55 -05:00
hyperdefined
fb1901085c config updater for 14 -> 15 2026-01-25 17:50:18 -05:00
hyperdefined
e537286785 improve compatibility with ValhallaMMO
fuck this plugin holy fuck
2026-01-20 20:14:18 -05:00
hyperdefined
6a994e4a82 move keys to own class
this took forever
2026-01-20 17:39:08 -05:00
hyperdefined
8a4da8ad56 add trident throws 2026-01-14 17:44:33 -05:00
hyperdefined
25e5a13095 support shields for damage taken 2026-01-14 16:57:49 -05:00
hyperdefined
72a5de5ee8 im a brick sometimes 2026-01-14 14:14:33 -05:00
hyperdefined
43b811db4e Update TokenData.java 2026-01-14 14:13:44 -05:00
hyperdefined
bd4ab50dc7 add critical strikes 2026-01-14 14:12:04 -05:00
hyperdefined
3087e3adcb more missing things 2026-01-14 13:58:02 -05:00
hyperdefined
588f413484 more misc things for bosses killed 2026-01-14 13:44:38 -05:00
hyperdefined
7beaa151c1 add bosses killed stat 2026-01-14 13:24:51 -05:00
hyperdefined
b5040a4636 1.9.11 (spear support) 2025-12-22 19:09:14 -05:00
37 changed files with 2380 additions and 715 deletions

View File

@@ -17,12 +17,14 @@ Here is everything it tracks:
* Crops mined (hoes). * Crops mined (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. * Armor damage taken (shields too).
* Damage done with weapons. * Damage done with weapons.
* Fish caught. * Fish caught.
* Sheep sheared. * Sheep sheared.
* Arrows shot (bows/crossbows). * Arrows shot (bows/crossbows).
* Flight time with elytras. * Flight time with elytras.
* Critical strikes for melee weapons.
* Times trident thrown.
The best part is, this data is stored on the item itself. The best part is, this data is stored on the item itself.

32
pom.xml
View File

@@ -23,7 +23,7 @@
<groupId>lol.hyper</groupId> <groupId>lol.hyper</groupId>
<artifactId>toolstats</artifactId> <artifactId>toolstats</artifactId>
<version>1.9.10</version> <version>2.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ToolStats</name> <name>ToolStats</name>
@@ -51,36 +51,12 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version> <version>3.15.0</version>
<configuration> <configuration>
<source>${java.version}</source> <source>${java.version}</source>
<target>${java.version}</target> <target>${java.version}</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<relocations>
<relocation>
<pattern>lol.hyper.hyperlib</pattern>
<shadedPattern>lol.hyper.toolstats.hyperlib</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
<resources> <resources>
<resource> <resource>
@@ -105,14 +81,14 @@
<dependency> <dependency>
<groupId>io.papermc.paper</groupId> <groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId> <artifactId>paper-api</artifactId>
<version>1.21.10-R0.1-SNAPSHOT</version> <version>1.21.11-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.hyperdefined</groupId> <groupId>com.github.hyperdefined</groupId>
<artifactId>hyperlib</artifactId> <artifactId>hyperlib</artifactId>
<version>1.0.9</version> <version>1.0.9</version>
<scope>compile</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -28,102 +28,18 @@ 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.logger.slf4j.ComponentLogger; import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; import java.io.File;
import java.util.HashSet;
import java.util.Set;
public final class ToolStats extends JavaPlugin { public final class ToolStats extends JavaPlugin {
/** public final int CONFIG_VERSION = 15;
* Stores who created an item.
*/
public final NamespacedKey itemOwner = new NamespacedKey(this, "owner");
/**
* Stores when the item was created.
*/
public final NamespacedKey timeCreated = new NamespacedKey(this, "time-created");
/**
* Stores how many player kills.
*/
public final NamespacedKey playerKills = new NamespacedKey(this, "player-kills");
/**
* Stores how many mob kills.
*/
public final NamespacedKey mobKills = new NamespacedKey(this, "mob-kills");
/**
* Stores how many blocks were mined.
*/
public final NamespacedKey blocksMined = new NamespacedKey(this, "generic-mined");
/**
* Stores how many crops were harvested.
*/
public final NamespacedKey cropsHarvested = new NamespacedKey(this, "crops-mined");
/**
* Stores how many fish were caught.
*/
public final NamespacedKey fishCaught = new NamespacedKey(this, "fish-caught");
/**
* Stores how many sheep were sheared.
*/
public final NamespacedKey sheepSheared = new NamespacedKey(this, "sheared");
/**
* Stores how much damage an armor piece has taken.
*/
public final NamespacedKey armorDamage = new NamespacedKey(this, "damage-taken");
/**
* Stores how much damage a weapon has done.
*/
public final NamespacedKey damageDone = new NamespacedKey(this, "damage-done");
/**
* Key for tracking new elytras that spawn.
*/
public final NamespacedKey newElytra = new NamespacedKey(this, "new");
/**
* Key for item has.
*/
public final NamespacedKey hash = new NamespacedKey(this, "hash");
/**
* Key for arrows shot.
*/
public final NamespacedKey arrowsShot = new NamespacedKey(this, "arrows-shot");
/**
* Key for arrows shot.
*/
public final NamespacedKey droppedBy = new NamespacedKey(this, "dropped-by");
/**
* Key for tracking flight time.
*/
public final NamespacedKey flightTime = new NamespacedKey(this, "flightTime");
/**
* Key for token type. This is for the token itself.
*/
public final NamespacedKey tokenType = new NamespacedKey(this, "token-type");
/**
* Key for applied token. This is what goes onto the tool/armor to record the type.
*/
public final NamespacedKey tokenApplied = new NamespacedKey(this, "token-applied");
/**
* Stores how an item was created.
* 0 = crafted.
* 1 = dropped.
* 2 = looted.
* 3 = traded.
* 4 = founded (for elytras).
* 5 = fished.
* 6 = spawned in (creative).
*/
public final NamespacedKey originType = new NamespacedKey(this, "origin");
public final int CONFIG_VERSION = 13;
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;
public final Set<NamespacedKey> tokenKeys = new HashSet<>();
public BlockBreak blockBreak; public BlockBreak blockBreak;
public ChunkPopulate chunkPopulate; public ChunkPopulate chunkPopulate;
@@ -154,6 +70,10 @@ public final class ToolStats extends JavaPlugin {
public BlockDispenseEvent blockDispenseEvent; public BlockDispenseEvent blockDispenseEvent;
public HyperLib hyperLib; public HyperLib hyperLib;
public TextUtils textUtils; public TextUtils textUtils;
public ProjectileShoot projectileShoot;
public ToolStatsKeys toolStatsKeys;
public InventoryClose inventoryClose;
public PlayerDrop playerDrop;
@Override @Override
public void onEnable() { public void onEnable() {
@@ -172,6 +92,8 @@ public final class ToolStats extends JavaPlugin {
loadConfig(); loadConfig();
configTools = new ConfigTools(this); configTools = new ConfigTools(this);
toolStatsKeys = new ToolStatsKeys(this);
toolStatsKeys.make();
tokenData = new TokenData(this); tokenData = new TokenData(this);
tokenData.setup(); tokenData.setup();
for (ShapedRecipe recipe : tokenData.getRecipes()) { for (ShapedRecipe recipe : tokenData.getRecipes()) {
@@ -203,17 +125,9 @@ public final class ToolStats extends JavaPlugin {
anvilEvent = new AnvilEvent(this); anvilEvent = new AnvilEvent(this);
prepareCraft = new PrepareCraft(this); prepareCraft = new PrepareCraft(this);
blockDispenseEvent = new BlockDispenseEvent(this); blockDispenseEvent = new BlockDispenseEvent(this);
projectileShoot = new ProjectileShoot(this);
// save which stat can be used by a reset token inventoryClose = new InventoryClose(this);
tokenKeys.add(blocksMined); playerDrop = new PlayerDrop(this);
tokenKeys.add(playerKills);
tokenKeys.add(mobKills);
tokenKeys.add(cropsHarvested);
tokenKeys.add(sheepSheared);
tokenKeys.add(fishCaught);
tokenKeys.add(flightTime);
tokenKeys.add(arrowsShot);
tokenKeys.add(armorDamage);
Bukkit.getServer().getPluginManager().registerEvents(blockBreak, this); Bukkit.getServer().getPluginManager().registerEvents(blockBreak, this);
Bukkit.getServer().getPluginManager().registerEvents(chunkPopulate, this); Bukkit.getServer().getPluginManager().registerEvents(chunkPopulate, this);
@@ -234,8 +148,11 @@ public final class ToolStats extends JavaPlugin {
Bukkit.getServer().getPluginManager().registerEvents(anvilEvent, this); Bukkit.getServer().getPluginManager().registerEvents(anvilEvent, this);
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(inventoryClose, this);
Bukkit.getServer().getPluginManager().registerEvents(playerDrop, this);
this.getCommand("toolstats").setExecutor(commandToolStats); registerCommand("toolstats", commandToolStats);
HyperUpdater updater = new HyperUpdater(hyperLib); HyperUpdater updater = new HyperUpdater(hyperLib);
updater.setGitHub("hyperdefined", "ToolStats"); updater.setGitHub("hyperdefined", "ToolStats");

View File

@@ -0,0 +1,37 @@
/*
* 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;
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
import io.papermc.paper.plugin.loader.PluginLoader;
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.repository.RemoteRepository;
public class ToolStatsLoader implements PluginLoader {
@Override
public void classloader(PluginClasspathBuilder classpathBuilder) {
MavenLibraryResolver resolver = new MavenLibraryResolver();
resolver.addRepository(new RemoteRepository.Builder("jitpack", "default", "https://jitpack.io").build());
resolver.addDependency(new Dependency(new DefaultArtifact("com.github.hyperdefined:hyperlib:1.0.9"), null));
classpathBuilder.addLibrary(resolver);
}
}

View File

@@ -65,12 +65,12 @@ public class AnvilEvent implements Listener {
PersistentDataContainer secondSlotContainer = secondSlot.getItemMeta().getPersistentDataContainer(); PersistentDataContainer secondSlotContainer = secondSlot.getItemMeta().getPersistentDataContainer();
// make sure the 2nd item is one of ours // make sure the 2nd item is one of ours
if (!secondSlotContainer.has(toolStats.tokenType, PersistentDataType.STRING)) { if (!secondSlotContainer.has(toolStats.toolStatsKeys.getTokenType(), PersistentDataType.STRING)) {
return; return;
} }
// get the type from the token // get the type from the token
String tokenType = secondSlotContainer.get(toolStats.tokenType, PersistentDataType.STRING); String tokenType = secondSlotContainer.get(toolStats.toolStatsKeys.getTokenType(), PersistentDataType.STRING);
if (tokenType == null) { if (tokenType == null) {
return; return;
} }
@@ -127,6 +127,18 @@ public class AnvilEvent implements Listener {
addToken(event, tokenType, "damage-done", clone); addToken(event, tokenType, "damage-done", clone);
return; return;
} }
if (tokenType.equalsIgnoreCase("wither-kills")) {
addToken(event, tokenType, "wither-kills", clone);
return;
}
if (tokenType.equalsIgnoreCase("enderdragon-kills")) {
addToken(event, tokenType, "enderdragon-kills", clone);
return;
}
if (tokenType.equalsIgnoreCase("critical-strikes")) {
addToken(event, tokenType, "critical-strikes", clone);
return;
}
} }
return; return;
} }
@@ -151,6 +163,22 @@ public class AnvilEvent implements Listener {
addToken(event, tokenType, "damage-done", clone); addToken(event, tokenType, "damage-done", clone);
return; return;
} }
if (tokenType.equalsIgnoreCase("wither-kills")) {
addToken(event, tokenType, "wither-kills", clone);
return;
}
if (tokenType.equalsIgnoreCase("enderdragon-kills")) {
addToken(event, tokenType, "enderdragon-kills", clone);
return;
}
if (tokenType.equalsIgnoreCase("critical-strikes")) {
addToken(event, tokenType, "critical-strikes", clone);
return;
}
if (tokenType.equalsIgnoreCase("trident-throws")) {
addToken(event, tokenType, "trident-throws", clone);
return;
}
return; return;
} }
if (firstSlotMaterial == Material.BOW || firstSlotMaterial == Material.CROSSBOW) { if (firstSlotMaterial == Material.BOW || firstSlotMaterial == Material.CROSSBOW) {
@@ -170,6 +198,14 @@ public class AnvilEvent implements Listener {
addToken(event, tokenType, "damage-done", clone); addToken(event, tokenType, "damage-done", clone);
return; return;
} }
if (tokenType.equalsIgnoreCase("wither-kills")) {
addToken(event, tokenType, "wither-kills", clone);
return;
}
if (tokenType.equalsIgnoreCase("enderdragon-kills")) {
addToken(event, tokenType, "enderdragon-kills", clone);
return;
}
return; return;
} }
if (firstSlotMaterial == Material.FISHING_ROD) { if (firstSlotMaterial == Material.FISHING_ROD) {
@@ -291,6 +327,42 @@ public class AnvilEvent implements Listener {
} }
break; break;
} }
case "wither-kills": {
if (toolStats.config.getBoolean("enabled.bosses-killed.wither")) {
newItem.setItemMeta(toolStats.itemLore.updateBossesKilled(newItem, 0, "wither"));
} else {
event.setResult(null);
return;
}
break;
}
case "enderdragon-kills": {
if (toolStats.config.getBoolean("enabled.bosses-killed.enderdragon")) {
newItem.setItemMeta(toolStats.itemLore.updateBossesKilled(newItem, 0, "enderdragon"));
} else {
event.setResult(null);
return;
}
break;
}
case "critical-strikes": {
if (toolStats.config.getBoolean("enabled.critical-strikes")) {
newItem.setItemMeta(toolStats.itemLore.updateCriticalStrikes(newItem, 0));
} else {
event.setResult(null);
return;
}
break;
}
case "trident-throws": {
if (toolStats.config.getBoolean("enabled.trident-throws")) {
newItem.setItemMeta(toolStats.itemLore.updateTridentThrows(newItem, 0));
} else {
event.setResult(null);
return;
}
break;
}
} }
event.setResult(newItem); event.setResult(newItem);
event.getView().setRepairCost(toolStats.itemChecker.getCost(targetToken)); event.getView().setRepairCost(toolStats.itemChecker.getCost(targetToken));
@@ -312,86 +384,118 @@ public class AnvilEvent implements Listener {
ItemMeta meta = finalItem.getItemMeta(); ItemMeta meta = finalItem.getItemMeta();
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.playerKills)) { if (container.has(toolStats.toolStatsKeys.getPlayerKills())) {
Integer playerKills = container.get(toolStats.playerKills, PersistentDataType.INTEGER); Integer playerKills = container.get(toolStats.toolStatsKeys.getPlayerKills(), PersistentDataType.INTEGER);
if (playerKills == null) { if (playerKills == null) {
return; return;
} }
meta = toolStats.itemLore.updatePlayerKills(finalItem, -playerKills); meta = toolStats.itemLore.updatePlayerKills(finalItem, -playerKills);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.mobKills)) { if (container.has(toolStats.toolStatsKeys.getMobKills())) {
Integer mobKills = container.get(toolStats.mobKills, PersistentDataType.INTEGER); Integer mobKills = container.get(toolStats.toolStatsKeys.getMobKills(), PersistentDataType.INTEGER);
if (mobKills == null) { if (mobKills == null) {
return; return;
} }
meta = toolStats.itemLore.updateMobKills(finalItem, -mobKills); meta = toolStats.itemLore.updateMobKills(finalItem, -mobKills);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.blocksMined)) { if (container.has(toolStats.toolStatsKeys.getBlocksMined())) {
Integer blocksMined = container.get(toolStats.blocksMined, PersistentDataType.INTEGER); Integer blocksMined = container.get(toolStats.toolStatsKeys.getBlocksMined(), PersistentDataType.INTEGER);
if (blocksMined == null) { if (blocksMined == null) {
return; return;
} }
meta = toolStats.itemLore.updateBlocksMined(finalItem, -blocksMined); meta = toolStats.itemLore.updateBlocksMined(finalItem, -blocksMined);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.cropsHarvested)) { if (container.has(toolStats.toolStatsKeys.getCropsHarvested())) {
Integer cropsHarvested = container.get(toolStats.playerKills, PersistentDataType.INTEGER); Integer cropsHarvested = container.get(toolStats.toolStatsKeys.getCropsHarvested(), PersistentDataType.INTEGER);
if (cropsHarvested == null) { if (cropsHarvested == null) {
return; return;
} }
meta = toolStats.itemLore.updateCropsMined(finalItem, -cropsHarvested); meta = toolStats.itemLore.updateCropsMined(finalItem, -cropsHarvested);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.fishCaught)) { if (container.has(toolStats.toolStatsKeys.getFishCaught())) {
Integer fishCaught = container.get(toolStats.fishCaught, PersistentDataType.INTEGER); Integer fishCaught = container.get(toolStats.toolStatsKeys.getFishCaught(), PersistentDataType.INTEGER);
if (fishCaught == null) { if (fishCaught == null) {
return; return;
} }
meta = toolStats.itemLore.updateFishCaught(finalItem, -fishCaught); meta = toolStats.itemLore.updateFishCaught(finalItem, -fishCaught);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.sheepSheared)) { if (container.has(toolStats.toolStatsKeys.getSheepSheared())) {
Integer sheepSheared = container.get(toolStats.sheepSheared, PersistentDataType.INTEGER); Integer sheepSheared = container.get(toolStats.toolStatsKeys.getSheepSheared(), PersistentDataType.INTEGER);
if (sheepSheared == null) { if (sheepSheared == null) {
return; return;
} }
meta = toolStats.itemLore.updateSheepSheared(finalItem, -sheepSheared); meta = toolStats.itemLore.updateSheepSheared(finalItem, -sheepSheared);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.armorDamage)) { if (container.has(toolStats.toolStatsKeys.getArmorDamage())) {
Double armorDamage = container.get(toolStats.armorDamage, PersistentDataType.DOUBLE); Double armorDamage = container.get(toolStats.toolStatsKeys.getArmorDamage(), PersistentDataType.DOUBLE);
if (armorDamage == null) { if (armorDamage == null) {
return; return;
} }
meta = toolStats.itemLore.updateArmorDamage(finalItem, -armorDamage, true); meta = toolStats.itemLore.updateArmorDamage(finalItem, -armorDamage, true);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.damageDone)) { if (container.has(toolStats.toolStatsKeys.getDamageDone())) {
Double damageDone = container.get(toolStats.damageDone, PersistentDataType.DOUBLE); Double damageDone = container.get(toolStats.toolStatsKeys.getDamageDone(), PersistentDataType.DOUBLE);
if (damageDone == null) { if (damageDone == null) {
return; return;
} }
meta = toolStats.itemLore.updateArmorDamage(finalItem, -damageDone, true); meta = toolStats.itemLore.updateArmorDamage(finalItem, -damageDone, true);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.arrowsShot)) { if (container.has(toolStats.toolStatsKeys.getArrowsShot())) {
Integer arrowsShot = container.get(toolStats.arrowsShot, PersistentDataType.INTEGER); Integer arrowsShot = container.get(toolStats.toolStatsKeys.getArrowsShot(), PersistentDataType.INTEGER);
if (arrowsShot == null) { if (arrowsShot == null) {
return; return;
} }
meta = toolStats.itemLore.updateArrowsShot(finalItem, -arrowsShot); meta = toolStats.itemLore.updateArrowsShot(finalItem, -arrowsShot);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.flightTime)) { if (container.has(toolStats.toolStatsKeys.getFlightTime())) {
Long flightTime = container.get(toolStats.flightTime, PersistentDataType.LONG); Long flightTime = container.get(toolStats.toolStatsKeys.getFlightTime(), PersistentDataType.LONG);
if (flightTime == null) { if (flightTime == null) {
return; return;
} }
meta = toolStats.itemLore.updateFlightTime(finalItem, -flightTime); meta = toolStats.itemLore.updateFlightTime(finalItem, -flightTime);
finalItem.setItemMeta(meta); finalItem.setItemMeta(meta);
} }
if (container.has(toolStats.toolStatsKeys.getWitherKills())) {
Integer witherKills = container.get(toolStats.toolStatsKeys.getWitherKills(), PersistentDataType.INTEGER);
if (witherKills == null) {
return;
}
meta = toolStats.itemLore.updateBossesKilled(finalItem, -witherKills, "wither");
finalItem.setItemMeta(meta);
}
if (container.has(toolStats.toolStatsKeys.getEnderDragonKills())) {
Integer enderDragonKills = container.get(toolStats.toolStatsKeys.getEnderDragonKills(), PersistentDataType.INTEGER);
if (enderDragonKills == null) {
return;
}
meta = toolStats.itemLore.updateBossesKilled(finalItem, -enderDragonKills, "enderdragon");
finalItem.setItemMeta(meta);
}
if (container.has(toolStats.toolStatsKeys.getCriticalStrikes())) {
Integer criticalStrikes = container.get(toolStats.toolStatsKeys.getCriticalStrikes(), PersistentDataType.INTEGER);
if (criticalStrikes == null) {
return;
}
meta = toolStats.itemLore.updateCriticalStrikes(finalItem, -criticalStrikes);
finalItem.setItemMeta(meta);
}
if (container.has(toolStats.toolStatsKeys.getTridentThrows())) {
Integer tridentThrows = container.get(toolStats.toolStatsKeys.getTridentThrows(), PersistentDataType.INTEGER);
if (tridentThrows == null) {
return;
}
meta = toolStats.itemLore.updateTridentThrows(finalItem, -tridentThrows);
finalItem.setItemMeta(meta);
}
event.setResult(finalItem); event.setResult(finalItem);
event.getView().setRepairCost(toolStats.itemChecker.getCost("reset")); event.getView().setRepairCost(toolStats.itemChecker.getCost("reset"));
} }

View File

@@ -18,25 +18,28 @@
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.*;
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.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale; import java.util.Locale;
public class BlockBreak implements Listener { public class BlockBreak implements Listener {
private final ToolStats toolStats; private final ToolStats toolStats;
public List<Block> brokenContainers = new ArrayList<>();
public BlockBreak(ToolStats toolStats) { public BlockBreak(ToolStats toolStats) {
this.toolStats = toolStats; this.toolStats = toolStats;
@@ -48,6 +51,9 @@ public class BlockBreak implements Listener {
return; return;
} }
Player player = event.getPlayer(); Player player = event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) { if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) {
return; return;
} }
@@ -55,9 +61,9 @@ 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) { if (block.getType() == Material.CHEST || block.getType() == Material.BARREL) {
toolStats.playerInteract.openedChests.put(block, player); brokenContainers.add(block);
Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> toolStats.playerInteract.openedChests.remove(block), 20); Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> brokenContainers.remove(block), 20);
} }
// only check certain items // only check certain items
@@ -96,4 +102,41 @@ public class BlockBreak implements Listener {
} }
} }
} }
@EventHandler(priority = EventPriority.HIGHEST)
public void onBreak(BlockDropItemEvent event) {
Player player = event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
Location eventLocation = event.getBlock().getLocation();
Chunk eventChunk = eventLocation.getChunk();
Bukkit.getRegionScheduler().runDelayed(toolStats, eventLocation.getWorld(), eventChunk.getX(), eventChunk.getZ(), scheduledTask -> {
boolean validLootDrops = false;
for (Location droppedLootLocation : toolStats.generateLoot.droppedLootLocations) {
if (eventLocation.getWorld() == droppedLootLocation.getWorld()) {
double distance = droppedLootLocation.distance(eventLocation);
if (distance <= 1.0) {
validLootDrops = true;
}
}
}
if (validLootDrops) {
toolStats.generateLoot.droppedLootLocations.remove(eventLocation);
for (Item droppedItemEntity : event.getItems()) {
ItemStack droppedItem = droppedItemEntity.getItemStack();
if (!toolStats.itemChecker.isValidItem(droppedItem.getType())) {
continue;
}
ItemStack newItem = toolStats.inventoryClose.addLootedOrigin(droppedItem, player);
if (newItem != null) {
droppedItemEntity.setItemStack(newItem);
}
}
}
}, 1);
}
} }

View File

@@ -48,11 +48,13 @@ public class BlockDispenseEvent implements Listener {
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onDispense(BlockDispenseLootEvent event) { public void onDispense(BlockDispenseLootEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (player == null) { if (player == null) {
return; return;
} }
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) { if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) {
return; return;
} }
@@ -99,7 +101,7 @@ public class BlockDispenseEvent implements Listener {
} }
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.itemOwner, PersistentDataType.LONG)) { if (container.has(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG) || container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
return null; return null;
} }
@@ -114,8 +116,8 @@ public class BlockDispenseEvent implements Listener {
// if creation date is enabled, add it // if creation date is enabled, add it
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 2, newItem); Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 2, newItem);
if (creationDate != null) { if (creationDate != null) {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.originType, PersistentDataType.INTEGER, 2); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 2);
lore.add(creationDate); lore.add(creationDate);
meta.lore(lore); meta.lore(lore);
} }
@@ -123,8 +125,8 @@ public class BlockDispenseEvent implements Listener {
// if ownership is enabled, add it // if ownership is enabled, add it
Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 2, newItem); Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 2, newItem);
if (itemOwner != null) { if (itemOwner != null) {
container.set(toolStats.itemOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 2); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 2);
lore.add(itemOwner); lore.add(itemOwner);
meta.lore(lore); meta.lore(lore);
} }
@@ -132,7 +134,7 @@ public class BlockDispenseEvent implements Listener {
// if hash is enabled, add it // if hash is enabled, add it
if (toolStats.config.getBoolean("generate-hash-for-items")) { if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated); String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated);
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);

View File

@@ -50,6 +50,9 @@ public class ChunkPopulate implements Listener {
return; return;
} }
World world = event.getChunk().getWorld(); World world = event.getChunk().getWorld();
if (!toolStats.configTools.checkWorld(world.getName())) {
return;
}
// 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();
@@ -68,7 +71,7 @@ public class ChunkPopulate implements Listener {
} }
// add the new tag so we know it's new // add the new tag so we know it's new
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(toolStats.newElytra, PersistentDataType.INTEGER, 1); container.set(toolStats.toolStatsKeys.getElytraKey(), PersistentDataType.INTEGER, 1);
elytraCopy.setItemMeta(meta); elytraCopy.setItemMeta(meta);
itemFrame.setItem(elytraCopy); itemFrame.setItem(elytraCopy);
} }

View File

@@ -50,6 +50,9 @@ public class CraftItem implements Listener {
return; return;
} }
Player player = (Player) event.getWhoClicked(); Player player = (Player) event.getWhoClicked();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) { if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) {
return; return;
} }
@@ -130,7 +133,7 @@ public class CraftItem implements Listener {
// if the item already has the tag // if the item already has the tag
// this is to prevent duplicate tags // this is to prevent duplicate tags
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.itemOwner, PersistentDataType.LONG)) { if (container.has(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG) || container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
return null; return null;
} }
@@ -145,8 +148,8 @@ public class CraftItem implements Listener {
// if creation date is enabled, add it // if creation date is enabled, add it
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 0, newItem); Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 0, newItem);
if (creationDate != null) { if (creationDate != null) {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.originType, PersistentDataType.INTEGER, 0); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 0);
lore.add(creationDate); lore.add(creationDate);
meta.lore(lore); meta.lore(lore);
} }
@@ -154,8 +157,8 @@ public class CraftItem implements Listener {
// if ownership is enabled, add it // if ownership is enabled, add it
Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 0, newItem); Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 0, newItem);
if (itemOwner != null) { if (itemOwner != null) {
container.set(toolStats.itemOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 0); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 0);
lore.add(itemOwner); lore.add(itemOwner);
meta.lore(lore); meta.lore(lore);
} }
@@ -163,7 +166,7 @@ public class CraftItem implements Listener {
// if hash is enabled, add it // if hash is enabled, add it
if (toolStats.config.getBoolean("generate-hash-for-items")) { if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated); String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated);
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);
return newItem; return newItem;

View File

@@ -45,6 +45,9 @@ public class CreativeEvent implements Listener {
@EventHandler @EventHandler
public void onCreativeEvent(InventoryCreativeEvent event) { public void onCreativeEvent(InventoryCreativeEvent event) {
Player player = (Player) event.getWhoClicked(); Player player = (Player) event.getWhoClicked();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
// make sure they are in creative mode // make sure they are in creative mode
if (player.getGameMode() != GameMode.CREATIVE) { if (player.getGameMode() != GameMode.CREATIVE) {
return; return;
@@ -61,7 +64,7 @@ public class CreativeEvent implements Listener {
// if the item already has an origin set, don't add it again // if the item already has an origin set, don't add it again
// this is needed since you can spam click an item and the event will fire again // this is needed since you can spam click an item and the event will fire again
PersistentDataContainer container = spawnedItemMeta.getPersistentDataContainer(); PersistentDataContainer container = spawnedItemMeta.getPersistentDataContainer();
if (container.has(toolStats.originType, PersistentDataType.INTEGER)) { if (container.has(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER)) {
return; return;
} }
@@ -97,7 +100,7 @@ public class CreativeEvent implements Listener {
// if the item already has the tag // if the item already has the tag
// this is to prevent duplicate tags // this is to prevent duplicate tags
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.itemOwner, PersistentDataType.LONG)) { if (container.has(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG) || container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
return null; return null;
} }
@@ -112,8 +115,8 @@ public class CreativeEvent implements Listener {
// if creation date is enabled, add it // if creation date is enabled, add it
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 6, newSpawnedItem); Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 6, newSpawnedItem);
if (creationDate != null) { if (creationDate != null) {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.originType, PersistentDataType.INTEGER, 6); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 6);
lore.add(creationDate); lore.add(creationDate);
meta.lore(lore); meta.lore(lore);
} }
@@ -121,8 +124,8 @@ public class CreativeEvent implements Listener {
// if ownership is enabled, add it // if ownership is enabled, add it
Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 6, newSpawnedItem); Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 6, newSpawnedItem);
if (itemOwner != null) { if (itemOwner != null) {
container.set(toolStats.itemOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 6); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 6);
lore.add(itemOwner); lore.add(itemOwner);
meta.lore(lore); meta.lore(lore);
} }
@@ -130,7 +133,7 @@ public class CreativeEvent implements Listener {
// if hash is enabled, add it // if hash is enabled, add it
if (toolStats.config.getBoolean("generate-hash-for-items")) { if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(newSpawnedItem.getType(), owner.getUniqueId(), timeCreated); String hash = toolStats.hashMaker.makeHash(newSpawnedItem.getType(), owner.getUniqueId(), timeCreated);
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
} }
newSpawnedItem.setItemMeta(meta); newSpawnedItem.setItemMeta(meta);

View File

@@ -29,6 +29,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.projectiles.ProjectileSource; import org.bukkit.projectiles.ProjectileSource;
@@ -55,6 +56,10 @@ public class EntityDamage implements Listener {
return; return;
} }
if (!toolStats.configTools.checkWorld(mobBeingAttacked.getWorld().getName())) {
return;
}
// ignore void and /kill damage // ignore void and /kill damage
EntityDamageEvent.DamageCause cause = event.getCause(); EntityDamageEvent.DamageCause cause = event.getCause();
if (ignoredCauses.contains(cause)) { if (ignoredCauses.contains(cause)) {
@@ -66,10 +71,21 @@ public class EntityDamage implements Listener {
boolean playerBeingAttacked = mobBeingAttacked instanceof Player; boolean playerBeingAttacked = mobBeingAttacked instanceof Player;
double finalDamage = event.getFinalDamage(); double finalDamage = event.getFinalDamage();
boolean modDied = mobBeingAttacked.getHealth() - finalDamage <= 0; boolean modDied = mobBeingAttacked.getHealth() - finalDamage <= 0;
EntityType mobAttackedType = event.getEntityType();
boolean critical = event.isCritical();
if (playerBeingAttacked) {
Player player = (Player) event.getEntity();
if (player.isBlocking()) {
double blockedDamage = -event.getDamage(EntityDamageEvent.DamageModifier.BLOCKING);
updateShieldDamage(player.getInventory(), blockedDamage);
}
}
// player attacks something // player attacks something
if (playerAttacking) { if (playerAttacking) {
PlayerInventory playerAttackingInventory = ((Player) damager).getInventory(); Player player = (Player) damager;
PlayerInventory playerAttackingInventory = player.getInventory();
// make sure the item the player used is an item we want // make sure the item the player used is an item we want
if (!toolStats.itemChecker.isMeleeWeapon(playerAttackingInventory.getItemInMainHand().getType())) { if (!toolStats.itemChecker.isMeleeWeapon(playerAttackingInventory.getItemInMainHand().getType())) {
return; return;
@@ -78,6 +94,11 @@ public class EntityDamage implements Listener {
// update their weapon's damage // update their weapon's damage
updateWeaponDamage(playerAttackingInventory, event.getFinalDamage()); updateWeaponDamage(playerAttackingInventory, event.getFinalDamage());
// if the player crit
if (critical) {
updateCriticalStrikes(playerAttackingInventory);
}
// the mob the player attacked died // the mob the player attacked died
if (modDied) { if (modDied) {
// player killed another player // player killed another player
@@ -86,6 +107,12 @@ public class EntityDamage implements Listener {
} else { } else {
// player kills a regular mob // player kills a regular mob
updateWeaponKills(playerAttackingInventory, "mob"); updateWeaponKills(playerAttackingInventory, "mob");
if (mobAttackedType == EntityType.WITHER) {
updateBossesKilled(playerAttackingInventory, "wither");
}
if (mobAttackedType == EntityType.ENDER_DRAGON) {
updateBossesKilled(playerAttackingInventory, "enderdragon");
}
} }
} }
@@ -96,7 +123,7 @@ public class EntityDamage implements Listener {
// something was hit by a trident // something was hit by a trident
if (damager instanceof Trident trident) { if (damager instanceof Trident trident) {
ProjectileSource source = trident.getShooter(); ProjectileSource source = trident.getShooter();
if (source instanceof Player) { if (source instanceof Player player) {
// update the trident's tracked damage // update the trident's tracked damage
updateTridentDamage(trident, finalDamage); updateTridentDamage(trident, finalDamage);
@@ -108,6 +135,12 @@ public class EntityDamage implements Listener {
} else { } else {
// the trident killed a mob, update the kills // the trident killed a mob, update the kills
updateTridentKills(trident, "mob"); updateTridentKills(trident, "mob");
if (mobAttackedType == EntityType.WITHER) {
updateBossesKilled(player.getInventory(), "wither");
}
if (mobAttackedType == EntityType.ENDER_DRAGON) {
updateBossesKilled(player.getInventory(), "enderdragon");
}
} }
} }
@@ -133,6 +166,12 @@ public class EntityDamage implements Listener {
} else { } else {
// player killed mob with an arrow // player killed mob with an arrow
updateBowKills(shootingPlayer.getInventory(), "mob"); updateBowKills(shootingPlayer.getInventory(), "mob");
if (mobAttackedType == EntityType.WITHER) {
updateBossesKilledByBow(shootingPlayer.getInventory(), "wither");
}
if (mobAttackedType == EntityType.ENDER_DRAGON) {
updateBossesKilledByBow(shootingPlayer.getInventory(), "enderdragon");
}
} }
} }
@@ -188,7 +227,6 @@ public class EntityDamage implements Listener {
boolean isMain = playerInventory.getItemInMainHand().getType() == Material.BOW || playerInventory.getItemInMainHand().getType() == Material.CROSSBOW; boolean isMain = playerInventory.getItemInMainHand().getType() == Material.BOW || playerInventory.getItemInMainHand().getType() == Material.CROSSBOW;
boolean isOffHand = playerInventory.getItemInOffHand().getType() == Material.BOW || playerInventory.getItemInOffHand().getType() == Material.CROSSBOW; boolean isOffHand = playerInventory.getItemInOffHand().getType() == Material.BOW || playerInventory.getItemInOffHand().getType() == Material.CROSSBOW;
ItemMeta newBowDamage = toolStats.itemLore.updateWeaponDamage(heldBow, damage, false); ItemMeta newBowDamage = toolStats.itemLore.updateWeaponDamage(heldBow, damage, false);
//toolStats.logger.info(newBowDamage.toString());
// player is shooting another player // player is shooting another player
if (newBowDamage != null) { if (newBowDamage != null) {
@@ -283,4 +321,82 @@ public class EntityDamage implements Listener {
playerInventory.getItemInMainHand().setItemMeta(newHeldWeaponMeta); playerInventory.getItemInMainHand().setItemMeta(newHeldWeaponMeta);
} }
} }
private void updateBossesKilled(PlayerInventory playerInventory, String boss) {
ItemStack heldWeapon = playerInventory.getItemInMainHand();
ItemMeta newHeldWeaponMeta = toolStats.itemLore.updateBossesKilled(heldWeapon, 1, boss);
if (newHeldWeaponMeta != null) {
playerInventory.getItemInMainHand().setItemMeta(newHeldWeaponMeta);
}
}
private void updateBossesKilledByBow(PlayerInventory playerInventory, String boss) {
ItemStack heldBow = toolStats.itemChecker.getBow(playerInventory);
if (heldBow == null) {
return;
}
boolean isMain = playerInventory.getItemInMainHand().getType() == Material.BOW || playerInventory.getItemInMainHand().getType() == Material.CROSSBOW;
boolean isOffHand = playerInventory.getItemInOffHand().getType() == Material.BOW || playerInventory.getItemInOffHand().getType() == Material.CROSSBOW;
ItemMeta newHeldWeaponMeta = toolStats.itemLore.updateBossesKilled(heldBow, 1, boss);
if (newHeldWeaponMeta != null) {
if (isMain && isOffHand) {
playerInventory.getItemInMainHand().setItemMeta(newHeldWeaponMeta);
} else if (isMain) {
playerInventory.getItemInMainHand().setItemMeta(newHeldWeaponMeta);
} else if (isOffHand) {
playerInventory.getItemInOffHand().setItemMeta(newHeldWeaponMeta);
}
}
}
private void updateCriticalStrikes(PlayerInventory playerInventory) {
ItemStack heldWeapon = playerInventory.getItemInMainHand();
ItemMeta newHeldWeaponMeta = toolStats.itemLore.updateCriticalStrikes(heldWeapon, 1);
if (newHeldWeaponMeta != null) {
playerInventory.getItemInMainHand().setItemMeta(newHeldWeaponMeta);
}
}
private void updateShieldDamage(PlayerInventory playerInventory, double damage) {
boolean isMain = playerInventory.getItemInMainHand().getType() == Material.SHIELD;
boolean isOffHand = playerInventory.getItemInOffHand().getType() == Material.SHIELD;
ItemStack heldShield;
if (isMain && isOffHand) {
heldShield = playerInventory.getItemInMainHand();
int shieldDamage = (heldShield.getItemMeta() instanceof Damageable d) ? d.getDamage() : 0;
ItemMeta newShieldMeta = toolStats.itemLore.updateArmorDamage(heldShield, damage, false);
if (newShieldMeta != null) {
if (newShieldMeta instanceof Damageable dNew) {
dNew.setDamage(shieldDamage);
}
playerInventory.getItemInMainHand().setItemMeta(newShieldMeta);
}
} else if (isMain) {
heldShield = playerInventory.getItemInMainHand();
int shieldDamage = (heldShield.getItemMeta() instanceof Damageable d) ? d.getDamage() : 0;
ItemMeta newShieldMeta = toolStats.itemLore.updateArmorDamage(heldShield, damage, false);
if (newShieldMeta != null) {
if (newShieldMeta instanceof Damageable dNew) {
dNew.setDamage(shieldDamage);
}
playerInventory.getItemInMainHand().setItemMeta(newShieldMeta);
}
} else if (isOffHand) {
heldShield = playerInventory.getItemInOffHand();
int shieldDamage = (heldShield.getItemMeta() instanceof Damageable d) ? d.getDamage() : 0;
ItemMeta newShieldMeta = toolStats.itemLore.updateArmorDamage(heldShield, damage, false);
if (newShieldMeta != null) {
if (newShieldMeta instanceof Damageable dNew) {
dNew.setDamage(shieldDamage);
}
playerInventory.getItemInOffHand().setItemMeta(newShieldMeta);
}
}
}
} }

View File

@@ -49,6 +49,9 @@ public class EntityDeath implements Listener {
if (livingEntity instanceof Player) { if (livingEntity instanceof Player) {
return; return;
} }
if (!toolStats.configTools.checkWorld(livingEntity.getWorld().getName())) {
return;
}
UUID livingEntityUUID = event.getEntity().getUniqueId(); UUID livingEntityUUID = event.getEntity().getUniqueId();
// if it's a mob we are tracking that matters // if it's a mob we are tracking that matters
if (toolStats.mobKill.trackedMobs.contains(livingEntityUUID)) { if (toolStats.mobKill.trackedMobs.contains(livingEntityUUID)) {
@@ -57,7 +60,7 @@ public class EntityDeath implements Listener {
ItemMeta droppedItemMeta = droppedItem.getItemMeta(); ItemMeta droppedItemMeta = droppedItem.getItemMeta();
if (droppedItemMeta != null) { if (droppedItemMeta != null) {
PersistentDataContainer container = droppedItemMeta.getPersistentDataContainer(); PersistentDataContainer container = droppedItemMeta.getPersistentDataContainer();
if (container.has(toolStats.originType, PersistentDataType.INTEGER)) { if (container.has(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER)) {
continue; // ignore any items that have our tags continue; // ignore any items that have our tags
} }
@@ -109,15 +112,15 @@ public class EntityDeath implements Listener {
// if creation date is enabled, add it // if creation date is enabled, add it
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 1, newItem); Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 1, newItem);
if (creationDate != null) { if (creationDate != null) {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.originType, PersistentDataType.INTEGER, 1); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 1);
lore.add(creationDate); lore.add(creationDate);
meta.lore(lore); meta.lore(lore);
} }
if (toolStats.config.getBoolean("enabled.dropped-by")) { if (toolStats.config.getBoolean("enabled.dropped-by")) {
container.set(toolStats.originType, PersistentDataType.INTEGER, 1); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 1);
container.set(toolStats.droppedBy, PersistentDataType.STRING, mobName); container.set(toolStats.toolStatsKeys.getDroppedBy(), PersistentDataType.STRING, mobName);
Component droppedBy = toolStats.configTools.formatLore("dropped-by", "{name}", mobName); Component droppedBy = toolStats.configTools.formatLore("dropped-by", "{name}", mobName);
lore.add(droppedBy); lore.add(droppedBy);
} }

View File

@@ -17,32 +17,30 @@
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.ArrayList;
import java.util.Date; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
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 List<Location> droppedLootLocations = new ArrayList<>();
public GenerateLoot(ToolStats toolStats) { public GenerateLoot(ToolStats toolStats) {
this.toolStats = toolStats; this.toolStats = toolStats;
@@ -55,117 +53,47 @@ public class GenerateLoot implements Listener {
return; return;
} }
Location lootLocation = event.getLootContext().getLocation(); Location lootLocation = event.getLootContext().getLocation();
if (!toolStats.configTools.checkWorld(lootLocation.getWorld().getName())) {
if (inventoryHolder instanceof Chest) { return;
Block openedChest = null; }
// look at the current list of opened chest and get the distance Chunk lootChunk = lootLocation.getChunk();
// between the LootContext location and chest location Bukkit.getRegionScheduler().runDelayed(toolStats, lootLocation.getWorld(), lootChunk.getX(), lootChunk.getZ(), scheduledTask -> {
// if the distance is less than 1, it's the same chest if (inventoryHolder instanceof Container) {
for (Block chest : toolStats.playerInteract.openedChests.keySet()) { Block openedChest = null;
Location chestLocation = chest.getLocation(); Location chestLocation = null;
if (chest.getWorld() == lootLocation.getWorld()) { // look at the current list of opened chest and get the distance
double distance = lootLocation.distance(chestLocation); // between the LootContext location and chest location
if (distance <= 1.0) { // if the distance is less than 1, it's the same chest
openedChest = chest; for (Block chest : toolStats.playerInteract.openedChests) {
chestLocation = chest.getLocation();
if (chest.getWorld() == lootLocation.getWorld()) {
double distance = lootLocation.distance(chestLocation);
if (distance <= 1.0) {
openedChest = chest;
}
} }
} }
} for (Block brokenChest : toolStats.blockBreak.brokenContainers) {
// ignore if the chest is not in the same location Location brokenChestLocation = brokenChest.getLocation();
if (openedChest == null) { if (brokenChestLocation.getWorld() == lootLocation.getWorld()) {
return; double distance = lootLocation.distance(brokenChestLocation);
} if (distance <= 1.0) {
droppedLootLocations.add(brokenChestLocation);
Player player = toolStats.playerInteract.openedChests.get(openedChest); Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask2 -> droppedLootLocations.remove(brokenChestLocation), 20);
setLoot(event.getLoot(), player); }
} }
if (inventoryHolder instanceof StorageMinecart mineCart) { }
if (toolStats.playerInteract.openedMineCarts.containsKey(mineCart)) { // ignore if the chest is not in the same location
Player player = toolStats.playerInteract.openedMineCarts.get(mineCart); if (openedChest != null) {
setLoot(event.getLoot(), player); generatedInventory.put(inventoryHolder.getInventory(), chestLocation);
}
}
}
/**
* 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.timeCreated, PersistentDataType.LONG) || container.has(toolStats.itemOwner, PersistentDataType.LONG)) {
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.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.originType, 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.itemOwner, new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, 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.hash, 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());
}
}
}, 1);
} }
} }

View File

@@ -0,0 +1,196 @@
/*
* 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();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
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.
*/
public 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

@@ -19,12 +19,14 @@ package lol.hyper.toolstats.events;
import lol.hyper.hyperlib.datatypes.UUIDDataType; import lol.hyper.hyperlib.datatypes.UUIDDataType;
import lol.hyper.toolstats.ToolStats; import lol.hyper.toolstats.ToolStats;
import org.bukkit.block.DoubleChest;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.BlockInventoryHolder;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack; 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;
@@ -47,12 +49,17 @@ public class InventoryOpen implements Listener {
} }
Inventory inventory = event.getInventory(); Inventory inventory = event.getInventory();
// only check these InventoryHolder holder = inventory.getHolder();
if (inventory.getType() != InventoryType.CHEST || inventory.getType() != InventoryType.BARREL || inventory.getType() != InventoryType.SHULKER_BOX || inventory.getType() != InventoryType.ENDER_CHEST) { boolean isBlockInventory = holder instanceof BlockInventoryHolder || holder instanceof DoubleChest;
if (!(inventory.getHolder() instanceof BlockInventoryHolder)) {
// ignore not real inventories
return; return;
} }
Player player = (Player) event.getPlayer(); Player player = (Player) event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
for (ItemStack itemStack : inventory) { for (ItemStack itemStack : inventory) {
if (itemStack == null) { if (itemStack == null) {
continue; continue;
@@ -69,13 +76,13 @@ public class InventoryOpen implements Listener {
if (toolStats.config.getBoolean("tokens.enabled")) { if (toolStats.config.getBoolean("tokens.enabled")) {
// if the token system is on and the item doesn't have stat keys // if the token system is on and the item doesn't have stat keys
if (toolStats.itemChecker.keyCheck(container) && !container.has(toolStats.tokenType)) { if (toolStats.itemChecker.keyCheck(container) && !container.has(toolStats.toolStatsKeys.getTokenType())) {
// add the tokens // add the tokens
String newTokens = toolStats.itemChecker.addTokensToExisting(itemStack); String newTokens = toolStats.itemChecker.addTokensToExisting(itemStack);
if (newTokens == null) { if (newTokens == null) {
return; return;
} }
container.set(toolStats.tokenApplied, PersistentDataType.STRING, newTokens); container.set(toolStats.toolStatsKeys.getTokenApplied(), PersistentDataType.STRING, newTokens);
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
} }
} }
@@ -83,29 +90,29 @@ public class InventoryOpen implements Listener {
// generate a hash if the item doesn't have one (and enabled) // generate a hash if the item doesn't have one (and enabled)
// if hashes are disabled and the item has one, remove it. // if hashes are disabled and the item has one, remove it.
if (toolStats.config.getBoolean("generate-hash-for-items")) { if (toolStats.config.getBoolean("generate-hash-for-items")) {
if (!container.has(toolStats.hash, PersistentDataType.STRING)) { if (!container.has(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING)) {
UUID owner = null; UUID owner = null;
// get the current owner if there is one. // get the current owner if there is one.
if (container.has(toolStats.itemOwner, new UUIDDataType())) { if (container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
owner = container.get(toolStats.itemOwner, new UUIDDataType()); owner = container.get(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType());
} }
// if there is no owner, use the player holding it // if there is no owner, use the player holding it
if (owner == null) { if (owner == null) {
owner = player.getUniqueId(); owner = player.getUniqueId();
} }
Long timestamp = container.get(toolStats.timeCreated, PersistentDataType.LONG); Long timestamp = container.get(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG);
if (timestamp == null) { if (timestamp == null) {
// if there is no time created, use now // if there is no time created, use now
timestamp = System.currentTimeMillis(); timestamp = System.currentTimeMillis();
} }
String hash = toolStats.hashMaker.makeHash(itemStack.getType(), owner, timestamp); String hash = toolStats.hashMaker.makeHash(itemStack.getType(), owner, timestamp);
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
} }
} else { } else {
// if hashes are disabled but the item has one, remove it. // if hashes are disabled but the item has one, remove it.
if (container.has(toolStats.hash, PersistentDataType.STRING)) { if (container.has(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING)) {
container.remove(toolStats.hash); container.remove(toolStats.toolStatsKeys.getHash());
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
} }
} }

View File

@@ -54,6 +54,9 @@ public class PickupItem implements Listener {
} }
Entity entity = event.getEntity(); Entity entity = event.getEntity();
if (entity instanceof Player player) { if (entity instanceof Player player) {
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) { if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) {
return; return;
} }
@@ -67,7 +70,7 @@ public class PickupItem implements Listener {
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (itemStack.getType() == Material.ELYTRA) { if (itemStack.getType() == Material.ELYTRA) {
// the elytra has the new key, set the lore to it // the elytra has the new key, set the lore to it
if (container.has(toolStats.newElytra, PersistentDataType.INTEGER)) { if (container.has(toolStats.toolStatsKeys.getElytraKey(), PersistentDataType.INTEGER)) {
ItemStack newElytra = addElytraOrigin(itemStack, (Player) event.getEntity()); ItemStack newElytra = addElytraOrigin(itemStack, (Player) event.getEntity());
if (newElytra != null) { if (newElytra != null) {
item.setItemStack(newElytra); item.setItemStack(newElytra);
@@ -105,7 +108,7 @@ public class PickupItem implements Listener {
// only make the hash if it's enabled // only make the hash if it's enabled
if (toolStats.config.getBoolean("generate-hash-for-items")) { if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(finalItem.getType(), owner.getUniqueId(), timeCreated); String hash = toolStats.hashMaker.makeHash(finalItem.getType(), owner.getUniqueId(), timeCreated);
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
} }
// get the current lore the item // get the current lore the item
@@ -116,23 +119,23 @@ public class PickupItem implements Listener {
lore = new ArrayList<>(); lore = new ArrayList<>();
} }
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.itemOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 4); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 4);
container.remove(toolStats.newElytra); container.remove(toolStats.toolStatsKeys.getElytraKey());
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 4, finalItem); Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 4, finalItem);
if (creationDate != null) { if (creationDate != null) {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.originType, PersistentDataType.INTEGER, 4); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 4);
lore.add(creationDate); lore.add(creationDate);
meta.lore(lore); meta.lore(lore);
} }
Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 4, finalItem); Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 4, finalItem);
if (itemOwner != null) { if (itemOwner != null) {
container.set(toolStats.itemOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 4); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 4);
lore.add(itemOwner); lore.add(itemOwner);
meta.lore(lore); meta.lore(lore);
} }

View File

@@ -0,0 +1,65 @@
/*
* 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.toolstats.ToolStats;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public class PlayerDrop implements Listener {
private final ToolStats toolStats;
public PlayerDrop(ToolStats toolStats) {
this.toolStats = toolStats;
}
@EventHandler
public void onDrop(PlayerDropItemEvent event) {
Player player = event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (toolStats.generateLoot.generatedInventory.isEmpty()) {
return;
}
player.getScheduler().runDelayed(toolStats, scheduledTask -> {
Inventory opened = player.getOpenInventory().getTopInventory();
if (toolStats.generateLoot.generatedInventory.containsKey(opened)) {
Item droppedItemEntity = event.getItemDrop();
ItemStack droppedItem = droppedItemEntity.getItemStack();
if (!toolStats.itemChecker.isValidItem(droppedItem.getType())) {
return;
}
ItemStack newItem = toolStats.inventoryClose.addLootedOrigin(droppedItem, player);
if (newItem != null) {
droppedItemEntity.setItemStack(newItem);
}
}
}, null, 1);
}
}

View File

@@ -57,6 +57,9 @@ public class PlayerFish implements Listener {
} }
Player player = event.getPlayer(); Player player = event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) { if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) {
return; return;
} }
@@ -117,7 +120,7 @@ public class PlayerFish implements Listener {
} }
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.itemOwner, PersistentDataType.LONG)) { if (container.has(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG) || container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
return null; return null;
} }
@@ -132,8 +135,8 @@ public class PlayerFish implements Listener {
// if creation date is enabled, add it // if creation date is enabled, add it
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 5, newItem); Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 5, newItem);
if (creationDate != null) { if (creationDate != null) {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.originType, PersistentDataType.INTEGER, 5); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 5);
lore.add(creationDate); lore.add(creationDate);
meta.lore(lore); meta.lore(lore);
} }
@@ -141,8 +144,8 @@ public class PlayerFish implements Listener {
// if ownership is enabled, add it // if ownership is enabled, add it
Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 5, newItem); Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 5, newItem);
if (itemOwner != null) { if (itemOwner != null) {
container.set(toolStats.itemOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 5); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 5);
lore.add(itemOwner); lore.add(itemOwner);
meta.lore(lore); meta.lore(lore);
} }
@@ -150,7 +153,7 @@ public class PlayerFish implements Listener {
// if hash is enabled, add it // if hash is enabled, add it
if (toolStats.config.getBoolean("generate-hash-for-items")) { if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated); String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated);
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);

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;
@@ -59,13 +62,18 @@ public class PlayerInteract implements Listener {
} }
Player player = event.getPlayer(); Player player = event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) { if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) {
return; return;
} }
// 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 +88,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);
} }
} }

View File

@@ -42,6 +42,9 @@ public class PlayerJoin implements Listener {
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
Inventory inventory = player.getInventory(); Inventory inventory = player.getInventory();
for (ItemStack itemStack : inventory) { for (ItemStack itemStack : inventory) {
@@ -60,42 +63,42 @@ public class PlayerJoin implements Listener {
if (toolStats.config.getBoolean("tokens.enabled")) { if (toolStats.config.getBoolean("tokens.enabled")) {
// if the token system is on and the item doesn't have stat keys // if the token system is on and the item doesn't have stat keys
if (toolStats.itemChecker.keyCheck(container) && !container.has(toolStats.tokenType)) { if (toolStats.itemChecker.keyCheck(container) && !container.has(toolStats.toolStatsKeys.getTokenType())) {
// add the tokens // add the tokens
String newTokens = toolStats.itemChecker.addTokensToExisting(itemStack); String newTokens = toolStats.itemChecker.addTokensToExisting(itemStack);
if (newTokens == null) { if (newTokens == null) {
return; return;
} }
container.set(toolStats.tokenApplied, PersistentDataType.STRING, newTokens); container.set(toolStats.toolStatsKeys.getTokenApplied(), PersistentDataType.STRING, newTokens);
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
} }
} }
// generate a hash if the item doesn't have one // generate a hash if the item doesn't have one
if (toolStats.config.getBoolean("generate-hash-for-items")) { if (toolStats.config.getBoolean("generate-hash-for-items")) {
if (!container.has(toolStats.hash, PersistentDataType.STRING)) { if (!container.has(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING)) {
UUID owner = null; UUID owner = null;
// get the current owner if there is one. // get the current owner if there is one.
if (container.has(toolStats.itemOwner, new UUIDDataType())) { if (container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
owner = container.get(toolStats.itemOwner, new UUIDDataType()); owner = container.get(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType());
} }
// if there is no owner, use the player holding it // if there is no owner, use the player holding it
if (owner == null) { if (owner == null) {
owner = player.getUniqueId(); owner = player.getUniqueId();
} }
Long timestamp = container.get(toolStats.timeCreated, PersistentDataType.LONG); Long timestamp = container.get(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG);
if (timestamp == null) { if (timestamp == null) {
// if there is no time created, use now // if there is no time created, use now
timestamp = System.currentTimeMillis(); timestamp = System.currentTimeMillis();
} }
String hash = toolStats.hashMaker.makeHash(itemStack.getType(), owner, timestamp); String hash = toolStats.hashMaker.makeHash(itemStack.getType(), owner, timestamp);
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
} }
} else { } else {
// if hashes are disabled but the item has one, remove it. // if hashes are disabled but the item has one, remove it.
if (container.has(toolStats.hash, PersistentDataType.STRING)) { if (container.has(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING)) {
container.remove(toolStats.hash); container.remove(toolStats.toolStatsKeys.getHash());
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
} }
} }

View File

@@ -42,6 +42,9 @@ public class PlayerMove implements Listener {
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onMove(PlayerMoveEvent event) { public void onMove(PlayerMoveEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
// player starts to fly // player starts to fly
if (player.isGliding()) { if (player.isGliding()) {
// if they are flying, and we don't have them tracked, add them // if they are flying, and we don't have them tracked, add them

View File

@@ -48,7 +48,7 @@ public class PrepareCraft implements Listener {
} }
// if the paper item has our PDC, cancel it // if the paper item has our PDC, cancel it
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.tokenType)) { if (container.has(toolStats.toolStatsKeys.getTokenType())) {
event.getInventory().setResult(null); event.getInventory().setResult(null);
} }
} }

View File

@@ -0,0 +1,59 @@
/*
* 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 com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.entity.Trident;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
;
public class ProjectileShoot implements Listener {
private final ToolStats toolStats;
public ProjectileShoot(ToolStats toolStats) {
this.toolStats = toolStats;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onProjectileLaunch(PlayerLaunchProjectileEvent event) {
if (!(event.getProjectile() instanceof Trident tridentEntity)) {
return;
}
if (!toolStats.configTools.checkWorld(tridentEntity.getWorld().getName())) {
return;
}
tridentEntity.getScheduler().runDelayed(toolStats, scheduledTask -> {
ItemStack tridentStack = tridentEntity.getItemStack();
ItemMeta newTridentMeta = toolStats.itemLore.updateTridentThrows(tridentStack, 1);
if (newTridentMeta == null) {
return;
}
tridentStack.setItemMeta(newTridentMeta);
tridentEntity.setItemStack(tridentStack);
}, null, 1);
}
}

View File

@@ -45,6 +45,9 @@ public class SheepShear implements Listener {
return; return;
} }
Player player = event.getPlayer(); Player player = event.getPlayer();
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) { if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) {
return; return;
} }

View File

@@ -46,6 +46,9 @@ public class ShootBow implements Listener {
return; return;
} }
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) { if (player.getGameMode() == GameMode.CREATIVE && !toolStats.config.getBoolean("allow-creative")) {
return; return;
} }

View File

@@ -56,6 +56,9 @@ public class VillagerTrade implements Listener {
if (!(event.getWhoClicked() instanceof Player player)) { if (!(event.getWhoClicked() instanceof Player player)) {
return; return;
} }
if (!toolStats.configTools.checkWorld(player.getWorld().getName())) {
return;
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return; return;
} }
@@ -134,7 +137,7 @@ public class VillagerTrade implements Listener {
} }
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.itemOwner, PersistentDataType.LONG)) { if (container.has(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG) || container.has(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType())) {
return null; return null;
} }
@@ -150,8 +153,8 @@ public class VillagerTrade implements Listener {
// if creation date is enabled, add it // if creation date is enabled, add it
Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 3, newItem); Component creationDate = toolStats.itemLore.formatCreationTime(timeCreated, 3, newItem);
if (creationDate != null) { if (creationDate != null) {
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated); container.set(toolStats.toolStatsKeys.getTimeCreated(), PersistentDataType.LONG, timeCreated);
container.set(toolStats.originType, PersistentDataType.INTEGER, 3); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 3);
lore.add(creationDate); lore.add(creationDate);
meta.lore(lore); meta.lore(lore);
} }
@@ -159,8 +162,8 @@ public class VillagerTrade implements Listener {
// if ownership is enabled, add it // if ownership is enabled, add it
Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 3, newItem); Component itemOwner = toolStats.itemLore.formatOwner(owner.getName(), 3, newItem);
if (itemOwner != null) { if (itemOwner != null) {
container.set(toolStats.itemOwner, new UUIDDataType(), owner.getUniqueId()); container.set(toolStats.toolStatsKeys.getItemOwner(), new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 3); container.set(toolStats.toolStatsKeys.getOriginType(), PersistentDataType.INTEGER, 3);
lore.add(itemOwner); lore.add(itemOwner);
meta.lore(lore); meta.lore(lore);
} }
@@ -168,7 +171,7 @@ public class VillagerTrade implements Listener {
// if hash is enabled, add it // if hash is enabled, add it
if (toolStats.config.getBoolean("generate-hash-for-items")) { if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated); String hash = toolStats.hashMaker.makeHash(newItem.getType(), owner.getUniqueId(), timeCreated);
container.set(toolStats.hash, PersistentDataType.STRING, hash); container.set(toolStats.toolStatsKeys.getHash(), PersistentDataType.STRING, hash);
} }
newItem.setItemMeta(meta); newItem.setItemMeta(meta);

View File

@@ -52,7 +52,7 @@ public class ItemChecker {
mineItems.add(material); mineItems.add(material);
} }
if (lowerCase.contains("_sword") || lowerCase.contains("_axe")) { if (lowerCase.contains("_sword") || lowerCase.contains("_axe") || lowerCase.contains("_spear")) {
meleeItems.add(material); meleeItems.add(material);
} }
@@ -70,6 +70,7 @@ public class ItemChecker {
validItems.add(Material.CROSSBOW); validItems.add(Material.CROSSBOW);
validItems.add(Material.FISHING_ROD); validItems.add(Material.FISHING_ROD);
validItems.add(Material.ELYTRA); validItems.add(Material.ELYTRA);
validItems.add(Material.SHIELD);
// combine the lists // combine the lists
validItems.addAll(armorItems); validItems.addAll(armorItems);
@@ -142,12 +143,12 @@ public class ItemChecker {
*/ */
public boolean checkTokens(PersistentDataContainer container, String targetToken) { public boolean checkTokens(PersistentDataContainer container, String targetToken) {
// make sure the item has tokens // make sure the item has tokens
if (!container.has(toolStats.tokenApplied, PersistentDataType.STRING)) { if (!container.has(toolStats.toolStatsKeys.getTokenApplied(), PersistentDataType.STRING)) {
return false; return false;
} }
// get the tokens for this item // get the tokens for this item
String tokens = container.get(toolStats.tokenApplied, PersistentDataType.STRING); String tokens = container.get(toolStats.toolStatsKeys.getTokenApplied(), PersistentDataType.STRING);
if (tokens == null) { if (tokens == null) {
return false; return false;
} }
@@ -168,12 +169,12 @@ public class ItemChecker {
return new String[0]; return new String[0];
} }
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
if (!container.has(toolStats.tokenApplied, PersistentDataType.STRING)) { if (!container.has(toolStats.toolStatsKeys.getTokenApplied(), PersistentDataType.STRING)) {
return new String[0]; return new String[0];
} }
// get the tokens for this item // get the tokens for this item
String tokensRaw = container.get(toolStats.tokenApplied, PersistentDataType.STRING); String tokensRaw = container.get(toolStats.toolStatsKeys.getTokenApplied(), PersistentDataType.STRING);
if (tokensRaw == null) { if (tokensRaw == null) {
return new String[0]; return new String[0];
} }
@@ -197,12 +198,12 @@ public class ItemChecker {
String[] tokens = getTokens(item); String[] tokens = getTokens(item);
// there are no tokens // there are no tokens
if (tokens.length == 0) { if (tokens.length == 0) {
container.set(toolStats.tokenApplied, PersistentDataType.STRING, token); container.set(toolStats.toolStatsKeys.getTokenApplied(), PersistentDataType.STRING, token);
} else { } else {
// other tokens exist, so add // other tokens exist, so add
String[] newTokens = Arrays.copyOf(tokens, tokens.length + 1); String[] newTokens = Arrays.copyOf(tokens, tokens.length + 1);
newTokens[tokens.length] = token; newTokens[tokens.length] = token;
container.set(toolStats.tokenApplied, PersistentDataType.STRING, String.join(",", newTokens)); container.set(toolStats.toolStatsKeys.getTokenApplied(), PersistentDataType.STRING, String.join(",", newTokens));
} }
item.setItemMeta(meta); item.setItemMeta(meta);
return item; return item;
@@ -320,36 +321,48 @@ public class ItemChecker {
} }
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
ArrayList<String> tokens = new ArrayList<>(); ArrayList<String> tokens = new ArrayList<>();
if (container.has(toolStats.playerKills)) { if (container.has(toolStats.toolStatsKeys.getPlayerKills())) {
tokens.add("player-kills"); tokens.add("player-kills");
} }
if (container.has(toolStats.mobKills)) { if (container.has(toolStats.toolStatsKeys.getMobKills())) {
tokens.add("mob-kills"); tokens.add("mob-kills");
} }
if (container.has(toolStats.blocksMined)) { if (container.has(toolStats.toolStatsKeys.getBlocksMined())) {
tokens.add("blocks-mined"); tokens.add("blocks-mined");
} }
if (container.has(toolStats.cropsHarvested)) { if (container.has(toolStats.toolStatsKeys.getCropsHarvested())) {
tokens.add("crops-mined"); tokens.add("crops-mined");
} }
if (container.has(toolStats.fishCaught)) { if (container.has(toolStats.toolStatsKeys.getFishCaught())) {
tokens.add("fish-caught"); tokens.add("fish-caught");
} }
if (container.has(toolStats.sheepSheared)) { if (container.has(toolStats.toolStatsKeys.getSheepSheared())) {
tokens.add("sheep-sheared"); tokens.add("sheep-sheared");
} }
if (container.has(toolStats.armorDamage)) { if (container.has(toolStats.toolStatsKeys.getArmorDamage())) {
tokens.add("damage-taken"); tokens.add("damage-taken");
} }
if (container.has(toolStats.arrowsShot)) { if (container.has(toolStats.toolStatsKeys.getArrowsShot())) {
tokens.add("arrows-shot"); tokens.add("arrows-shot");
} }
if (container.has(toolStats.flightTime)) { if (container.has(toolStats.toolStatsKeys.getFlightTime())) {
tokens.add("flight-time"); tokens.add("flight-time");
} }
if (container.has(toolStats.damageDone)) { if (container.has(toolStats.toolStatsKeys.getDamageDone())) {
tokens.add("damage-done"); tokens.add("damage-done");
} }
if (container.has(toolStats.toolStatsKeys.getWitherKills())) {
tokens.add("wither-kills");
}
if (container.has(toolStats.toolStatsKeys.getEnderDragonKills())) {
tokens.add("enderdragon-kills");
}
if (container.has(toolStats.toolStatsKeys.getCriticalStrikes())) {
tokens.add("critical-strikes");
}
if (container.has(toolStats.toolStatsKeys.getTridentThrows())) {
tokens.add("trident-throws");
}
if (tokens.isEmpty()) { if (tokens.isEmpty()) {
return null; return null;
} }
@@ -386,6 +399,6 @@ public class ItemChecker {
public boolean keyCheck(PersistentDataContainer container) { public boolean keyCheck(PersistentDataContainer container) {
return container.getKeys().stream() return container.getKeys().stream()
.map(NamespacedKey::getKey) .map(NamespacedKey::getKey)
.anyMatch(key -> toolStats.tokenKeys.stream().anyMatch(tokenKey -> tokenKey.getKey().equalsIgnoreCase(key))); .anyMatch(key -> toolStats.toolStatsKeys.getTokenKeys().stream().anyMatch(tokenKey -> tokenKey.getKey().equalsIgnoreCase(key)));
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -125,6 +125,34 @@ public class TokenData {
removeRecipe.setIngredient('P', Material.PAPER); removeRecipe.setIngredient('P', Material.PAPER);
recipes.add(removeRecipe); recipes.add(removeRecipe);
NamespacedKey witherKillsKey = new NamespacedKey(toolStats, "wither-kills-token");
ShapedRecipe witherKillsRecipe = new ShapedRecipe(witherKillsKey, createToken("wither-kills"));
witherKillsRecipe.shape(" P ", "PWP", " P ");
witherKillsRecipe.setIngredient('P', Material.PAPER);
witherKillsRecipe.setIngredient('W', Material.WITHER_ROSE);
recipes.add(witherKillsRecipe);
NamespacedKey enderDragonKillsKey = new NamespacedKey(toolStats, "enderdragon-kills-token");
ShapedRecipe enderDragonKillsRecipe = new ShapedRecipe(enderDragonKillsKey, createToken("enderdragon-kills"));
enderDragonKillsRecipe.shape(" P ", "PEP", " P ");
enderDragonKillsRecipe.setIngredient('P', Material.PAPER);
enderDragonKillsRecipe.setIngredient('E', Material.ENDER_PEARL);
recipes.add(enderDragonKillsRecipe);
NamespacedKey criticalStrikesKey = new NamespacedKey(toolStats, "critical-strikes-token");
ShapedRecipe criticalStrikesRecipe = new ShapedRecipe(criticalStrikesKey, createToken("critical-strikes"));
criticalStrikesRecipe.shape(" P ", "PSP", " P ");
criticalStrikesRecipe.setIngredient('P', Material.PAPER);
criticalStrikesRecipe.setIngredient('S', Material.GOLDEN_SWORD);
recipes.add(criticalStrikesRecipe);
NamespacedKey tridentThrowsKey = new NamespacedKey(toolStats, "trident-throws-token");
ShapedRecipe tridentThrowsRecipe = new ShapedRecipe(tridentThrowsKey, createToken("trident-throws"));
tridentThrowsRecipe.shape(" P ", "PSP", " P ");
tridentThrowsRecipe.setIngredient('P', Material.PAPER);
tridentThrowsRecipe.setIngredient('S', Material.PRISMARINE_SHARD);
recipes.add(tridentThrowsRecipe);
tokenTypes.add("crops-mined"); tokenTypes.add("crops-mined");
tokenTypes.add("blocks-mined"); tokenTypes.add("blocks-mined");
tokenTypes.add("damage-taken"); tokenTypes.add("damage-taken");
@@ -137,6 +165,10 @@ public class TokenData {
tokenTypes.add("fish-caught"); tokenTypes.add("fish-caught");
tokenTypes.add("reset"); tokenTypes.add("reset");
tokenTypes.add("remove"); tokenTypes.add("remove");
tokenTypes.add("wither-kills");
tokenTypes.add("enderdragon-kills");
tokenTypes.add("critical-strikes");
tokenTypes.add("trident-throws");
} }
public Set<ShapedRecipe> getRecipes() { public Set<ShapedRecipe> getRecipes() {
@@ -177,7 +209,7 @@ public class TokenData {
tokenMeta.lore(lore); tokenMeta.lore(lore);
// set the PDC // set the PDC
tokenData.set(toolStats.tokenType, PersistentDataType.STRING, tokenType); tokenData.set(toolStats.toolStatsKeys.getTokenType(), PersistentDataType.STRING, tokenType);
token.setItemMeta(tokenMeta); token.setItemMeta(tokenMeta);
// set the custom model data // set the custom model data

View File

@@ -0,0 +1,182 @@
package lol.hyper.toolstats.tools;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.NamespacedKey;
import java.util.HashSet;
import java.util.Set;
public class ToolStatsKeys {
private final ToolStats toolStats;
private final Set<NamespacedKey> tokenKeys = new HashSet<>();
public ToolStatsKeys(ToolStats toolStats) {
this.toolStats = toolStats;
}
private NamespacedKey itemOwner;
private NamespacedKey timeCreated;
private NamespacedKey playerKills;
private NamespacedKey mobKills;
private NamespacedKey blocksMined;
private NamespacedKey cropsHarvested;
private NamespacedKey fishCaught;
private NamespacedKey sheepSheared;
private NamespacedKey armorDamage;
private NamespacedKey damageDone;
private NamespacedKey newElytra;
private NamespacedKey hash;
private NamespacedKey arrowsShot;
private NamespacedKey droppedBy;
private NamespacedKey flightTime;
private NamespacedKey tokenType;
private NamespacedKey tokenApplied;
private NamespacedKey witherKills;
private NamespacedKey enderDragonKills;
private NamespacedKey criticalStrikes;
private NamespacedKey tridentThrows;
private NamespacedKey originType;
public void make() {
itemOwner = new NamespacedKey(toolStats, "owner");
timeCreated = new NamespacedKey(toolStats, "time-created");
playerKills = new NamespacedKey(toolStats, "player-kills");
mobKills = new NamespacedKey(toolStats, "mob-kills");
blocksMined = new NamespacedKey(toolStats, "generic-mined");
cropsHarvested = new NamespacedKey(toolStats, "crops-mined");
fishCaught = new NamespacedKey(toolStats, "fish-caught");
sheepSheared = new NamespacedKey(toolStats, "sheared");
armorDamage = new NamespacedKey(toolStats, "damage-taken");
damageDone = new NamespacedKey(toolStats, "damage-done");
newElytra = new NamespacedKey(toolStats, "new");
hash = new NamespacedKey(toolStats, "hash");
arrowsShot = new NamespacedKey(toolStats, "arrows-shot");
droppedBy = new NamespacedKey(toolStats, "dropped-by");
flightTime = new NamespacedKey(toolStats, "flightTime");
tokenType = new NamespacedKey(toolStats, "token-type");
tokenApplied = new NamespacedKey(toolStats, "token-applied");
witherKills = new NamespacedKey(toolStats, "wither-kills");
enderDragonKills = new NamespacedKey(toolStats, "enderdragon-kills");
criticalStrikes = new NamespacedKey(toolStats, "critical-strikes");
tridentThrows = new NamespacedKey(toolStats, "trident-throws");
originType = new NamespacedKey(toolStats, "origin");
// save which stat can be used by a reset token
tokenKeys.add(blocksMined);
tokenKeys.add(playerKills);
tokenKeys.add(mobKills);
tokenKeys.add(cropsHarvested);
tokenKeys.add(sheepSheared);
tokenKeys.add(fishCaught);
tokenKeys.add(flightTime);
tokenKeys.add(arrowsShot);
tokenKeys.add(armorDamage);
tokenKeys.add(witherKills);
tokenKeys.add(enderDragonKills);
tokenKeys.add(criticalStrikes);
tokenKeys.add(tridentThrows);
}
public NamespacedKey getItemOwner() {
return itemOwner;
}
public NamespacedKey getTimeCreated() {
return timeCreated;
}
public NamespacedKey getPlayerKills() {
return playerKills;
}
public NamespacedKey getMobKills() {
return mobKills;
}
public NamespacedKey getBlocksMined() {
return blocksMined;
}
public NamespacedKey getCropsHarvested() {
return cropsHarvested;
}
public NamespacedKey getFishCaught() {
return fishCaught;
}
public NamespacedKey getSheepSheared() {
return sheepSheared;
}
public NamespacedKey getArmorDamage() {
return armorDamage;
}
public NamespacedKey getDamageDone() {
return damageDone;
}
public NamespacedKey getElytraKey() {
return newElytra;
}
public NamespacedKey getHash() {
return hash;
}
public NamespacedKey getArrowsShot() {
return arrowsShot;
}
public NamespacedKey getDroppedBy() {
return droppedBy;
}
public NamespacedKey getFlightTime() {
return flightTime;
}
public NamespacedKey getTokenType() {
return tokenType;
}
public NamespacedKey getTokenApplied() {
return tokenApplied;
}
public NamespacedKey getWitherKills() {
return witherKills;
}
public NamespacedKey getEnderDragonKills() {
return enderDragonKills;
}
public NamespacedKey getCriticalStrikes() {
return criticalStrikes;
}
public NamespacedKey getTridentThrows() {
return tridentThrows;
}
/**
* Stores how an item was created.
* 0 = crafted.
* 1 = dropped.
* 2 = looted.
* 3 = traded.
* 4 = founded (for elytras).
* 5 = fished.
* 6 = spawned in (creative).
*/
public NamespacedKey getOriginType() {
return originType;
}
public Set<NamespacedKey> getTokenKeys() {
return tokenKeys;
}
}

View File

@@ -87,12 +87,54 @@ public class ConfigTools {
case "trident" -> toolStats.config.getBoolean("enabled." + configName + ".trident"); case "trident" -> toolStats.config.getBoolean("enabled." + configName + ".trident");
case "fishing-rod" -> toolStats.config.getBoolean("enabled." + configName + ".fishing-rod"); case "fishing-rod" -> toolStats.config.getBoolean("enabled." + configName + ".fishing-rod");
case "mace" -> toolStats.config.getBoolean("enabled." + configName + ".mace"); case "mace" -> toolStats.config.getBoolean("enabled." + configName + ".mace");
case "spear" -> toolStats.config.getBoolean("enabled." + configName + ".spear");
case "helmet", "chestplate", "leggings", "boots" -> case "helmet", "chestplate", "leggings", "boots" ->
toolStats.config.getBoolean("enabled." + configName + ".armor"); toolStats.config.getBoolean("enabled." + configName + ".armor");
default -> false; default -> false;
}; };
} }
/**
* Check the status of a world from the config.
*
* @param worldName The world to check.
* @return True if we can work in this world, false if not.
*/
public boolean checkWorld(String worldName) {
boolean enabled = toolStats.config.getBoolean("world-limit.enabled");
// if the system is disabled, all worlds are allowed
if (!enabled) {
return true;
}
String mode = toolStats.config.getString("world-limit.mode");
if (mode == null) {
toolStats.logger.info("world-limit.mode is not set, not allowing any worlds by default.");
return false;
}
List<String> worlds = toolStats.config.getStringList("world-limit.worlds");
// if no worlds are defined, deny them
if (worlds.isEmpty()) {
return false;
}
if (mode.equalsIgnoreCase("blacklist")) {
// this world is on list and mode = blacklisted
// don't allow this world, allow others not on list
return !worlds.contains(worldName);
}
if (mode.equalsIgnoreCase("whitelist")) {
// this world is on list and mode = whitelisted
// allow it. if the world is not on list, don't allow it
return worlds.contains(worldName);
}
toolStats.logger.warn("Unknown worlds.mode '{}', denying by default.", mode);
return false;
}
/** /**
* Format a string to be ready for lore usage. * Format a string to be ready for lore usage.
* *

View File

@@ -40,6 +40,8 @@ public class ConfigUpdater {
case 10 -> new Version11(toolStats).update(); // 10 to 11 case 10 -> new Version11(toolStats).update(); // 10 to 11
case 11 -> new Version12(toolStats).update(); // 11 to 12 case 11 -> new Version12(toolStats).update(); // 11 to 12
case 12 -> new Version13(toolStats).update(); // 12 to 13 case 12 -> new Version13(toolStats).update(); // 12 to 13
case 13 -> new Version14(toolStats).update(); // 13 to 14
case 14 -> new Version15(toolStats).update(); // 14 to 15
} }
} }
} }

View File

@@ -0,0 +1,88 @@
/*
* 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 Version14 {
private final ToolStats toolStats;
/**
* Used for updating from version 13 to 14.
*
* @param toolStats ToolStats instance.
*/
public Version14(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-13.yml");
} catch (IOException exception) {
toolStats.logger.error("Unable to save config-13.yml!", exception);
}
toolStats.logger.info("Updating config.yml to version 14.");
toolStats.config.set("config-version", 14);
// add spear to sections to be a toggle
toolStats.config.set("enabled.crafted-by.spear", true);
toolStats.logger.info("Adding enabled.crafted-by.spear");
toolStats.config.set("enabled.crafted-on.spear", true);
toolStats.logger.info("Adding enabled.crafted-on.spear");
toolStats.config.set("enabled.looted-by.spear", true);
toolStats.logger.info("Adding enabled.looted-by.spear");
toolStats.config.set("enabled.looted-on.spear", true);
toolStats.logger.info("Adding enabled.looted-on.spear");
toolStats.config.set("enabled.damage-done.spear", true);
toolStats.logger.info("Adding enabled.damage-done.spear");
toolStats.config.set("enabled.player-kills.spear", true);
toolStats.logger.info("Adding enabled.player-kills.spear");
toolStats.config.set("enabled.mob-kills.spear", true);
toolStats.logger.info("Adding enabled.mob-kills.spear");
toolStats.config.set("enabled.spawned-in-by.spear", true);
toolStats.logger.info("Adding enabled.spawned-in-by.spear");
toolStats.config.set("enabled.spawned-in-on.spear", true);
toolStats.logger.info("Adding enabled.spawned-in-on.spear");
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 14. A copy of version 13 has been saved as config-13.yml");
}
}

View File

@@ -0,0 +1,147 @@
/*
* 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 org.bukkit.configuration.ConfigurationSection;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Version15 {
private final ToolStats toolStats;
/**
* Used for updating from version 14 to 15.
*
* @param toolStats ToolStats instance.
*/
public Version15(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-14.yml");
} catch (IOException exception) {
toolStats.logger.error("Unable to save config-14.yml!", exception);
}
toolStats.logger.info("Updating config.yml to version 15.");
toolStats.config.set("config-version", 15);
// wither kills token
toolStats.logger.info("Adding new token to config: wither-kills");
toolStats.config.set("tokens.data.wither-kills.title", "&7ToolStats: &8Wither Kills Token");
toolStats.config.set("tokens.data.wither-kills.lore", List.of(
"&8Combine with a melee or ranged weapon in an anvil to track wither kills.",
"&8Uses &7{levels} &8level."
));
toolStats.config.set("tokens.data.wither-kills.levels", 1);
toolStats.config.set("tokens.data.wither-kills.material", "PAPER");
toolStats.config.set("tokens.data.wither-kills.custom-model-data.enabled", false);
toolStats.config.set("tokens.data.wither-kills.custom-model-data.type", "float");
toolStats.config.set("tokens.data.wither-kills.custom-model-data.value", 1001);
// ender dragon kills token
toolStats.logger.info("Adding new token to config: enderdragon-kills");
toolStats.config.set("tokens.data.enderdragon-kills.title", "&7ToolStats: &8Ender Dragon Kills Token");
toolStats.config.set("tokens.data.enderdragon-kills.lore", List.of(
"&8Combine with a melee or ranged weapon in an anvil to track Ender Dragon kills.",
"&8Uses &7{levels} &8level."
));
toolStats.config.set("tokens.data.enderdragon-kills.levels", 1);
toolStats.config.set("tokens.data.enderdragon-kills.material", "PAPER");
toolStats.config.set("tokens.data.enderdragon-kills.custom-model-data.enabled", false);
toolStats.config.set("tokens.data.enderdragon-kills.custom-model-data.type", "float");
toolStats.config.set("tokens.data.enderdragon-kills.custom-model-data.value", 1001);
// critical strikes token
toolStats.logger.info("Adding new token to config: critical-strikes");
toolStats.config.set("tokens.data.critical-strikes.title", "&7ToolStats: &8Critical Strikes Token");
toolStats.config.set("tokens.data.critical-strikes.lore", List.of(
"&8Combine with a melee or ranged weapon in an anvil to track critical strikes.",
"&8Uses &7{levels} &8level."
));
toolStats.config.set("tokens.data.critical-strikes.levels", 1);
toolStats.config.set("tokens.data.critical-strikes.material", "PAPER");
toolStats.config.set("tokens.data.critical-strikes.custom-model-data.enabled", false);
toolStats.config.set("tokens.data.critical-strikes.custom-model-data.type", "float");
toolStats.config.set("tokens.data.critical-strikes.custom-model-data.value", 1001);
// trident throws token
toolStats.logger.info("Adding new token to config: trident-throws");
toolStats.config.set("tokens.data.trident-throws.title", "&7ToolStats: &8Trident Throws Token");
toolStats.config.set("tokens.data.trident-throws.lore", List.of(
"&8Combine with a trident in an anvil to track times thrown.",
"&8Uses &7{levels} &8level."
));
toolStats.config.set("tokens.data.trident-throws.levels", 1);
toolStats.config.set("tokens.data.trident-throws.material", "PAPER");
toolStats.config.set("tokens.data.trident-throws.custom-model-data.enabled", false);
toolStats.config.set("tokens.data.trident-throws.custom-model-data.type", "float");
toolStats.config.set("tokens.data.trident-throws.custom-model-data.value", 1001);
// bosses-killed stuff
toolStats.logger.info("Adding enabled.bosses-killed.wither");
toolStats.config.set("enabled.bosses-killed.wither", true);
toolStats.logger.info("Adding enabled.bosses-killed.enderdragon");
toolStats.config.set("enabled.bosses-killed.enderdragon", true);
// critical strikes
toolStats.config.set("enabled.critical-strikes", true);
toolStats.logger.info("Adding enabled.critical-strikes");
//trident throws
toolStats.config.set("enabled.trident-throws", true);
toolStats.logger.info("Adding enabled.trident-throws");
// default for new stats
toolStats.logger.info("Adding new default messages");
toolStats.config.set("messages.bosses-killed.wither", "&7Withers killed: &8{kills}");
toolStats.config.set("messages.bosses-killed.enderdragon", "&7Ender Dragons killed: &8{kills}");
toolStats.config.set("messages.critical-strikes", "&7Critical strikes: &8{strikes}");
toolStats.config.set("messages.trident-throws", "&7Times thrown: &8{times}");
// blacklist feature
toolStats.logger.info("Adding new world-limit feature, which is disabled by default");
List<String> worlds = Arrays.asList("world_1", "world_2");
toolStats.config.set("world-limit.enabled", false);
toolStats.config.set("world-limit.mode", "blacklist");
toolStats.config.set("world-limit.worlds", worlds);
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 15. A copy of version 14 has been saved as config-14.yml");
}
}

View File

@@ -136,6 +136,50 @@ tokens:
enabled: false enabled: false
type: float type: float
value: 1001 value: 1001
wither-kills:
title: "&7ToolStats: &8Wither Kills Token"
lore:
- "&8Combine with a melee or ranged weapon in an anvil to track wither kills."
- "&8Uses &7{levels} &8level."
levels: 1
material: PAPER
custom-model-data:
enabled: false
type: float
value: 1001
enderdragon-kills:
title: "&7ToolStats: &8Ender Dragon Kills Token"
lore:
- "&8Combine with a melee or ranged weapon in an anvil to track Ender Dragon kills."
- "&8Uses &7{levels} &8level."
levels: 1
material: PAPER
custom-model-data:
enabled: false
type: float
value: 1001
critical-strikes:
title: "&7ToolStats: &8Critical Strikes Token"
lore:
- "&8Combine with a melee or ranged weapon in an anvil to track critical strikes."
- "&8Uses &7{levels} &8level."
levels: 1
material: PAPER
custom-model-data:
enabled: false
type: float
value: 1001
trident-throws:
title: "&7ToolStats: &8Trident Throws Token"
lore:
- "&8Combine with a trident in an anvil to track times thrown."
- "&8Uses &7{levels} &8level."
levels: 1
material: PAPER
custom-model-data:
enabled: false
type: float
value: 1001
enabled: enabled:
# Will show "Crafted by <player>" # Will show "Crafted by <player>"
@@ -150,6 +194,7 @@ enabled:
armor: true armor: true
mace: true mace: true
fishing-rod: true fishing-rod: true
spear: true
# Will show "Crafted on <date>" # Will show "Crafted on <date>"
crafted-on: crafted-on:
pickaxe: true pickaxe: true
@@ -162,6 +207,7 @@ enabled:
armor: true armor: true
mace: true mace: true
fishing-rod: true fishing-rod: true
spear: true
# Will show "Fished by <player>" # Will show "Fished by <player>"
fished-by: fished-by:
pickaxe: true pickaxe: true
@@ -195,6 +241,7 @@ enabled:
bow: true bow: true
armor: true armor: true
fishing-rod: true fishing-rod: true
spear: true
# Will show "Found on <date>" # Will show "Found on <date>"
looted-on: looted-on:
pickaxe: true pickaxe: true
@@ -206,6 +253,7 @@ enabled:
bow: true bow: true
armor: true armor: true
fishing-rod: true fishing-rod: true
spear: true
# Will show "Traded by <player>" # Will show "Traded by <player>"
traded-by: traded-by:
pickaxe: true pickaxe: true
@@ -234,18 +282,21 @@ enabled:
trident: true trident: true
bow: true bow: true
mace: true mace: true
spear: true
player-kills: player-kills:
sword: true sword: true
axe: true axe: true
trident: true trident: true
bow: true bow: true
mace: true mace: true
spear: true
mob-kills: mob-kills:
sword: true sword: true
axe: true axe: true
trident: true trident: true
bow: true bow: true
mace: true mace: true
spear: true
blocks-mined: blocks-mined:
pickaxe: true pickaxe: true
shovel: true shovel: true
@@ -264,6 +315,7 @@ enabled:
armor: true armor: true
mace: true mace: true
fishing-rod: true fishing-rod: true
spear: true
# Will show "Spawned in on <date>" # Will show "Spawned in on <date>"
spawned-in-on: spawned-in-on:
pickaxe: true pickaxe: true
@@ -276,6 +328,10 @@ enabled:
armor: true armor: true
mace: true mace: true
fishing-rod: true fishing-rod: true
spear: true
bosses-killed:
wither: true
enderdragon: true
fish-caught: true fish-caught: true
sheep-sheared: true sheep-sheared: true
armor-damage: true armor-damage: true
@@ -285,6 +341,8 @@ enabled:
arrows-shot: true arrows-shot: true
flight-time: true flight-time: true
crops-harvested: true crops-harvested: true
critical-strikes: true
trident-throws: true
messages: messages:
crafted: crafted:
@@ -308,6 +366,9 @@ messages:
spawned-in: spawned-in:
spawned-by: "&7Spawned in by: &8{player}" spawned-by: "&7Spawned in by: &8{player}"
spawned-on: "&7Spawned on: &8{date}" spawned-on: "&7Spawned on: &8{date}"
bosses-killed:
wither: "&7Withers killed: &8{kills}"
enderdragon: "&7Ender Dragons killed: &8{kills}"
blocks-mined: "&7Blocks mined: &8{blocks}" blocks-mined: "&7Blocks mined: &8{blocks}"
crops-harvested: "&7Crops harvested: &8{crops}" crops-harvested: "&7Crops harvested: &8{crops}"
sheep-sheared: "&7Sheep sheared: &8{sheep}" sheep-sheared: "&7Sheep sheared: &8{sheep}"
@@ -317,6 +378,8 @@ messages:
arrows-shot: "&7Arrows shot: &8{arrows}" arrows-shot: "&7Arrows shot: &8{arrows}"
flight-time: "&7Flight time: &8{years}y {months}m {days}d {hours}h {minutes}m {seconds}s" flight-time: "&7Flight time: &8{years}y {months}m {days}d {hours}h {minutes}m {seconds}s"
damage-done: "&7Damage done: &8{damage}" damage-done: "&7Damage done: &8{damage}"
critical-strikes: "&7Critical strikes: &8{strikes}"
trident-throws: "&7Times thrown: &8{times}"
# 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"
@@ -346,4 +409,13 @@ normalize-time-creation: false
# Allows stats and origins to be tracked if the player is in creative mode. # Allows stats and origins to be tracked if the player is in creative mode.
allow-creative: false allow-creative: false
config-version: 13 # Allows you to change what worlds ToolStats works in.
# Mode is blacklist or whitelist.
world-limit:
enabled: false
mode: "blacklist"
worlds:
- world_1
- world_2
config-version: 15

View File

@@ -1,34 +1,26 @@
name: ToolStats name: ToolStats
version: '${project.version}' version: ${project.version}
main: lol.hyper.toolstats.ToolStats main: lol.hyper.toolstats.ToolStats
api-version: 1.21 api-version: 1.21
folia-supported: true
author: hyperdefined author: hyperdefined
description: Track various tool stats! description: Track various tool stats!
website: https://github.com/hyperdefined/ToolStats website: https://github.com/hyperdefined/ToolStats
folia-supported: true
commands: loader: lol.hyper.toolstats.ToolStatsLoader
toolstats:
usage: /toolstats
permission: toolstats.command
permissions: permissions:
toolstats.command: toolstats.command:
description: Allows the usage of /toolstats. description: Allows the usage of /toolstats.
default: true default: true
children:
toolstats.reset: true
toolstats.reset.confirm: true
toolstats.purge: true
toolstats.purge.confirm: true
toolstats.reload: toolstats.reload:
description: Allows the usage of /toolstats reload. description: Allows the usage of /toolstats reload.
default: op default: op
toolstats.reset:
description: Allows the usage of /toolstats reset.
default: true
toolstats.reset.confirm:
description: Allows the usage of /toolstats reset confirm.
default: true
toolstats.purge:
description: Allows the usage of /toolstats purge.
default: true
toolstats.purge.confirm:
description: Allows the usage of /toolstats purge confirm.
default: true
toolstats.givetokens: toolstats.givetokens:
description: Allows the usage of /toolstats givetoken. description: Allows the usage of /toolstats givetoken.
default: op default: op