mirror of
https://github.com/hyperdefined/ToolStats.git
synced 2025-12-24 18:25:08 +00:00
Compare commits
14 Commits
a4393780a2
...
1.9.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfd2ef7d7b | ||
|
|
957d4d95cb | ||
|
|
2143daa133 | ||
|
|
be8fcc2d57 | ||
|
|
ed9afc1812 | ||
|
|
706175a13a | ||
|
|
256581fa08 | ||
|
|
818f2e7a39 | ||
|
|
d83bc55eec | ||
|
|
3196223d30 | ||
|
|
02d5d1c17e | ||
|
|
d675549209 | ||
|
|
d5324b5db6 | ||
|
|
4fe4c2be25 |
BIN
images/crafting/damage-done.png
Normal file
BIN
images/crafting/damage-done.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
@@ -48,7 +48,7 @@ public class CommandToolStats implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
|
||||||
if (!sender.hasPermission("toolstats.command")) {
|
if (!sender.hasPermission("toolstats.command")) {
|
||||||
sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
|
sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
|
||||||
return true;
|
return true;
|
||||||
@@ -210,7 +210,8 @@ public class CommandToolStats implements TabExecutor {
|
|||||||
|
|
||||||
if (flightTime != null) {
|
if (flightTime != null) {
|
||||||
if (toolStats.config.getBoolean("enabled.flight-time")) {
|
if (toolStats.config.getBoolean("enabled.flight-time")) {
|
||||||
Component line = toolStats.configTools.formatLore("flight-time", "{time}", toolStats.numberFormat.formatDouble((double) flightTime / 1000));
|
Map<String, String> flightTimeFormatted = toolStats.numberFormat.formatTime(flightTime);
|
||||||
|
Component line = toolStats.configTools.formatLoreMultiplePlaceholders("flight-time", flightTimeFormatted);
|
||||||
lore.add(line);
|
lore.add(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -406,6 +407,12 @@ public class CommandToolStats implements TabExecutor {
|
|||||||
target.getInventory().addItem(itemStack);
|
target.getInventory().addItem(itemStack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "damage-done": {
|
||||||
|
ItemStack itemStack = toolStats.tokenItems.damageDone();
|
||||||
|
itemStack.setAmount(amount);
|
||||||
|
target.getInventory().addItem(itemStack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "mob-kills": {
|
case "mob-kills": {
|
||||||
ItemStack itemStack = toolStats.tokenItems.mobKills();
|
ItemStack itemStack = toolStats.tokenItems.mobKills();
|
||||||
itemStack.setAmount(amount);
|
itemStack.setAmount(amount);
|
||||||
@@ -459,7 +466,7 @@ public class CommandToolStats implements TabExecutor {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String @NotNull [] args) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
List<String> suggestions = new ArrayList<>();
|
List<String> suggestions = new ArrayList<>();
|
||||||
if (sender.hasPermission("toolstats.reload")) {
|
if (sender.hasPermission("toolstats.reload")) {
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.bukkit.entity.*;
|
|||||||
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.entity.EntityDamageByBlockEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
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;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ 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.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
@@ -46,6 +47,11 @@ public class InventoryOpen implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Inventory inventory = event.getInventory();
|
Inventory inventory = event.getInventory();
|
||||||
|
// only check these
|
||||||
|
if (inventory.getType() != InventoryType.CHEST || inventory.getType() != InventoryType.BARREL || inventory.getType() != InventoryType.SHULKER_BOX || inventory.getType() != InventoryType.ENDER_CHEST) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Player player = (Player) event.getPlayer();
|
Player player = (Player) event.getPlayer();
|
||||||
for (ItemStack itemStack : inventory) {
|
for (ItemStack itemStack : inventory) {
|
||||||
if (itemStack == null) {
|
if (itemStack == null) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.bukkit.persistence.PersistentDataType;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ItemLore {
|
public class ItemLore {
|
||||||
|
|
||||||
@@ -767,8 +768,15 @@ public class ItemLore {
|
|||||||
}
|
}
|
||||||
container.remove(toolStats.flightTime);
|
container.remove(toolStats.flightTime);
|
||||||
if (meta.hasLore()) {
|
if (meta.hasLore()) {
|
||||||
String oldFlightTimeFormatted = toolStats.numberFormat.formatDouble(flightTime);
|
// if the old format is in the config, check to see if the old format is on the elytra
|
||||||
Component lineToRemove = toolStats.configTools.formatLore("flight-time", "{time}", oldFlightTimeFormatted);
|
if (toolStats.config.getString("messages.flight-time-old") != null) {
|
||||||
|
String oldFormatFormatted = toolStats.numberFormat.formatDouble((double) flightTime / 1000);
|
||||||
|
Component oldFormat = toolStats.configTools.formatLore("flight-time-old", "{time}", oldFormatFormatted);
|
||||||
|
meta.lore(removeLore(meta.lore(), oldFormat));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> oldFlightTimeFormatted = toolStats.numberFormat.formatTime(flightTime);
|
||||||
|
Component lineToRemove = toolStats.configTools.formatLoreMultiplePlaceholders("flight-time", oldFlightTimeFormatted);
|
||||||
List<Component> newLore = removeLore(meta.lore(), lineToRemove);
|
List<Component> newLore = removeLore(meta.lore(), lineToRemove);
|
||||||
meta.lore(newLore);
|
meta.lore(newLore);
|
||||||
}
|
}
|
||||||
@@ -815,10 +823,16 @@ public class ItemLore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
container.set(toolStats.flightTime, PersistentDataType.LONG, flightTime + duration);
|
container.set(toolStats.flightTime, PersistentDataType.LONG, flightTime + duration);
|
||||||
String oldFlightFormatted = toolStats.numberFormat.formatDouble((double) flightTime / 1000);
|
Map<String, String> oldFlightFormatted = toolStats.numberFormat.formatTime(flightTime);
|
||||||
String newFlightFormatted = toolStats.numberFormat.formatDouble((double) (flightTime + duration) / 1000);
|
Map<String, String> newFlightFormatted = toolStats.numberFormat.formatTime(flightTime + duration);
|
||||||
Component oldLine = toolStats.configTools.formatLore("flight-time", "{time}", oldFlightFormatted);
|
// if the old format is in the config, check to see if the old format is on the elytra
|
||||||
Component newLine = toolStats.configTools.formatLore("flight-time", "{time}", newFlightFormatted);
|
if (toolStats.config.getString("messages.flight-time-old") != null) {
|
||||||
|
String oldFormatFormatted = toolStats.numberFormat.formatDouble((double) flightTime / 1000);
|
||||||
|
Component oldFormat = toolStats.configTools.formatLore("flight-time-old", "{time}", oldFormatFormatted);
|
||||||
|
meta.lore(removeLore(meta.lore(), oldFormat));
|
||||||
|
}
|
||||||
|
Component oldLine = toolStats.configTools.formatLoreMultiplePlaceholders("flight-time", oldFlightFormatted);
|
||||||
|
Component newLine = toolStats.configTools.formatLoreMultiplePlaceholders("flight-time", newFlightFormatted);
|
||||||
if (oldLine == null || newLine == null) {
|
if (oldLine == null || newLine == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ import java.text.DecimalFormat;
|
|||||||
import java.text.DecimalFormatSymbols;
|
import java.text.DecimalFormatSymbols;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class NumberFormat {
|
public class NumberFormat {
|
||||||
|
|
||||||
@@ -136,4 +138,59 @@ public class NumberFormat {
|
|||||||
public String formatDate(Date date) {
|
public String formatDate(Date date) {
|
||||||
return DATE_FORMAT.format(date);
|
return DATE_FORMAT.format(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a human readable form of time in milliseconds.
|
||||||
|
* E.g. given 3752348000L outputs 1 years, 5 months, 3 days, 14 hours, 12 minutes, 28 seconds.
|
||||||
|
* @param time The time in ms.
|
||||||
|
* @return Map with units as keys and time value, e.g. "years" (key) -> 1 (value)
|
||||||
|
*/
|
||||||
|
public Map<String, String> formatTime(Long time) {
|
||||||
|
final int SECONDS_PER_MINUTE = 60;
|
||||||
|
final int MINUTES_PER_HOUR = 60;
|
||||||
|
final int HOURS_PER_DAY = 24;
|
||||||
|
final int DAYS_PER_MONTH = 30; // Approximation
|
||||||
|
final int DAYS_PER_YEAR = 365; // Approximation
|
||||||
|
|
||||||
|
long totalSeconds = time / 1000;
|
||||||
|
|
||||||
|
Map<String, String> timeUnits = new HashMap<>();
|
||||||
|
|
||||||
|
long years = totalSeconds / (DAYS_PER_YEAR * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||||
|
if (years > 0) {
|
||||||
|
timeUnits.put("years", Long.toString(years));
|
||||||
|
}
|
||||||
|
totalSeconds %= (DAYS_PER_YEAR * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||||
|
|
||||||
|
long months = totalSeconds / (DAYS_PER_MONTH * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||||
|
if (months > 0) {
|
||||||
|
timeUnits.put("months", Long.toString(months));
|
||||||
|
}
|
||||||
|
totalSeconds %= (DAYS_PER_MONTH * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||||
|
|
||||||
|
long days = totalSeconds / (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||||
|
if (days > 0) {
|
||||||
|
timeUnits.put("days", Long.toString(days));
|
||||||
|
}
|
||||||
|
totalSeconds %= (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||||
|
|
||||||
|
long hours = totalSeconds / (MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||||
|
if (hours > 0) {
|
||||||
|
timeUnits.put("hours", Long.toString(hours));
|
||||||
|
}
|
||||||
|
totalSeconds %= (MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||||
|
|
||||||
|
long minutes = totalSeconds / SECONDS_PER_MINUTE;
|
||||||
|
if (minutes > 0) {
|
||||||
|
timeUnits.put("minutes", Long.toString(minutes));
|
||||||
|
}
|
||||||
|
totalSeconds %= SECONDS_PER_MINUTE;
|
||||||
|
|
||||||
|
long seconds = totalSeconds;
|
||||||
|
if (seconds > 0 || timeUnits.isEmpty()) { // Always include seconds if everything else is zero
|
||||||
|
timeUnits.put("seconds", Long.toString(seconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeUnits;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,13 +115,14 @@ public class TokenCrafting {
|
|||||||
|
|
||||||
NamespacedKey removeKey = new NamespacedKey(toolStats, "remove-token");
|
NamespacedKey removeKey = new NamespacedKey(toolStats, "remove-token");
|
||||||
ShapedRecipe removeRecipe = new ShapedRecipe(removeKey, toolStats.tokenItems.removeToken());
|
ShapedRecipe removeRecipe = new ShapedRecipe(removeKey, toolStats.tokenItems.removeToken());
|
||||||
resetRecipe.shape(" P ", "P P", " P ");
|
removeRecipe.shape(" P ", "P P", " P ");
|
||||||
resetRecipe.setIngredient('P', Material.PAPER);
|
removeRecipe.setIngredient('P', Material.PAPER);
|
||||||
recipes.add(removeRecipe);
|
recipes.add(removeRecipe);
|
||||||
|
|
||||||
tokenTypes.add("crops-mined");
|
tokenTypes.add("crops-mined");
|
||||||
tokenTypes.add("blocks-mined");
|
tokenTypes.add("blocks-mined");
|
||||||
tokenTypes.add("damage-taken");
|
tokenTypes.add("damage-taken");
|
||||||
|
tokenTypes.add("damage-done");
|
||||||
tokenTypes.add("mob-kills");
|
tokenTypes.add("mob-kills");
|
||||||
tokenTypes.add("player-kills");
|
tokenTypes.add("player-kills");
|
||||||
tokenTypes.add("arrows-shot");
|
tokenTypes.add("arrows-shot");
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.bukkit.Material;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -133,6 +134,65 @@ public class ConfigTools {
|
|||||||
return component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE);
|
return component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a string with several placeholders to be ready for lore usage.
|
||||||
|
*
|
||||||
|
* @param configName The message to use.
|
||||||
|
* @param placeHoldersValues Map containing placeholders names as keys and values.
|
||||||
|
* @return Formatted string, null if the configName doesn't exist.
|
||||||
|
*/
|
||||||
|
public Component formatLoreMultiplePlaceholders(String configName, Map<String, String> placeHoldersValues) {
|
||||||
|
String lore = toolStats.config.getString("messages." + configName);
|
||||||
|
if (lore == null) {
|
||||||
|
toolStats.logger.warning("Unable to find config message for: messages." + configName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the config message is empty, don't send it
|
||||||
|
if (lore.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile("\\{([^}]+)\\}(\\S*)\\s*");
|
||||||
|
Matcher matcher = pattern.matcher(lore);
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
int lastEnd = 0;
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
String placeholder = matcher.group(1);
|
||||||
|
String unit = matcher.group(2);
|
||||||
|
|
||||||
|
result.append(lore, lastEnd, matcher.start());
|
||||||
|
|
||||||
|
if (placeHoldersValues.containsKey(placeholder)) {
|
||||||
|
result.append(placeHoldersValues.get(placeholder)).append(unit).append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update lastEnd to end of the match
|
||||||
|
lastEnd = matcher.end();
|
||||||
|
}
|
||||||
|
if (lastEnd < lore.length()) {
|
||||||
|
result.append(lore.substring(lastEnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
Component component;
|
||||||
|
// Clean output text
|
||||||
|
String outputText = result.toString().replaceAll("\\s+", " ").trim();
|
||||||
|
|
||||||
|
// if we match the old color codes, then format them as so
|
||||||
|
Matcher hexMatcher = CONFIG_HEX_PATTERN.matcher(outputText);
|
||||||
|
Matcher colorMatcher = COLOR_CODES.matcher(outputText);
|
||||||
|
if (hexMatcher.find() || colorMatcher.find()) {
|
||||||
|
component = LegacyComponentSerializer.legacyAmpersand().deserialize(outputText);
|
||||||
|
} else {
|
||||||
|
// otherwise format them normally
|
||||||
|
component = MiniMessage.miniMessage().deserialize(outputText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a string from the config.
|
* Format a string from the config.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -62,4 +62,4 @@ public class ConfigUpdater {
|
|||||||
version11.update();
|
version11.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,6 @@ import org.bukkit.inventory.meta.ItemMeta;
|
|||||||
import org.bukkit.persistence.PersistentDataContainer;
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TokenItems {
|
public class TokenItems {
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ public class Version11 {
|
|||||||
toolStats.logger.info("Adding enabled.damage-done.bow to config.yml");
|
toolStats.logger.info("Adding enabled.damage-done.bow to config.yml");
|
||||||
toolStats.logger.info("Adding enabled.damage-done.mace to config.yml");
|
toolStats.logger.info("Adding enabled.damage-done.mace to config.yml");
|
||||||
|
|
||||||
|
toolStats.logger.info("Updating entry for messages.flight-time");
|
||||||
|
String oldFlightTime = toolStats.config.getString("messages.flight-time");
|
||||||
|
toolStats.config.set("messages.flight-time-old", oldFlightTime);
|
||||||
|
toolStats.config.set("messages.flight-time", "&7Flight time: &8{years}y {months}m {days}d {hours}h {minutes}m {seconds}s");
|
||||||
|
|
||||||
// save the config and reload it
|
// save the config and reload it
|
||||||
try {
|
try {
|
||||||
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config.yml");
|
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config.yml");
|
||||||
@@ -96,4 +101,4 @@ public class Version11 {
|
|||||||
toolStats.loadConfig();
|
toolStats.loadConfig();
|
||||||
toolStats.logger.info("Config has been updated to version 11. A copy of version 10 has been saved as config-10.yml");
|
toolStats.logger.info("Config has been updated to version 11. A copy of version 10 has been saved as config-10.yml");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ messages:
|
|||||||
dropped-by: "&7Dropped by: &8{name}" # name will be player/mob name
|
dropped-by: "&7Dropped by: &8{name}" # name will be player/mob name
|
||||||
damage-taken: "&7Damage taken: &8{damage}"
|
damage-taken: "&7Damage taken: &8{damage}"
|
||||||
arrows-shot: "&7Arrows shot: &8{arrows}"
|
arrows-shot: "&7Arrows shot: &8{arrows}"
|
||||||
flight-time: "&7Flight time: &8{time}"
|
flight-time: "&7Flight time: &8{years}y {months}m {days}d {hours}h {minutes}m {seconds}s"
|
||||||
damage-done: "&7Damage done: &8{damage}"
|
damage-done: "&7Damage done: &8{damage}"
|
||||||
# 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:
|
||||||
|
|||||||
Reference in New Issue
Block a user