Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15e6b3aafc |
No files matched your search
+1
-21
@@ -1,21 +1 @@
|
||||
/target/
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
/.idea/
|
||||
*.iml
|
||||
dependency-reduced-pom.xml
|
||||
.floo*
|
||||
# Ignore Gradle project-specific cache directory
|
||||
.gradle
|
||||
|
||||
# Ignore Gradle build output directory
|
||||
build
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
|
||||
out
|
||||
|
||||
### Maven ###
|
||||
target/*
|
||||
build/
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies {
|
||||
compileOnly project(":api")
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
<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>com.extendedclip.papi.expansion.mcstatistics</groupId>
|
||||
<artifactId>statistics-expansion</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<name>PAPI-Expansion-Statistic</name>
|
||||
<description>PlaceholderAPI expansion for minecraft statistic placeholders</description>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/dev/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.15.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.10.8-DEV-86</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<finalName>${name}</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.2</version>
|
||||
<configuration>
|
||||
<target>1.8</target>
|
||||
<source>1.8</source>
|
||||
<encoding>UTF-8</encoding>
|
||||
<useIncrementalCompilation>false</useIncrementalCompilation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,303 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Statistics-Expansion
|
||||
* Copyright (C) 2020 Ryan McCarthy
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package com.extendedclip.papi.expansion.mcstatistics;
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.expansion.Cacheable;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class StatisticsExpansion extends PlaceholderExpansion implements Cacheable {
|
||||
|
||||
private final ListMultimap<Statistic, Material> ignoredMaterials = ArrayListMultimap.create();
|
||||
private final String VERSION = getClass().getPackage().getImplementationVersion();
|
||||
private final boolean isLegacy = !Enums.getIfPresent(Material.class, "TURTLE_HELMET").isPresent();
|
||||
public static final String SERVER_VERSION = Bukkit.getBukkitVersion().split("-")[0];
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "clip";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "statistic";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"DuplicatedCode", "Guava"})
|
||||
@Override
|
||||
public String onRequest(final OfflinePlayer offlinePlayer, String identifier) {
|
||||
if (offlinePlayer == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!offlinePlayer.isOnline()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final Player player = offlinePlayer.getPlayer();
|
||||
|
||||
final int secondsPlayed = StatisticsUtils.getSecondsPlayed(player, isLegacy);
|
||||
final int secondsSinceLastDeath = StatisticsUtils.getSecondsSinceLastDeath(player, isLegacy);
|
||||
|
||||
switch (identifier.toLowerCase()) {
|
||||
case "mine_block": {
|
||||
return calculateTotal(player, Statistic.MINE_BLOCK);
|
||||
}
|
||||
|
||||
case "use_item": {
|
||||
return calculateTotal(player, Statistic.USE_ITEM);
|
||||
}
|
||||
|
||||
case "break_item": {
|
||||
return calculateTotal(player, Statistic.BREAK_ITEM);
|
||||
}
|
||||
|
||||
case "craft_item": {
|
||||
return calculateTotal(player, Statistic.CRAFT_ITEM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Time played
|
||||
*/
|
||||
case "time_played": {
|
||||
return StatisticsUtils.formatTime(Duration.of(secondsPlayed, ChronoUnit.SECONDS));
|
||||
}
|
||||
|
||||
case "time_played:seconds": {
|
||||
//return seconds != 0 ? Long.toString(TimeUnit.MINUTES.toSeconds(1) - seconds) : "0";
|
||||
return Integer.toString(secondsPlayed % 60);
|
||||
}
|
||||
|
||||
case "time_played:minutes": {
|
||||
//return minutes != 0 ? Long.toString(TimeUnit.HOURS.toMinutes(1) - minutes) : "0";
|
||||
return Long.toString(TimeUnit.SECONDS.toMinutes(secondsPlayed) % 60);
|
||||
}
|
||||
|
||||
case "time_played:hours": {
|
||||
//return hours != 0 ? Long.toString(TimeUnit.DAYS.toHours(1) - hours) : "0";
|
||||
return Long.toString(TimeUnit.SECONDS.toHours(secondsPlayed) % 24);
|
||||
}
|
||||
|
||||
case "seconds_played": {
|
||||
return Integer.toString(secondsPlayed);
|
||||
}
|
||||
|
||||
case "minutes_played": {
|
||||
return Long.toString(TimeUnit.SECONDS.toMinutes(secondsPlayed));
|
||||
}
|
||||
|
||||
case "hours_played": {
|
||||
return Long.toString(TimeUnit.SECONDS.toHours(secondsPlayed));
|
||||
}
|
||||
|
||||
case "time_played:days":
|
||||
case "days_played": {
|
||||
return Long.toString(TimeUnit.SECONDS.toDays(secondsPlayed));
|
||||
}
|
||||
|
||||
/*
|
||||
* Time since last death
|
||||
*/
|
||||
case "time_since_death": {
|
||||
return StatisticsUtils.formatTime(Duration.of(secondsSinceLastDeath, ChronoUnit.SECONDS));
|
||||
}
|
||||
|
||||
case "seconds_since_death": {
|
||||
return Integer.toString(secondsSinceLastDeath);
|
||||
}
|
||||
|
||||
case "minutes_since_death": {
|
||||
return Long.toString(TimeUnit.SECONDS.toMinutes(secondsSinceLastDeath));
|
||||
}
|
||||
|
||||
case "hours_since_death": {
|
||||
return Long.toString(TimeUnit.SECONDS.toHours(secondsSinceLastDeath));
|
||||
}
|
||||
|
||||
case "days_since_death": {
|
||||
return Long.toString(TimeUnit.SECONDS.toDays(secondsSinceLastDeath));
|
||||
}
|
||||
}
|
||||
|
||||
final int splitterIndex = identifier.indexOf(':');
|
||||
// %statistic_<Statistic>%
|
||||
if (splitterIndex == -1) {
|
||||
return StatisticsUtils.getStatistic(player, identifier);
|
||||
}
|
||||
|
||||
final String statisticIdentifier = identifier.substring(0, splitterIndex).toUpperCase();
|
||||
final String types = identifier.substring(splitterIndex + 1).toUpperCase();
|
||||
|
||||
if (types.trim().isEmpty()) {
|
||||
return StatisticsUtils.getStatistic(player, statisticIdentifier);
|
||||
}
|
||||
|
||||
final Optional<Statistic> statisticOptional = Enums.getIfPresent(Statistic.class, statisticIdentifier);
|
||||
|
||||
if (!statisticOptional.isPresent()) {
|
||||
return "Unknown statistic '" + statisticIdentifier + "', check https://helpch.at/docs/" + SERVER_VERSION + "/org/bukkit/Statistic.html for more info";
|
||||
}
|
||||
|
||||
final Statistic statistic = statisticOptional.get();
|
||||
|
||||
// %statistic_<Statistic>:<Material/Entity>%
|
||||
if (!types.contains(",")) {
|
||||
switch (statistic.getType()) {
|
||||
case BLOCK:
|
||||
case ITEM: {
|
||||
final Optional<Material> material = Enums.getIfPresent(Material.class, types);
|
||||
|
||||
if (!material.isPresent()) {
|
||||
return "Invalid material " + types;
|
||||
}
|
||||
|
||||
try {
|
||||
return Integer.toString(player.getStatistic(statistic, material.get()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
errorLog("Could not get the statistic '" + statistic.name() + "' for '" + material.get().name() + "'", e);
|
||||
return "Could not get the statistic '" + statistic.name() + "' for '" + material.get().name() + "'";
|
||||
}
|
||||
}
|
||||
|
||||
case ENTITY: {
|
||||
final Optional<EntityType> entityType = Enums.getIfPresent(EntityType.class, types);
|
||||
|
||||
if (!entityType.isPresent()) {
|
||||
return "Invalid entity " + types;
|
||||
}
|
||||
|
||||
try {
|
||||
return Integer.toString(player.getStatistic(statistic, entityType.get()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
errorLog("Could not get the statistic '" + statistic.name() + "' for '" + entityType.get().name() + "'", e);
|
||||
return "Could not get the statistic '" + statistic.name() + "' for '" + entityType.get().name() + "'";
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// %statistic_<Statistic>:<Material/Entity>,<Material/Entity>,<Material/Entity>%
|
||||
final String[] args = types.split(",");
|
||||
final AtomicInteger total = new AtomicInteger();
|
||||
|
||||
switch (statistic.getType()) {
|
||||
case BLOCK:
|
||||
case ITEM: {
|
||||
for (String arg : args) {
|
||||
final Optional<Material> material = Enums.getIfPresent(Material.class, arg);
|
||||
|
||||
if (!material.isPresent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
total.addAndGet(player.getStatistic(statistic, material.get()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
errorLog("Could not get the statistic '" + statistic.name() + "' for '" + material.get().name() + "'", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ENTITY: {
|
||||
for (String arg : args) {
|
||||
final Optional<EntityType> entityType = Enums.getIfPresent(EntityType.class, arg);
|
||||
|
||||
if (!entityType.isPresent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
total.addAndGet(player.getStatistic(statistic, entityType.get()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
errorLog("Could not get the statistic '" + statistic.name() + "' for '" + entityType.get().name() + "'", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Integer.toString(total.get());
|
||||
}
|
||||
|
||||
private String calculateTotal(final Player player, final Statistic statistic) {
|
||||
final AtomicLong total = new AtomicLong();
|
||||
|
||||
for (Material material : Material.values()) {
|
||||
if (ignoredMaterials.get(statistic).contains(material)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (statistic == Statistic.MINE_BLOCK && (material.name().equals("GRASS") || material.name().equals("SOIL"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
total.addAndGet(player.getStatistic(statistic, material));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
ignoredMaterials.put(statistic, material);
|
||||
}
|
||||
}
|
||||
|
||||
return Long.toString(total.get());
|
||||
}
|
||||
|
||||
private void errorLog(final String message, final Throwable exception) {
|
||||
PlaceholderAPIPlugin.getInstance().getLogger().log(Level.SEVERE, "[Statistic Expansion] " + message, exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
ignoredMaterials.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Statistics-Expansion
|
||||
* Copyright (C) 2020 Ryan McCarthy
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package com.extendedclip.papi.expansion.mcstatistics;
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
import com.google.common.base.Optional;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class StatisticsUtils {
|
||||
public static int getSecondsPlayed(final Player player, final boolean isLegacy) {
|
||||
return isLegacy ? player.getStatistic(Statistic.valueOf("PLAY_ONE_TICK")) / 20 : player.getStatistic(Statistic.PLAY_ONE_MINUTE) / 20;
|
||||
}
|
||||
|
||||
public static int getSecondsSinceLastDeath(final Player player, final boolean isLegacy) {
|
||||
return isLegacy ? player.getStatistic(Statistic.valueOf("TIME_SINCE_DEATH")) / 20 : player.getStatistic(Statistic.TIME_SINCE_DEATH) / 20;
|
||||
}
|
||||
|
||||
@SuppressWarnings("Guava")
|
||||
public static String getStatistic(final Player player, final String identifier) {
|
||||
final Optional<Statistic> optional = Enums.getIfPresent(Statistic.class, identifier.toUpperCase());
|
||||
|
||||
if (!optional.isPresent()) {
|
||||
return "Unknown statistic '" + identifier + "', check https://helpch.at/docs/" + StatisticsExpansion.SERVER_VERSION + "/org/bukkit/Statistic.html for more info";
|
||||
}
|
||||
|
||||
if (optional.get().getType() != Statistic.Type.UNTYPED) {
|
||||
return "The statistic '" + identifier + "' require an argument, check https://helpch.at/docs/" + StatisticsExpansion.SERVER_VERSION + "/org/bukkit/Statistic.Type.html for more info" ;
|
||||
}
|
||||
|
||||
return Integer.toString(player.getStatistic(optional.get()));
|
||||
}
|
||||
|
||||
public static boolean isItem(final Material material, final boolean isLegacy) {
|
||||
if (isLegacy) {
|
||||
switch (material.name()) {
|
||||
case "ACACIA_DOOR":
|
||||
case "BED_BLOCK":
|
||||
case "BEETROOT_BLOCK":
|
||||
case "BIRCH_DOOR":
|
||||
case "BREWING_STAND":
|
||||
case "BURNING_FURNACE":
|
||||
case "CAKE_BLOCK":
|
||||
case "CARROT":
|
||||
case "CAULDRON":
|
||||
case "COCOA":
|
||||
case "CROPS":
|
||||
case "DARK_OAK_DOOR":
|
||||
case "DAYLIGHT_DETECTOR_INVERTED":
|
||||
case "DIODE_BLOCK_OFF":
|
||||
case "DIODE_BLOCK_ON":
|
||||
case "DOUBLE_STEP":
|
||||
case "DOUBLE_STONE_SLAB2":
|
||||
case "ENDER_PORTAL":
|
||||
case "END_GATEWAY":
|
||||
case "FIRE":
|
||||
case "FLOWER_POT":
|
||||
case "FROSTED_ICE":
|
||||
case "GLOWING_REDSTONE_ORE":
|
||||
case "IRON_DOOR_BLOCK":
|
||||
case "JUNGLE_DOOR":
|
||||
case "LAVA":
|
||||
case "MELON_STEM":
|
||||
case "NETHER_WARTS":
|
||||
case "PISTON_EXTENSION":
|
||||
case "PISTON_MOVING_PIECE":
|
||||
case "PORTAL":
|
||||
case "POTATO":
|
||||
case "PUMPKIN_STEM":
|
||||
case "PURPUR_DOUBLE_SLAB":
|
||||
case "REDSTONE_COMPARATOR_OFF":
|
||||
case "REDSTONE_COMPARATOR_ON":
|
||||
case "REDSTONE_LAMP_ON":
|
||||
case "REDSTONE_TORCH_OFF":
|
||||
case "REDSTONE_WIRE":
|
||||
case "SIGN_POST":
|
||||
case "SKULL":
|
||||
case "SPRUCE_DOOR":
|
||||
case "STANDING_BANNER":
|
||||
case "STATIONARY_LAVA":
|
||||
case "STATIONARY_WATER":
|
||||
case "SUGAR_CANE_BLOCK":
|
||||
case "TRIPWIRE":
|
||||
case "WALL_BANNER":
|
||||
case "WALL_SIGN":
|
||||
case "WATER":
|
||||
case "WOODEN_DOOR":
|
||||
case "WOOD_DOUBLE_STEP":
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return material.isItem();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Sxtanna
|
||||
*/
|
||||
public static String formatTime(final Duration duration) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
long seconds = duration.getSeconds();
|
||||
long minutes = seconds / 60;
|
||||
long hours = minutes / 60;
|
||||
long days = hours / 24;
|
||||
|
||||
seconds %= 60;
|
||||
minutes %= 60;
|
||||
hours %= 60;
|
||||
days %= 24;
|
||||
|
||||
if (seconds > 0) {
|
||||
builder.insert(0, seconds + "s");
|
||||
}
|
||||
|
||||
if (minutes > 0) {
|
||||
if (builder.length() > 0) {
|
||||
builder.insert(0, ' ');
|
||||
}
|
||||
|
||||
builder.insert(0, minutes + "m");
|
||||
}
|
||||
|
||||
if (hours > 0) {
|
||||
if (builder.length() > 0) {
|
||||
builder.insert(0, ' ');
|
||||
}
|
||||
|
||||
builder.insert(0, hours + "h");
|
||||
}
|
||||
|
||||
if (days > 0) {
|
||||
if (builder.length() > 0) {
|
||||
builder.insert(0, ' ');
|
||||
}
|
||||
|
||||
builder.insert(0, days + "d");
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Reference in new issue
Block a user