mirror of
https://github.com/hyperdefined/ToolStats.git
synced 2025-12-05 22:31:45 +00:00
added base files (NOT DONE)
This commit is contained in:
113
.gitignore
vendored
Normal file
113
.gitignore
vendored
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# User-specific stuff
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
target/
|
||||||
|
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
.flattened-pom.xml
|
||||||
|
|
||||||
|
# Common working directory
|
||||||
|
run/
|
||||||
10
README.md
Normal file
10
README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# ToolStats
|
||||||
|
|
||||||
|
A simple plugin to track cool stats for your tools and armor!
|
||||||
|
|
||||||
|
## Todo
|
||||||
|
* Track trident throw kills.
|
||||||
|
* Track armor damage.
|
||||||
|
* Track fish caught.
|
||||||
|
* Track sheep sheared.
|
||||||
|
* Properly handle combing of tools. Stats should combine together.
|
||||||
108
pom.xml
Normal file
108
pom.xml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>lol.hyper</groupId>
|
||||||
|
<artifactId>toolstats</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>ToolStats</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>auto-clean</id>
|
||||||
|
<phase>initialize</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>clean</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.2.4</version>
|
||||||
|
<configuration>
|
||||||
|
<relocations>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.bstats</pattern>
|
||||||
|
<shadedPattern>lol.hyper.toolstats.bstats</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
</relocations>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>spigotmc-repo</id>
|
||||||
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot-api</artifactId>
|
||||||
|
<version>1.18.1-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains</groupId>
|
||||||
|
<artifactId>annotations</artifactId>
|
||||||
|
<version>23.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bstats</groupId>
|
||||||
|
<artifactId>bstats-bukkit</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>lol.hyper</groupId>
|
||||||
|
<artifactId>github-release-api</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
80
src/main/java/lol/hyper/toolstats/ToolStats.java
Normal file
80
src/main/java/lol/hyper/toolstats/ToolStats.java
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package lol.hyper.toolstats;
|
||||||
|
|
||||||
|
import lol.hyper.githubreleaseapi.GitHubRelease;
|
||||||
|
import lol.hyper.githubreleaseapi.GitHubReleaseAPI;
|
||||||
|
import lol.hyper.toolstats.events.BlocksMined;
|
||||||
|
import lol.hyper.toolstats.events.CraftItem;
|
||||||
|
import lol.hyper.toolstats.events.EntityDeath;
|
||||||
|
import lol.hyper.toolstats.events.MobKill;
|
||||||
|
import org.bstats.bukkit.Metrics;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public final class ToolStats extends JavaPlugin {
|
||||||
|
|
||||||
|
// stores who crafted an item
|
||||||
|
public final NamespacedKey craftedOwner = new NamespacedKey(this, "owner");
|
||||||
|
// stores when an item was crafted
|
||||||
|
public final NamespacedKey craftedTime = new NamespacedKey(this, "time-created");
|
||||||
|
// stores how many player kills by sword
|
||||||
|
public final NamespacedKey swordPlayerKills = new NamespacedKey(this, "player-kills");
|
||||||
|
// stores how many mob kills by sword
|
||||||
|
public final NamespacedKey swordMobKills = new NamespacedKey(this, "mob-kills");
|
||||||
|
// stores how blocks mined (used for all tools)
|
||||||
|
public final NamespacedKey genericMined = new NamespacedKey(this, "generic-mined");
|
||||||
|
// stores how many fish were caught
|
||||||
|
public final NamespacedKey fishingRodCaught = new NamespacedKey(this, "fish-caught");
|
||||||
|
// stores how many times sheep were sheared
|
||||||
|
public final NamespacedKey shearsSheared = new NamespacedKey(this, "sheared");
|
||||||
|
|
||||||
|
public BlocksMined blocksMined;
|
||||||
|
public CraftItem craftItem;
|
||||||
|
public EntityDeath entityDeath;
|
||||||
|
public MobKill mobKill;
|
||||||
|
|
||||||
|
public Logger logger = this.getLogger();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
blocksMined = new BlocksMined(this);
|
||||||
|
craftItem = new CraftItem(this);
|
||||||
|
entityDeath = new EntityDeath(this);
|
||||||
|
mobKill = new MobKill(this);
|
||||||
|
|
||||||
|
Bukkit.getServer().getPluginManager().registerEvents(blocksMined, this);
|
||||||
|
Bukkit.getServer().getPluginManager().registerEvents(craftItem, this);
|
||||||
|
Bukkit.getServer().getPluginManager().registerEvents(entityDeath, this);
|
||||||
|
Bukkit.getServer().getPluginManager().registerEvents(mobKill, this);
|
||||||
|
|
||||||
|
new Metrics(this, 14110);
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(this, this::checkForUpdates);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkForUpdates() {
|
||||||
|
GitHubReleaseAPI api;
|
||||||
|
try {
|
||||||
|
api = new GitHubReleaseAPI("ToolStats", "hyperdefined");
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warning("Unable to check updates!");
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GitHubRelease current = api.getReleaseByTag(this.getDescription().getVersion());
|
||||||
|
GitHubRelease latest = api.getLatestVersion();
|
||||||
|
if (current == null) {
|
||||||
|
logger.warning("You are running a version that does not exist on GitHub. If you are in a dev environment, you can ignore this. Otherwise, this is a bug!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int buildsBehind = api.getBuildsBehind(current);
|
||||||
|
if (buildsBehind == 0) {
|
||||||
|
logger.info("You are running the latest version.");
|
||||||
|
} else {
|
||||||
|
logger.warning("A new version is available (" + latest.getTagVersion() + ")! You are running version " + current.getTagVersion() + ". You are " + buildsBehind + " version(s) behind.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/main/java/lol/hyper/toolstats/UUIDDataType.java
Normal file
37
src/main/java/lol/hyper/toolstats/UUIDDataType.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package lol.hyper.toolstats;
|
||||||
|
|
||||||
|
import org.bukkit.persistence.PersistentDataAdapterContext;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UUIDDataType implements PersistentDataType<byte[], UUID> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Class<byte[]> getPrimitiveType() {
|
||||||
|
return byte[].class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Class<UUID> getComplexType() {
|
||||||
|
return UUID.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte @NotNull [] toPrimitive(UUID complex, @NotNull PersistentDataAdapterContext context) {
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
|
||||||
|
bb.putLong(complex.getMostSignificantBits());
|
||||||
|
bb.putLong(complex.getLeastSignificantBits());
|
||||||
|
return bb.array();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull UUID fromPrimitive(byte @NotNull [] primitive, @NotNull PersistentDataAdapterContext context) {
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(primitive);
|
||||||
|
long firstLong = bb.getLong();
|
||||||
|
long secondLong = bb.getLong();
|
||||||
|
return new UUID(firstLong, secondLong);
|
||||||
|
}
|
||||||
|
}
|
||||||
90
src/main/java/lol/hyper/toolstats/events/BlocksMined.java
Normal file
90
src/main/java/lol/hyper/toolstats/events/BlocksMined.java
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package lol.hyper.toolstats.events;
|
||||||
|
|
||||||
|
import lol.hyper.toolstats.ToolStats;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
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.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BlocksMined implements Listener {
|
||||||
|
|
||||||
|
private final ToolStats toolStats;
|
||||||
|
private final String[] validTools = {"pickaxe", "axe", "hoe", "shovel"};
|
||||||
|
private final String blocksMinedLore = ChatColor.GRAY + "Blocks mined: " + ChatColor.DARK_GRAY + "X";
|
||||||
|
|
||||||
|
public BlocksMined(ToolStats toolStats) {
|
||||||
|
this.toolStats = toolStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBreak(BlockBreakEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (player.getGameMode() != GameMode.SURVIVAL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot());
|
||||||
|
if (heldItem == null || heldItem.getType() == Material.AIR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String itemName = heldItem.getType().toString().toLowerCase();
|
||||||
|
if (Arrays.stream(validTools).noneMatch(itemName::contains)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateBlocksMined(heldItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBlocksMined(ItemStack itemStack) {
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
if (meta == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Integer blocksMined = 0;
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) {
|
||||||
|
blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER);
|
||||||
|
}
|
||||||
|
if (blocksMined == null) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
blocksMined++;
|
||||||
|
}
|
||||||
|
container.set(toolStats.genericMined, PersistentDataType.INTEGER, blocksMined);
|
||||||
|
|
||||||
|
List<String> lore;
|
||||||
|
if (meta.hasLore()) {
|
||||||
|
lore = meta.getLore();
|
||||||
|
assert lore != null;
|
||||||
|
boolean hasLore = false;
|
||||||
|
// we do a for loop like this, we can keep track of index
|
||||||
|
// this doesn't mess the lore up of existing items
|
||||||
|
for (int x = 0; x < lore.size(); x++) {
|
||||||
|
if (lore.get(x).contains("Blocks mined")) {
|
||||||
|
hasLore = true;
|
||||||
|
lore.set(x, blocksMinedLore.replace("X", Integer.toString(blocksMined)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if the item has lore but doesn't have the tag, add it
|
||||||
|
if (!hasLore) {
|
||||||
|
lore.add(blocksMinedLore.replace("X", Integer.toString(blocksMined)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if the item has no lore, create a new list and add the string
|
||||||
|
lore = new ArrayList<>();
|
||||||
|
lore.add(blocksMinedLore.replace("X", Integer.toString(blocksMined)));
|
||||||
|
}
|
||||||
|
meta.setLore(lore);
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
72
src/main/java/lol/hyper/toolstats/events/CraftItem.java
Normal file
72
src/main/java/lol/hyper/toolstats/events/CraftItem.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package lol.hyper.toolstats.events;
|
||||||
|
|
||||||
|
import lol.hyper.toolstats.ToolStats;
|
||||||
|
import lol.hyper.toolstats.UUIDDataType;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.inventory.CraftItemEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class CraftItem implements Listener {
|
||||||
|
|
||||||
|
private final ToolStats toolStats;
|
||||||
|
public final String[] validItems = {
|
||||||
|
"pickaxe", "sword", "shovel", "axe", "hoe", "bow", "helmet", "chestplate", "leggings", "boots", "fishing"
|
||||||
|
};
|
||||||
|
private final String timeCreatedLore = ChatColor.GRAY + "Crafted on: " + ChatColor.DARK_GRAY + "X";
|
||||||
|
private final String ownerLore = ChatColor.GRAY + "Crafted by: " + ChatColor.DARK_GRAY + "X";
|
||||||
|
private final SimpleDateFormat format = new SimpleDateFormat("M/dd/yyyy", Locale.ENGLISH);
|
||||||
|
|
||||||
|
public CraftItem(ToolStats toolStats) {
|
||||||
|
this.toolStats = toolStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onCraft(CraftItemEvent event) {
|
||||||
|
Player player = (Player) event.getWhoClicked();
|
||||||
|
ItemStack itemStack = event.getCurrentItem();
|
||||||
|
if (itemStack == null || itemStack.getType() == Material.AIR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String name = itemStack.getType().toString().toLowerCase(Locale.ROOT);
|
||||||
|
for (String x : validItems) {
|
||||||
|
if (name.contains(x)) {
|
||||||
|
event.setCurrentItem(addLore(itemStack, player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack addLore(ItemStack itemStack, Player owner) {
|
||||||
|
ItemStack newItem = itemStack.clone();
|
||||||
|
ItemMeta meta = newItem.getItemMeta();
|
||||||
|
if (meta == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
long timeCreated = System.currentTimeMillis();
|
||||||
|
Date finalDate = new Date(timeCreated);
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
container.set(toolStats.craftedTime, PersistentDataType.LONG, timeCreated);
|
||||||
|
container.set(toolStats.craftedOwner, new UUIDDataType(), owner.getUniqueId());
|
||||||
|
List<String> lore;
|
||||||
|
if (meta.hasLore()) {
|
||||||
|
lore = meta.getLore();
|
||||||
|
assert lore != null;
|
||||||
|
} else {
|
||||||
|
lore = new ArrayList<>();
|
||||||
|
}
|
||||||
|
lore.add(timeCreatedLore.replace("X", format.format(finalDate)));
|
||||||
|
lore.add(ownerLore.replace("X", owner.getName()));
|
||||||
|
meta.setLore(lore);
|
||||||
|
newItem.setItemMeta(meta);
|
||||||
|
return newItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
57
src/main/java/lol/hyper/toolstats/events/EntityDeath.java
Normal file
57
src/main/java/lol/hyper/toolstats/events/EntityDeath.java
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package lol.hyper.toolstats.events;
|
||||||
|
|
||||||
|
import lol.hyper.toolstats.ToolStats;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class EntityDeath implements Listener {
|
||||||
|
|
||||||
|
private final ToolStats toolStats;
|
||||||
|
private final String droppedLore = ChatColor.GRAY + "Dropped by: " + ChatColor.DARK_GRAY + "X";
|
||||||
|
|
||||||
|
public EntityDeath(ToolStats toolStats) {
|
||||||
|
this.toolStats = toolStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onDeath(EntityDeathEvent event) {
|
||||||
|
LivingEntity livingEntity = event.getEntity();
|
||||||
|
UUID livingEntityUUID = event.getEntity().getUniqueId();
|
||||||
|
if (toolStats.mobKill.trackedMobs.contains(livingEntityUUID)) {
|
||||||
|
for (ItemStack current : event.getDrops()) {
|
||||||
|
String name = current.getType().toString().toLowerCase(Locale.ROOT);
|
||||||
|
for (String item : toolStats.craftItem.validItems) {
|
||||||
|
if (name.contains(item)) {
|
||||||
|
addLore(current, livingEntity.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toolStats.mobKill.trackedMobs.remove(livingEntityUUID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLore(ItemStack itemStack, String mob) {
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
if (meta == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> lore;
|
||||||
|
if (meta.hasLore()) {
|
||||||
|
lore = meta.getLore();
|
||||||
|
assert lore != null;
|
||||||
|
} else {
|
||||||
|
// if the item has no lore, create a new list and add the string
|
||||||
|
lore = new ArrayList<>();
|
||||||
|
}
|
||||||
|
lore.add(droppedLore.replace("X", mob));
|
||||||
|
meta.setLore(lore);
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
149
src/main/java/lol/hyper/toolstats/events/MobKill.java
Normal file
149
src/main/java/lol/hyper/toolstats/events/MobKill.java
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
package lol.hyper.toolstats.events;
|
||||||
|
|
||||||
|
import lol.hyper.toolstats.ToolStats;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class MobKill implements Listener {
|
||||||
|
|
||||||
|
private final ToolStats toolStats;
|
||||||
|
private final String[] validTools = {"sword", "trident", "axe"};
|
||||||
|
private final String playerKillsLore = ChatColor.GRAY + "Player kills: " + ChatColor.DARK_GRAY + "X";
|
||||||
|
private final String mobKillsLore = ChatColor.GRAY + "Mob kills: " + ChatColor.DARK_GRAY + "X";
|
||||||
|
public Set<UUID> trackedMobs = new HashSet<>();
|
||||||
|
|
||||||
|
public MobKill(ToolStats toolStats) {
|
||||||
|
this.toolStats = toolStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onDamage(EntityDamageByEntityEvent event) {
|
||||||
|
LivingEntity livingEntity = (LivingEntity) event.getEntity();
|
||||||
|
// mob is going to die
|
||||||
|
if (livingEntity.getHealth() - event.getFinalDamage() <= 0) {
|
||||||
|
// a player is killing something
|
||||||
|
if (event.getDamager() instanceof Player) {
|
||||||
|
Player player = (Player) event.getDamager();
|
||||||
|
if (player.getGameMode() != GameMode.SURVIVAL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot());
|
||||||
|
if (heldItem == null || heldItem.getType() == Material.AIR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String itemName = heldItem.getType().toString().toLowerCase();
|
||||||
|
if (Arrays.stream(validTools).noneMatch(itemName::contains)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// a player is killing another player
|
||||||
|
if (livingEntity instanceof Player) {
|
||||||
|
updatePlayerKills(heldItem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// player is killing regular mob
|
||||||
|
updateMobKills(heldItem);
|
||||||
|
trackedMobs.add(livingEntity.getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePlayerKills(ItemStack itemStack) {
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
if (meta == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Integer playerKills = 0;
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
|
||||||
|
playerKills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
|
||||||
|
}
|
||||||
|
if (playerKills == null) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
playerKills++;
|
||||||
|
}
|
||||||
|
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills);
|
||||||
|
|
||||||
|
List<String> lore;
|
||||||
|
if (meta.hasLore()) {
|
||||||
|
lore = meta.getLore();
|
||||||
|
assert lore != null;
|
||||||
|
boolean hasLore = false;
|
||||||
|
// we do a for loop like this, we can keep track of index
|
||||||
|
// this doesn't mess the lore up of existing items
|
||||||
|
for (int x = 0; x < lore.size(); x++) {
|
||||||
|
if (lore.get(x).contains("Mob kills")) {
|
||||||
|
hasLore = true;
|
||||||
|
lore.set(x, playerKillsLore.replace("X", Integer.toString(playerKills)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if the item has lore but doesn't have the tag, add it
|
||||||
|
if (!hasLore) {
|
||||||
|
lore.add(playerKillsLore.replace("X", Integer.toString(playerKills)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if the item has no lore, create a new list and add the string
|
||||||
|
lore = new ArrayList<>();
|
||||||
|
lore.add(playerKillsLore.replace("X", Integer.toString(playerKills)));
|
||||||
|
}
|
||||||
|
meta.setLore(lore);
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMobKills(ItemStack itemStack) {
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
if (meta == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Integer mobKills = 0;
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
|
||||||
|
mobKills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
|
||||||
|
}
|
||||||
|
if (mobKills == null) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
mobKills++;
|
||||||
|
}
|
||||||
|
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills);
|
||||||
|
|
||||||
|
List<String> lore;
|
||||||
|
if (meta.hasLore()) {
|
||||||
|
lore = meta.getLore();
|
||||||
|
assert lore != null;
|
||||||
|
boolean hasLore = false;
|
||||||
|
// we do a for loop like this, we can keep track of index
|
||||||
|
// this doesn't mess the lore up of existing items
|
||||||
|
for (int x = 0; x < lore.size(); x++) {
|
||||||
|
if (lore.get(x).contains("Mob kills")) {
|
||||||
|
hasLore = true;
|
||||||
|
lore.set(x, mobKillsLore.replace("X", Integer.toString(mobKills)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if the item has lore but doesn't have the tag, add it
|
||||||
|
if (!hasLore) {
|
||||||
|
lore.add(mobKillsLore.replace("X", Integer.toString(mobKills)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if the item has no lore, create a new list and add the string
|
||||||
|
lore = new ArrayList<>();
|
||||||
|
lore.add(mobKillsLore.replace("X", Integer.toString(mobKills)));
|
||||||
|
}
|
||||||
|
meta.setLore(lore);
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/main/resources/plugin.yml
Normal file
4
src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
name: ToolStats
|
||||||
|
version: '${project.version}'
|
||||||
|
main: lol.hyper.toolstats.ToolStats
|
||||||
|
api-version: 1.18
|
||||||
Reference in New Issue
Block a user