mirror of https://github.com/PaperMC/Paper.git
Better Stats API
This commit is contained in:
parent
086ca616d8
commit
205dabd4f2
|
@ -0,0 +1,832 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||||
|
Date: Thu, 20 May 2021 01:10:54 -0700
|
||||||
|
Subject: [PATCH] Better Stats API
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerRequestStatisticsEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerRequestStatisticsEvent.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..ce1b6ae06c411f0e346e3ccf5760ec5aa86e43e3
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/event/player/PlayerRequestStatisticsEvent.java
|
||||||
|
@@ -0,0 +1,56 @@
|
||||||
|
+package io.papermc.paper.event.player;
|
||||||
|
+
|
||||||
|
+import io.papermc.paper.statistic.Statistic;
|
||||||
|
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
|
+import org.bukkit.entity.Player;
|
||||||
|
+import org.bukkit.event.Cancellable;
|
||||||
|
+import org.bukkit.event.HandlerList;
|
||||||
|
+import org.bukkit.event.player.PlayerEvent;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Called when the player requests their statistics.
|
||||||
|
+ */
|
||||||
|
+public class PlayerRequestStatisticsEvent extends PlayerEvent implements Cancellable {
|
||||||
|
+
|
||||||
|
+ private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
+
|
||||||
|
+ private final Object2IntMap<Statistic<?>> statisticMap;
|
||||||
|
+ private boolean cancelled;
|
||||||
|
+
|
||||||
|
+ public PlayerRequestStatisticsEvent(@NotNull Player who, @NotNull Object2IntMap<Statistic<?>> statisticMap) {
|
||||||
|
+ super(who);
|
||||||
|
+ this.statisticMap = statisticMap;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the statistic map to be sent to the player.
|
||||||
|
+ *
|
||||||
|
+ * @return the mutable statistic map
|
||||||
|
+ */
|
||||||
|
+ @NotNull
|
||||||
|
+ public Object2IntMap<Statistic<?>> getStatisticMap() {
|
||||||
|
+ return statisticMap;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean isCancelled() {
|
||||||
|
+ return this.cancelled;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void setCancelled(boolean cancel) {
|
||||||
|
+ this.cancelled = cancel;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ @Override
|
||||||
|
+ public HandlerList getHandlers() {
|
||||||
|
+ return HANDLER_LIST;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ public static HandlerList getHandlerList() {
|
||||||
|
+ return HANDLER_LIST;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/statistic/CustomStatistic.java b/src/main/java/io/papermc/paper/statistic/CustomStatistic.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..abf3a7c06c90ed399e8f6da7eedfb9e6d257e544
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/statistic/CustomStatistic.java
|
||||||
|
@@ -0,0 +1,102 @@
|
||||||
|
+package io.papermc.paper.statistic;
|
||||||
|
+
|
||||||
|
+import net.kyori.adventure.translation.Translatable;
|
||||||
|
+import org.bukkit.Keyed;
|
||||||
|
+import org.bukkit.NamespacedKey;
|
||||||
|
+import org.bukkit.Registry;
|
||||||
|
+import org.jetbrains.annotations.ApiStatus;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Custom statistic types.
|
||||||
|
+ */
|
||||||
|
+@ApiStatus.NonExtendable
|
||||||
|
+public interface CustomStatistic extends Keyed, Translatable {
|
||||||
|
+
|
||||||
|
+ CustomStatistic LEAVE_GAME = get("leave_game");
|
||||||
|
+ CustomStatistic PLAY_TIME = get("play_time");
|
||||||
|
+ CustomStatistic TOTAL_WORLD_TIME = get("total_world_time");
|
||||||
|
+ CustomStatistic TIME_SINCE_DEATH = get("time_since_death");
|
||||||
|
+ CustomStatistic TIME_SINCE_REST = get("time_since_rest");
|
||||||
|
+ CustomStatistic SNEAK_TIME = get("sneak_time");
|
||||||
|
+ CustomStatistic WALK_ONE_CM = get("walk_one_cm");
|
||||||
|
+ CustomStatistic CROUCH_ONE_CM = get("crouch_one_cm");
|
||||||
|
+ CustomStatistic SPRINT_ONE_CM = get("sprint_one_cm");
|
||||||
|
+ CustomStatistic WALK_ON_WATER_ONE_CM = get("walk_on_water_one_cm");
|
||||||
|
+ CustomStatistic FALL_ONE_CM = get("fall_one_cm");
|
||||||
|
+ CustomStatistic CLIMB_ONE_CM = get("climb_one_cm");
|
||||||
|
+ CustomStatistic FLY_ONE_CM = get("fly_one_cm");
|
||||||
|
+ CustomStatistic WALK_UNDER_WATER_ONE_CM = get("walk_under_water_one_cm");
|
||||||
|
+ CustomStatistic MINECART_ONE_CM = get("minecart_one_cm");
|
||||||
|
+ CustomStatistic BOAT_ONE_CM = get("boat_one_cm");
|
||||||
|
+ CustomStatistic PIG_ONE_CM = get("pig_one_cm");
|
||||||
|
+ CustomStatistic HORSE_ONE_CM = get("horse_one_cm");
|
||||||
|
+ CustomStatistic AVIATE_ONE_CM = get("aviate_one_cm");
|
||||||
|
+ CustomStatistic SWIM_ONE_CM = get("swim_one_cm");
|
||||||
|
+ CustomStatistic STRIDER_ONE_CM = get("strider_one_cm");
|
||||||
|
+ CustomStatistic JUMP = get("jump");
|
||||||
|
+ CustomStatistic DROP = get("drop");
|
||||||
|
+ CustomStatistic DAMAGE_DEALT = get("damage_dealt");
|
||||||
|
+ CustomStatistic DAMAGE_DEALT_ABSORBED = get("damage_dealt_absorbed");
|
||||||
|
+ CustomStatistic DAMAGE_DEALT_RESISTED = get("damage_dealt_resisted");
|
||||||
|
+ CustomStatistic DAMAGE_TAKEN = get("damage_taken");
|
||||||
|
+ CustomStatistic DAMAGE_BLOCKED_BY_SHIELD = get("damage_blocked_by_shield");
|
||||||
|
+ CustomStatistic DAMAGE_ABSORBED = get("damage_absorbed");
|
||||||
|
+ CustomStatistic DAMAGE_RESISTED = get("damage_resisted");
|
||||||
|
+ CustomStatistic DEATHS = get("deaths");
|
||||||
|
+ CustomStatistic MOB_KILLS = get("mob_kills");
|
||||||
|
+ CustomStatistic ANIMALS_BRED = get("animals_bred");
|
||||||
|
+ CustomStatistic PLAYER_KILLS = get("player_kills");
|
||||||
|
+ CustomStatistic FISH_CAUGHT = get("fish_caught");
|
||||||
|
+ CustomStatistic TALKED_TO_VILLAGER = get("talked_to_villager");
|
||||||
|
+ CustomStatistic TRADED_WITH_VILLAGER = get("traded_with_villager");
|
||||||
|
+ CustomStatistic EAT_CAKE_SLICE = get("eat_cake_slice");
|
||||||
|
+ CustomStatistic FILL_CAULDRON = get("fill_cauldron");
|
||||||
|
+ CustomStatistic USE_CAULDRON = get("use_cauldron");
|
||||||
|
+ CustomStatistic CLEAN_ARMOR = get("clean_armor");
|
||||||
|
+ CustomStatistic CLEAN_BANNER = get("clean_banner");
|
||||||
|
+ CustomStatistic CLEAN_SHULKER_BOX = get("clean_shulker_box");
|
||||||
|
+ CustomStatistic INTERACT_WITH_BREWINGSTAND = get("interact_with_brewingstand");
|
||||||
|
+ CustomStatistic INTERACT_WITH_BEACON = get("interact_with_beacon");
|
||||||
|
+ CustomStatistic INSPECT_DROPPER = get("inspect_dropper");
|
||||||
|
+ CustomStatistic INSPECT_HOPPER = get("inspect_hopper");
|
||||||
|
+ CustomStatistic INSPECT_DISPENSER = get("inspect_dispenser");
|
||||||
|
+ CustomStatistic PLAY_NOTEBLOCK = get("play_noteblock");
|
||||||
|
+ CustomStatistic TUNE_NOTEBLOCK = get("tune_noteblock");
|
||||||
|
+ CustomStatistic POT_FLOWER = get("pot_flower");
|
||||||
|
+ CustomStatistic TRIGGER_TRAPPED_CHEST = get("trigger_trapped_chest");
|
||||||
|
+ CustomStatistic OPEN_ENDERCHEST = get("open_enderchest");
|
||||||
|
+ CustomStatistic ENCHANT_ITEM = get("enchant_item");
|
||||||
|
+ CustomStatistic PLAY_RECORD = get("play_record");
|
||||||
|
+ CustomStatistic INTERACT_WITH_FURNACE = get("interact_with_furnace");
|
||||||
|
+ CustomStatistic INTERACT_WITH_CRAFTING_TABLE = get("interact_with_crafting_table");
|
||||||
|
+ CustomStatistic OPEN_CHEST = get("open_chest");
|
||||||
|
+ CustomStatistic SLEEP_IN_BED = get("sleep_in_bed");
|
||||||
|
+ CustomStatistic OPEN_SHULKER_BOX = get("open_shulker_box");
|
||||||
|
+ CustomStatistic OPEN_BARREL = get("open_barrel");
|
||||||
|
+ CustomStatistic INTERACT_WITH_BLAST_FURNACE = get("interact_with_blast_furnace");
|
||||||
|
+ CustomStatistic INTERACT_WITH_SMOKER = get("interact_with_smoker");
|
||||||
|
+ CustomStatistic INTERACT_WITH_LECTERN = get("interact_with_lectern");
|
||||||
|
+ CustomStatistic INTERACT_WITH_CAMPFIRE = get("interact_with_campfire");
|
||||||
|
+ CustomStatistic INTERACT_WITH_CARTOGRAPHY_TABLE = get("interact_with_cartography_table");
|
||||||
|
+ CustomStatistic INTERACT_WITH_LOOM = get("interact_with_loom");
|
||||||
|
+ CustomStatistic INTERACT_WITH_STONECUTTER = get("interact_with_stonecutter");
|
||||||
|
+ CustomStatistic BELL_RING = get("bell_ring");
|
||||||
|
+ CustomStatistic RAID_TRIGGER = get("raid_trigger");
|
||||||
|
+ CustomStatistic RAID_WIN = get("raid_win");
|
||||||
|
+ CustomStatistic INTERACT_WITH_ANVIL = get("interact_with_anvil");
|
||||||
|
+ CustomStatistic INTERACT_WITH_GRINDSTONE = get("interact_with_grindstone");
|
||||||
|
+ CustomStatistic TARGET_HIT = get("target_hit");
|
||||||
|
+ CustomStatistic INTERACT_WITH_SMITHING_TABLE = get("interact_with_smithing_table");
|
||||||
|
+
|
||||||
|
+ private static CustomStatistic get(final String key) {
|
||||||
|
+ return Registry.CUSTOM_STATISTIC.get(NamespacedKey.minecraft(key));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the actual statistic for this custom stat.
|
||||||
|
+ *
|
||||||
|
+ * @return the actual statistic
|
||||||
|
+ */
|
||||||
|
+ @NotNull Statistic<CustomStatistic> statistic();
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/statistic/Statistic.java b/src/main/java/io/papermc/paper/statistic/Statistic.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..3cf244593dceb8e457e7faab72b26f31b3f2cd28
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/statistic/Statistic.java
|
||||||
|
@@ -0,0 +1,40 @@
|
||||||
|
+package io.papermc.paper.statistic;
|
||||||
|
+
|
||||||
|
+import org.bukkit.Keyed;
|
||||||
|
+import org.bukkit.scoreboard.Criteria;
|
||||||
|
+import org.bukkit.scoreboard.RenderType;
|
||||||
|
+import org.jetbrains.annotations.ApiStatus;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Represents an individual statistic
|
||||||
|
+ *
|
||||||
|
+ * @param <S> stat (one of {@link org.bukkit.entity.EntityType}, {@link org.bukkit.Material} or {@link CustomStatistic}).
|
||||||
|
+ */
|
||||||
|
+@ApiStatus.NonExtendable
|
||||||
|
+public interface Statistic<S extends Keyed> extends Criteria {
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the statistic.
|
||||||
|
+ *
|
||||||
|
+ * @return the stat
|
||||||
|
+ */
|
||||||
|
+ @NotNull S value();
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Get the stat type.
|
||||||
|
+ *
|
||||||
|
+ * @return the stat type
|
||||||
|
+ */
|
||||||
|
+ @NotNull StatisticType<S> type();
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ default boolean isReadOnly() {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ default @NotNull RenderType getDefaultRenderType() {
|
||||||
|
+ return RenderType.INTEGER;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/statistic/StatisticType.java b/src/main/java/io/papermc/paper/statistic/StatisticType.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..c3ffd55c3cabe66a9a2e9a1872c25000c06f7042
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/statistic/StatisticType.java
|
||||||
|
@@ -0,0 +1,60 @@
|
||||||
|
+package io.papermc.paper.statistic;
|
||||||
|
+
|
||||||
|
+import java.util.HashMap;
|
||||||
|
+import java.util.Map;
|
||||||
|
+import net.kyori.adventure.translation.Translatable;
|
||||||
|
+import org.bukkit.Keyed;
|
||||||
|
+import org.bukkit.Material;
|
||||||
|
+import org.bukkit.NamespacedKey;
|
||||||
|
+import org.bukkit.Registry;
|
||||||
|
+import org.bukkit.entity.EntityType;
|
||||||
|
+import org.jetbrains.annotations.ApiStatus;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+
|
||||||
|
+@ApiStatus.NonExtendable
|
||||||
|
+public interface StatisticType<S extends Keyed> extends Keyed, Translatable {
|
||||||
|
+
|
||||||
|
+ Map<NamespacedKey, StatisticType<?>> STATISTIC_TYPE_MAP = new HashMap<>();
|
||||||
|
+
|
||||||
|
+ StatisticType<Material> BLOCK_MINED = get("mined");
|
||||||
|
+ StatisticType<Material> ITEM_CRAFTED = get("crafted");
|
||||||
|
+ StatisticType<Material> ITEM_USED = get("used");
|
||||||
|
+ StatisticType<Material> ITEM_BROKEN = get("broken");
|
||||||
|
+ StatisticType<Material> ITEM_PICKED_UP = get("picked_up");
|
||||||
|
+ StatisticType<Material> ITEM_DROPPED = get("dropped");
|
||||||
|
+ StatisticType<EntityType> ENTITY_KILLED = get("killed");
|
||||||
|
+ StatisticType<EntityType> ENTITY_KILLED_BY = get("killed_by");
|
||||||
|
+ StatisticType<CustomStatistic> CUSTOM = get("custom");
|
||||||
|
+
|
||||||
|
+ @SuppressWarnings("unchecked")
|
||||||
|
+ private static <S extends Keyed> StatisticType<S> get(final String key) {
|
||||||
|
+ return (StatisticType<S>) Registry.STATISTIC_TYPE.get(NamespacedKey.minecraft(key));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Creates or gets the statistic from this type for the specified value.
|
||||||
|
+ *
|
||||||
|
+ * @param value what you want the stat of
|
||||||
|
+ * @return the statistic for that thing
|
||||||
|
+ * @throws IllegalArgumentException if the thing is not valid for this {@link StatisticType}
|
||||||
|
+ */
|
||||||
|
+ @NotNull Statistic<S> of(@NotNull S value);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the registry associated with this stat type.
|
||||||
|
+ *
|
||||||
|
+ * @return the registry
|
||||||
|
+ */
|
||||||
|
+ @NotNull Registry<S> registry();
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * {@inheritDoc}
|
||||||
|
+ * <p>
|
||||||
|
+ * {@link StatisticType#CUSTOM} does <b>NOT</b> have a
|
||||||
|
+ * translation key.
|
||||||
|
+ * @throws IllegalArgumentException if used with {@link StatisticType#CUSTOM}
|
||||||
|
+ * @see CustomStatistic#translationKey()
|
||||||
|
+ */
|
||||||
|
+ @Override
|
||||||
|
+ @NotNull String translationKey();
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||||
|
index bce07d84cafca677bb6fad78c21b82097f06430c..f3b41836057dacea93c5b084f97c1587148cfacf 100644
|
||||||
|
--- a/src/main/java/org/bukkit/OfflinePlayer.java
|
||||||
|
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||||
|
@@ -270,6 +270,79 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @return last seen time
|
||||||
|
*/
|
||||||
|
public long getLastSeen();
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Decrements the given stat for this player.
|
||||||
|
+ * <p>
|
||||||
|
+ * This is equivalent to the following code: {@code decrementStatistic(Statistic, 1)}
|
||||||
|
+ *
|
||||||
|
+ * @param statistic the stat to decrement
|
||||||
|
+ * @throws IllegalArgumentException if the stat is invalid OR decreasing the stat value would put the stat below 0
|
||||||
|
+ */
|
||||||
|
+ default void decrementStatistic(@NotNull io.papermc.paper.statistic.Statistic<?> statistic) {
|
||||||
|
+ this.decrementStatistic(statistic, 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Increments the given stat for this player.
|
||||||
|
+ * <p>
|
||||||
|
+ * This is equivalent to the following code: {@code incrementStatistic(Statistic, 1)}
|
||||||
|
+ *
|
||||||
|
+ * @param statistic the stat to increment
|
||||||
|
+ * @throws IllegalArgumentException if the stat is invalid
|
||||||
|
+ */
|
||||||
|
+ default void incrementStatistic(@NotNull io.papermc.paper.statistic.Statistic<?> statistic) {
|
||||||
|
+ this.incrementStatistic(statistic, 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Decrements the given stat for this player.
|
||||||
|
+ *
|
||||||
|
+ * @param statistic the stat to decrement
|
||||||
|
+ * @param amount the value to decrement by
|
||||||
|
+ * @throws IllegalArgumentException if the stat is invalid, the amount is nonpositive, or the stat
|
||||||
|
+ * would have a negative value after decrementing it
|
||||||
|
+ */
|
||||||
|
+ default void decrementStatistic(@NotNull io.papermc.paper.statistic.Statistic<?> statistic, int amount) {
|
||||||
|
+ this.incrementStatistic(statistic, -amount);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Increments the given stat for this player.
|
||||||
|
+ *
|
||||||
|
+ * @param statistic the stat to increment
|
||||||
|
+ * @param amount the amount to increment by
|
||||||
|
+ * @throws IllegalArgumentException if the stat is invalid or the amount is nonpositive
|
||||||
|
+ */
|
||||||
|
+ public void incrementStatistic(@NotNull io.papermc.paper.statistic.Statistic<?> statistic, int amount);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Sets the given stat for this player.
|
||||||
|
+ *
|
||||||
|
+ * @param statistic the stat to set
|
||||||
|
+ * @param newAmount the value to set the stat to
|
||||||
|
+ * @throws IllegalArgumentException if the stat is invalid or the amount is negative
|
||||||
|
+ */
|
||||||
|
+ public void setStatistic(@NotNull io.papermc.paper.statistic.Statistic<?> statistic, int newAmount);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the given stat for this player.
|
||||||
|
+ *
|
||||||
|
+ * @param statistic the stat to get
|
||||||
|
+ * @return the amount for the stat
|
||||||
|
+ * @throws IllegalArgumentException if the stat is invalid
|
||||||
|
+ */
|
||||||
|
+ public int getStatistic(@NotNull io.papermc.paper.statistic.Statistic<?> statistic);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Get the formatted value for this stat. This is how the stat might
|
||||||
|
+ * appear in the client's statistic window
|
||||||
|
+ *
|
||||||
|
+ * @param statistic the stat to get the formatted value for
|
||||||
|
+ * @return the formatted value
|
||||||
|
+ * @throws IllegalArgumentException if the stat is invalid
|
||||||
|
+ */
|
||||||
|
+ public @NotNull String getFormattedValue(@NotNull io.papermc.paper.statistic.Statistic<?> statistic);
|
||||||
|
// Paper end
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -282,7 +355,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if statistic is null
|
||||||
|
* @throws IllegalArgumentException if the statistic requires an
|
||||||
|
* additional parameter
|
||||||
|
+ * @deprecated use {@link #incrementStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void incrementStatistic(@NotNull Statistic statistic) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -295,7 +370,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if statistic is null
|
||||||
|
* @throws IllegalArgumentException if the statistic requires an
|
||||||
|
* additional parameter
|
||||||
|
+ * @deprecated use {@link #decrementStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void decrementStatistic(@NotNull Statistic statistic) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -307,7 +384,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if amount is negative
|
||||||
|
* @throws IllegalArgumentException if the statistic requires an
|
||||||
|
* additional parameter
|
||||||
|
+ * @deprecated use {@link #incrementStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void incrementStatistic(@NotNull Statistic statistic, int amount) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -319,7 +398,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if amount is negative
|
||||||
|
* @throws IllegalArgumentException if the statistic requires an
|
||||||
|
* additional parameter
|
||||||
|
+ * @deprecated use {@link #decrementStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void decrementStatistic(@NotNull Statistic statistic, int amount) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -331,7 +412,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if newValue is negative
|
||||||
|
* @throws IllegalArgumentException if the statistic requires an
|
||||||
|
* additional parameter
|
||||||
|
+ * @deprecated use {@link #setStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void setStatistic(@NotNull Statistic statistic, int newValue) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -342,7 +425,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if statistic is null
|
||||||
|
* @throws IllegalArgumentException if the statistic requires an
|
||||||
|
* additional parameter
|
||||||
|
+ * @deprecated use {@link #getStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public int getStatistic(@NotNull Statistic statistic) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -357,7 +442,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if material is null
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #incrementStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void incrementStatistic(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -372,7 +459,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if material is null
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #decrementStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void decrementStatistic(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -385,7 +474,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if material is null
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #getStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public int getStatistic(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -399,7 +490,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if amount is negative
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #incrementStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void incrementStatistic(@NotNull Statistic statistic, @NotNull Material material, int amount) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -413,7 +506,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if amount is negative
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #decrementStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void decrementStatistic(@NotNull Statistic statistic, @NotNull Material material, int amount) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -427,7 +522,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if newValue is negative
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #setStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void setStatistic(@NotNull Statistic statistic, @NotNull Material material, int newValue) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -442,7 +539,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if entityType is null
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #incrementStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void incrementStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -457,7 +556,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if entityType is null
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #decrementStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void decrementStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -470,7 +571,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if entityType is null
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #getStatistic(io.papermc.paper.statistic.Statistic)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public int getStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -484,7 +587,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if amount is negative
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #incrementStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void incrementStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType, int amount) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -498,7 +603,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if amount is negative
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #decrementStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void decrementStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType, int amount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -512,7 +619,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||||
|
* @throws IllegalArgumentException if newValue is negative
|
||||||
|
* @throws IllegalArgumentException if the given parameter is not valid
|
||||||
|
* for the statistic
|
||||||
|
+ * @deprecated use {@link #setStatistic(io.papermc.paper.statistic.Statistic, int)}
|
||||||
|
*/
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public void setStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType, int newValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
|
||||||
|
index 800d23bb249e19d5cf924e7ba36684068624da02..f13315d196f2fda14ddeb5590b875ef6b4be890c 100644
|
||||||
|
--- a/src/main/java/org/bukkit/Registry.java
|
||||||
|
+++ b/src/main/java/org/bukkit/Registry.java
|
||||||
|
@@ -173,7 +173,9 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
||||||
|
* Server statistics.
|
||||||
|
*
|
||||||
|
* @see Statistic
|
||||||
|
+ * @deprecated use {@link #CUSTOM_STATISTIC} and {@link #STATISTIC_TYPE}
|
||||||
|
*/
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
Registry<Statistic> STATISTIC = new SimpleRegistry<>(Statistic.class);
|
||||||
|
/**
|
||||||
|
* Server structures.
|
||||||
|
@@ -296,6 +298,20 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
||||||
|
return StreamSupport.stream(this.spliterator(), false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
+ /**
|
||||||
|
+ * Custom statistics
|
||||||
|
+ *
|
||||||
|
+ * @see io.papermc.paper.statistic.CustomStatistic
|
||||||
|
+ */
|
||||||
|
+ Registry<io.papermc.paper.statistic.CustomStatistic> CUSTOM_STATISTIC = java.util.Objects.requireNonNull(org.bukkit.Bukkit.getRegistry(io.papermc.paper.statistic.CustomStatistic.class));
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Statistic types
|
||||||
|
+ *
|
||||||
|
+ * @see io.papermc.paper.statistic.StatisticType
|
||||||
|
+ */
|
||||||
|
+ @SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
+ Registry<io.papermc.paper.statistic.StatisticType<?>> STATISTIC_TYPE = java.util.Objects.requireNonNull(org.bukkit.Bukkit.getRegistry((Class<io.papermc.paper.statistic.StatisticType<?>>) (Class) io.papermc.paper.statistic.StatisticType.class));
|
||||||
|
// Paper end
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/src/main/java/org/bukkit/Statistic.java b/src/main/java/org/bukkit/Statistic.java
|
||||||
|
index 4ce888688d04eb0c4b2261a6474df870e7d2bb00..c2fe6c8e518a8a1b85c2582ae3887e3e09eccb36 100644
|
||||||
|
--- a/src/main/java/org/bukkit/Statistic.java
|
||||||
|
+++ b/src/main/java/org/bukkit/Statistic.java
|
||||||
|
@@ -5,7 +5,9 @@ import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a countable statistic, which is tracked by the server.
|
||||||
|
+ * @deprecated use {@link io.papermc.paper.statistic.StatisticType} and {@link io.papermc.paper.statistic.Statistic}
|
||||||
|
*/
|
||||||
|
+@Deprecated(forRemoval = true) // Paper
|
||||||
|
public enum Statistic implements Keyed {
|
||||||
|
DAMAGE_DEALT,
|
||||||
|
DAMAGE_TAKEN,
|
||||||
|
@@ -152,7 +154,9 @@ public enum Statistic implements Keyed {
|
||||||
|
/**
|
||||||
|
* The type of statistic.
|
||||||
|
*
|
||||||
|
+ * @deprecated use {@link io.papermc.paper.statistic.StatisticType}
|
||||||
|
*/
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public enum Type {
|
||||||
|
/**
|
||||||
|
* Statistics of this type do not require a qualifier.
|
||||||
|
@@ -174,4 +178,65 @@ public enum Statistic implements Keyed {
|
||||||
|
*/
|
||||||
|
ENTITY;
|
||||||
|
}
|
||||||
|
+ // Paper start - add legacy conversion methods
|
||||||
|
+ @Deprecated(forRemoval = true)
|
||||||
|
+ public static Statistic toLegacy(final io.papermc.paper.statistic.Statistic<?> stat) {
|
||||||
|
+ if (stat.type() == io.papermc.paper.statistic.StatisticType.CUSTOM && stat.value() instanceof final io.papermc.paper.statistic.CustomStatistic customStatistic) {
|
||||||
|
+ if (customStatistic == io.papermc.paper.statistic.CustomStatistic.PLAY_TIME) { // special case cause upstream is wrong
|
||||||
|
+ return org.bukkit.Statistic.PLAY_ONE_MINUTE;
|
||||||
|
+ } else {
|
||||||
|
+ return java.util.Objects.requireNonNull(org.bukkit.Registry.STATISTIC.get(customStatistic.getKey()), "Couldn't convert " + stat + " to a legacy stat");
|
||||||
|
+ }
|
||||||
|
+ } else if (stat.type() == io.papermc.paper.statistic.StatisticType.BLOCK_MINED) {
|
||||||
|
+ return Statistic.MINE_BLOCK;
|
||||||
|
+ } else if (stat.type() == io.papermc.paper.statistic.StatisticType.ITEM_BROKEN) {
|
||||||
|
+ return Statistic.BREAK_ITEM;
|
||||||
|
+ } else if (stat.type() == io.papermc.paper.statistic.StatisticType.ITEM_CRAFTED) {
|
||||||
|
+ return Statistic.CRAFT_ITEM;
|
||||||
|
+ } else if (stat.type() == io.papermc.paper.statistic.StatisticType.ITEM_DROPPED) {
|
||||||
|
+ return Statistic.DROP;
|
||||||
|
+ } else if (stat.type() == io.papermc.paper.statistic.StatisticType.ITEM_USED) {
|
||||||
|
+ return Statistic.USE_ITEM;
|
||||||
|
+ } else if (stat.type() == io.papermc.paper.statistic.StatisticType.ITEM_PICKED_UP) {
|
||||||
|
+ return Statistic.PICKUP;
|
||||||
|
+ } else if (stat.type() == io.papermc.paper.statistic.StatisticType.ENTITY_KILLED) {
|
||||||
|
+ return Statistic.KILL_ENTITY;
|
||||||
|
+ } else if (stat.type() == io.papermc.paper.statistic.StatisticType.ENTITY_KILLED_BY) {
|
||||||
|
+ return Statistic.ENTITY_KILLED_BY;
|
||||||
|
+ }
|
||||||
|
+ throw new IllegalArgumentException("Couldn't convert " + stat + " to a legacy stat");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Deprecated(forRemoval = true)
|
||||||
|
+ public io.papermc.paper.statistic.Statistic<?> toModern(@org.jetbrains.annotations.Nullable org.bukkit.entity.EntityType entityType, @org.jetbrains.annotations.Nullable Material material) {
|
||||||
|
+ com.google.common.base.Preconditions.checkArgument(entityType == null || material == null, "No stat has an entity type and material value at the same time");
|
||||||
|
+ com.google.common.base.Preconditions.checkArgument(this.type != Type.UNTYPED || (entityType == null && material == null), "no value needed for untyped stats");
|
||||||
|
+ com.google.common.base.Preconditions.checkArgument(this.type != Type.ENTITY || entityType != null);
|
||||||
|
+ com.google.common.base.Preconditions.checkArgument(this.type != Type.BLOCK || material != null && material.isBlock());
|
||||||
|
+ com.google.common.base.Preconditions.checkArgument(this.type != Type.ITEM || material != null && material.isItem());
|
||||||
|
+ return switch (this.type) {
|
||||||
|
+ case UNTYPED -> {
|
||||||
|
+ if (this == PLAY_ONE_MINUTE) { // special case cause upstream is wrong
|
||||||
|
+ yield io.papermc.paper.statistic.CustomStatistic.PLAY_TIME.statistic();
|
||||||
|
+ } else {
|
||||||
|
+ yield java.util.Objects.requireNonNull(Registry.CUSTOM_STATISTIC.get(this.key), "Couldn't convert " + this + " to a modern stat").statistic();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ case BLOCK -> io.papermc.paper.statistic.StatisticType.BLOCK_MINED.of(material);
|
||||||
|
+ case ITEM -> switch (this) {
|
||||||
|
+ case DROP -> io.papermc.paper.statistic.StatisticType.ITEM_DROPPED.of(material);
|
||||||
|
+ case BREAK_ITEM -> io.papermc.paper.statistic.StatisticType.ITEM_BROKEN.of(material);
|
||||||
|
+ case CRAFT_ITEM -> io.papermc.paper.statistic.StatisticType.ITEM_CRAFTED.of(material);
|
||||||
|
+ case USE_ITEM -> io.papermc.paper.statistic.StatisticType.ITEM_USED.of(material);
|
||||||
|
+ case PICKUP -> io.papermc.paper.statistic.StatisticType.ITEM_PICKED_UP.of(material);
|
||||||
|
+ default -> throw new IllegalArgumentException("Couldn't convert " + this + ", mat: " + material + " to a modern stat");
|
||||||
|
+ };
|
||||||
|
+ case ENTITY -> switch (this) {
|
||||||
|
+ case KILL_ENTITY -> io.papermc.paper.statistic.StatisticType.ENTITY_KILLED.of(entityType);
|
||||||
|
+ case ENTITY_KILLED_BY -> io.papermc.paper.statistic.StatisticType.ENTITY_KILLED_BY.of(entityType);
|
||||||
|
+ default -> throw new IllegalArgumentException("Couldn't convert " + this + ", entity_type: " + entityType + " to a modern stat");
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/org/bukkit/event/player/PlayerStatisticIncrementEvent.java b/src/main/java/org/bukkit/event/player/PlayerStatisticIncrementEvent.java
|
||||||
|
index f971844bf490c7a7bfbe305d33df739ed2197a37..ef36f8f1fe2b793870c6ca82eaf48612deb1e59d 100644
|
||||||
|
--- a/src/main/java/org/bukkit/event/player/PlayerStatisticIncrementEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/player/PlayerStatisticIncrementEvent.java
|
||||||
|
@@ -18,48 +18,75 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
*/
|
||||||
|
public class PlayerStatisticIncrementEvent extends PlayerEvent implements Cancellable {
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
- protected final Statistic statistic;
|
||||||
|
+ private final io.papermc.paper.statistic.Statistic<?> statistic; // Paper
|
||||||
|
private final int initialValue;
|
||||||
|
private final int newValue;
|
||||||
|
private boolean isCancelled = false;
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
private final EntityType entityType;
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
private final Material material;
|
||||||
|
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public PlayerStatisticIncrementEvent(@NotNull Player player, @NotNull Statistic statistic, int initialValue, int newValue) {
|
||||||
|
super(player);
|
||||||
|
- this.statistic = statistic;
|
||||||
|
+ this.statistic = statistic.toModern(null, null); // Paper
|
||||||
|
this.initialValue = initialValue;
|
||||||
|
this.newValue = newValue;
|
||||||
|
this.entityType = null;
|
||||||
|
this.material = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public PlayerStatisticIncrementEvent(@NotNull Player player, @NotNull Statistic statistic, int initialValue, int newValue, @NotNull EntityType entityType) {
|
||||||
|
super(player);
|
||||||
|
- this.statistic = statistic;
|
||||||
|
+ this.statistic = statistic.toModern(entityType, null); // Paper
|
||||||
|
this.initialValue = initialValue;
|
||||||
|
this.newValue = newValue;
|
||||||
|
this.entityType = entityType;
|
||||||
|
this.material = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public PlayerStatisticIncrementEvent(@NotNull Player player, @NotNull Statistic statistic, int initialValue, int newValue, @NotNull Material material) {
|
||||||
|
super(player);
|
||||||
|
- this.statistic = statistic;
|
||||||
|
+ this.statistic = statistic.toModern(null, material); // Paper
|
||||||
|
this.initialValue = initialValue;
|
||||||
|
this.newValue = newValue;
|
||||||
|
this.entityType = null;
|
||||||
|
this.material = material;
|
||||||
|
}
|
||||||
|
+ // Paper start
|
||||||
|
+ @org.jetbrains.annotations.ApiStatus.Internal
|
||||||
|
+ public PlayerStatisticIncrementEvent(@NotNull Player player, @NotNull io.papermc.paper.statistic.Statistic<?> statistic, int initialValue, int newValue) {
|
||||||
|
+ super(player);
|
||||||
|
+ this.statistic = statistic;
|
||||||
|
+ this.initialValue = initialValue;
|
||||||
|
+ this.newValue = newValue;
|
||||||
|
+ this.entityType = statistic.value() instanceof EntityType entityType ? entityType : null;
|
||||||
|
+ this.material = statistic.value() instanceof Material material ? material : null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the statistic that is being incremented.
|
||||||
|
+ *
|
||||||
|
+ * @return the incremented statistic
|
||||||
|
+ */
|
||||||
|
+ public @NotNull io.papermc.paper.statistic.Statistic<?> getStat() {
|
||||||
|
+ return this.statistic;
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the statistic that is being incremented.
|
||||||
|
*
|
||||||
|
* @return the incremented statistic
|
||||||
|
+ * @deprecated use {@link #getStat()}
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public Statistic getStatistic() {
|
||||||
|
- return statistic;
|
||||||
|
+ return Statistic.toLegacy(this.statistic); // Paper
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -85,8 +112,10 @@ public class PlayerStatisticIncrementEvent extends PlayerEvent implements Cancel
|
||||||
|
* entity statistic otherwise returns null.
|
||||||
|
*
|
||||||
|
* @return the EntityType of the statistic
|
||||||
|
+ * @deprecated use {@link #getStat()}
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public EntityType getEntityType() {
|
||||||
|
return entityType;
|
||||||
|
}
|
||||||
|
@@ -96,8 +125,10 @@ public class PlayerStatisticIncrementEvent extends PlayerEvent implements Cancel
|
||||||
|
* or item statistic otherwise returns null.
|
||||||
|
*
|
||||||
|
* @return the Material of the statistic
|
||||||
|
+ * @deprecated use {@link #getStat()}
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/org/bukkit/scoreboard/Criteria.java b/src/main/java/org/bukkit/scoreboard/Criteria.java
|
||||||
|
index 3bc3abaf093d13e22b6ac2ee59ab584c92b4666a..56cf36b696062490de2adb68c796c5bb74732b0c 100644
|
||||||
|
--- a/src/main/java/org/bukkit/scoreboard/Criteria.java
|
||||||
|
+++ b/src/main/java/org/bukkit/scoreboard/Criteria.java
|
||||||
|
@@ -12,8 +12,8 @@ import org.jetbrains.annotations.NotNull;
|
||||||
|
* Represents a scoreboard criteria, either custom or built-in to the Minecraft server, used to
|
||||||
|
* keep track of and manually or automatically change scores on a scoreboard.
|
||||||
|
* <p>
|
||||||
|
- * While this class outlines constants for standard criteria, see {@link #statistic(Statistic)}
|
||||||
|
- * (and its overloads) to create instances for statistically-backed criteria.
|
||||||
|
+ * While this class outlines constants for standard criteria, see {@link io.papermc.paper.statistic.Statistic}
|
||||||
|
+ * for statistically-backed criteria.
|
||||||
|
*/
|
||||||
|
public interface Criteria {
|
||||||
|
|
||||||
|
@@ -241,8 +241,10 @@ public interface Criteria {
|
||||||
|
* {@link Material#isBlock()} is false
|
||||||
|
* @throws IllegalArgumentException if {@link Statistic#getType()} is {@link Type#ITEM}, but
|
||||||
|
* {@link Material#isItem()} is false
|
||||||
|
+ * @deprecated use {@link io.papermc.paper.statistic.Statistic}
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
+ @Deprecated // Paper
|
||||||
|
public static Criteria statistic(@NotNull Statistic statistic, @NotNull Material material) {
|
||||||
|
Preconditions.checkArgument(statistic != null, "statistic must not be null");
|
||||||
|
Preconditions.checkArgument(material != null, "material must not be null");
|
||||||
|
@@ -298,8 +300,10 @@ public interface Criteria {
|
||||||
|
* @param entityType the relevant entity type
|
||||||
|
* @return the criteria
|
||||||
|
* @throws IllegalArgumentException if {@link Statistic#getType()} is not {@link Type#ENTITY}
|
||||||
|
+ * @deprecated use {@link io.papermc.paper.statistic.Statistic}
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public static Criteria statistic(@NotNull Statistic statistic, @NotNull EntityType entityType) {
|
||||||
|
Preconditions.checkArgument(statistic != null, "statistic must not be null");
|
||||||
|
Preconditions.checkArgument(entityType != null, "entityType must not be null");
|
||||||
|
@@ -331,8 +335,10 @@ public interface Criteria {
|
||||||
|
*
|
||||||
|
* @param statistic the statistic for which to get a criteria
|
||||||
|
* @return the criteria
|
||||||
|
+ * @deprecated Use {@link io.papermc.paper.statistic.Statistic}
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
+ @Deprecated(forRemoval = true) // Paper
|
||||||
|
public static Criteria statistic(@NotNull Statistic statistic) {
|
||||||
|
Preconditions.checkArgument(statistic != null, "statistic must not be null");
|
||||||
|
return Bukkit.getScoreboardCriteria(org.bukkit.Bukkit.getUnsafe().getStatisticCriteriaKey(statistic)); // Paper
|
|
@ -0,0 +1,735 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||||
|
Date: Thu, 20 May 2021 01:10:15 -0700
|
||||||
|
Subject: [PATCH] Better Stats API
|
||||||
|
|
||||||
|
== AT ==
|
||||||
|
public net.minecraft.stats.StatType map
|
||||||
|
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/statistic/PaperCustomStatistic.java b/src/main/java/io/papermc/paper/statistic/PaperCustomStatistic.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..c70300fb84918739190325946f26fd5231f3c0e0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/statistic/PaperCustomStatistic.java
|
||||||
|
@@ -0,0 +1,36 @@
|
||||||
|
+package io.papermc.paper.statistic;
|
||||||
|
+
|
||||||
|
+import net.minecraft.resources.ResourceLocation;
|
||||||
|
+import org.bukkit.NamespacedKey;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+
|
||||||
|
+public class PaperCustomStatistic implements CustomStatistic {
|
||||||
|
+
|
||||||
|
+ private final NamespacedKey key;
|
||||||
|
+ private final ResourceLocation nmsValue;
|
||||||
|
+
|
||||||
|
+ public PaperCustomStatistic(NamespacedKey key, ResourceLocation nmsValue) {
|
||||||
|
+ this.key = key;
|
||||||
|
+ this.nmsValue = nmsValue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @NotNull NamespacedKey getKey() {
|
||||||
|
+ return this.key;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @NotNull String translationKey() {
|
||||||
|
+ return "stat." + this.nmsValue.toString().replace(':', '.');
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @NotNull Statistic<CustomStatistic> statistic() {
|
||||||
|
+ return StatisticType.CUSTOM.of(this);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @NotNull String toString() {
|
||||||
|
+ return this.getKey().asString();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/statistic/PaperStatistic.java b/src/main/java/io/papermc/paper/statistic/PaperStatistic.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..5e44ffc5788883f659505db54258ed2a50f2aa15
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/statistic/PaperStatistic.java
|
||||||
|
@@ -0,0 +1,39 @@
|
||||||
|
+package io.papermc.paper.statistic;
|
||||||
|
+
|
||||||
|
+import net.minecraft.stats.Stat;
|
||||||
|
+import org.bukkit.Keyed;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+
|
||||||
|
+public class PaperStatistic<S extends Keyed, M> implements Statistic<S> {
|
||||||
|
+
|
||||||
|
+ private final Stat<M> handle;
|
||||||
|
+ private final S value;
|
||||||
|
+ private final M nmsValue;
|
||||||
|
+ private final StatisticType<S> type;
|
||||||
|
+
|
||||||
|
+ PaperStatistic(Stat<M> handle, @NotNull S value, M nmsValue, @NotNull StatisticType<S> type) {
|
||||||
|
+ this.handle = handle;
|
||||||
|
+ this.value = value;
|
||||||
|
+ this.nmsValue = nmsValue;
|
||||||
|
+ this.type = type;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @NotNull S value() {
|
||||||
|
+ return this.value;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @NotNull StatisticType<S> type() {
|
||||||
|
+ return this.type;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @NotNull String getName() {
|
||||||
|
+ return Stat.buildName(this.handle.getType(),this.nmsValue);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public Stat<M> getHandle() {
|
||||||
|
+ return this.handle;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/statistic/PaperStatisticType.java b/src/main/java/io/papermc/paper/statistic/PaperStatisticType.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..2af5e257795f9b27028f9906676a1c8b75749b27
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/statistic/PaperStatisticType.java
|
||||||
|
@@ -0,0 +1,113 @@
|
||||||
|
+package io.papermc.paper.statistic;
|
||||||
|
+
|
||||||
|
+import com.google.common.base.Preconditions;
|
||||||
|
+import java.util.IdentityHashMap;
|
||||||
|
+import java.util.Map;
|
||||||
|
+import java.util.Objects;
|
||||||
|
+import java.util.function.Function;
|
||||||
|
+import java.util.function.Predicate;
|
||||||
|
+import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
+import net.minecraft.resources.ResourceLocation;
|
||||||
|
+import net.minecraft.stats.Stat;
|
||||||
|
+import net.minecraft.stats.StatType;
|
||||||
|
+import net.minecraft.stats.Stats;
|
||||||
|
+import net.minecraft.world.item.Item;
|
||||||
|
+import net.minecraft.world.level.block.Block;
|
||||||
|
+import org.bukkit.Keyed;
|
||||||
|
+import org.bukkit.Material;
|
||||||
|
+import org.bukkit.NamespacedKey;
|
||||||
|
+import org.bukkit.Registry;
|
||||||
|
+import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||||
|
+import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||||
|
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||||
|
+import org.bukkit.entity.EntityType;
|
||||||
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
+
|
||||||
|
+@DefaultQualifier(NonNull.class)
|
||||||
|
+public class PaperStatisticType<S extends Keyed, M> implements StatisticType<S> {
|
||||||
|
+
|
||||||
|
+ private final NamespacedKey key;
|
||||||
|
+ private final StatType<M> nmsType;
|
||||||
|
+ private final Registry<S> registry;
|
||||||
|
+ private final @Nullable Function<S, M> toNms;
|
||||||
|
+ private final Map<S, Statistic<S>> statisticMap;
|
||||||
|
+ private final Predicate<S> typeCheck;
|
||||||
|
+
|
||||||
|
+ @SuppressWarnings("unchecked")
|
||||||
|
+ public static <M> StatisticType<?> create(final NamespacedKey key, final StatType<M> type) {
|
||||||
|
+ if (type == Stats.BLOCK_MINED) {
|
||||||
|
+ return new PaperStatisticType<>(key, (StatType<Block>) type, Registry.MATERIAL, CraftMagicNumbers::getBlock, Material::isBlock);
|
||||||
|
+ } else if (type == Stats.ITEM_CRAFTED || type == Stats.ITEM_USED || type == Stats.ITEM_BROKEN || type == Stats.ITEM_PICKED_UP || type == Stats.ITEM_DROPPED) {
|
||||||
|
+ return new PaperStatisticType<>(key, (StatType<Item>) type, Registry.MATERIAL, CraftMagicNumbers::getItem, Material::isItem);
|
||||||
|
+ } else if (type == Stats.ENTITY_KILLED || type == Stats.ENTITY_KILLED_BY) {
|
||||||
|
+ return new PaperStatisticType<>(key, (StatType<net.minecraft.world.entity.EntityType<?>>) type, Registry.ENTITY_TYPE, CraftEntityType::bukkitToMinecraft, t -> t != EntityType.UNKNOWN);
|
||||||
|
+ } else if (type == Stats.CUSTOM) {
|
||||||
|
+ return new PaperStatisticType<>(key, (StatType<ResourceLocation>) type, Registry.CUSTOM_STATISTIC, null);
|
||||||
|
+ } else {
|
||||||
|
+ throw new IllegalArgumentException("Did not recognize " + BuiltInRegistries.STAT_TYPE.getKey(type) + " as a statistic type");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private PaperStatisticType(NamespacedKey key, StatType<M> nmsType, Registry<S> registry, @Nullable Function<S, M> toNms) {
|
||||||
|
+ this(key, nmsType, registry, toNms, s -> true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private PaperStatisticType(NamespacedKey key, StatType<M> nmsType, Registry<S> registry, @Nullable Function<S, M> toNms, Predicate<S> typeCheck) {
|
||||||
|
+ this.key = key;
|
||||||
|
+ this.nmsType = nmsType;
|
||||||
|
+ this.registry = registry;
|
||||||
|
+ this.toNms = toNms;
|
||||||
|
+ this.statisticMap = new IdentityHashMap<>();
|
||||||
|
+ this.typeCheck = typeCheck;
|
||||||
|
+ STATISTIC_TYPE_MAP.put(this.key, this);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public Statistic<S> of(S value) {
|
||||||
|
+ if (!this.typeCheck.test(value)) {
|
||||||
|
+ throw new IllegalArgumentException(value + " is not valid for " + this.getKey());
|
||||||
|
+ }
|
||||||
|
+ if (this == StatisticType.CUSTOM) {
|
||||||
|
+ return Objects.requireNonNull(this.statisticMap.get(value), "This should never be null as all custom stats should be present in this map upon initialization");
|
||||||
|
+ }
|
||||||
|
+ return this.statisticMap.computeIfAbsent(value, newValue -> {
|
||||||
|
+ final M nmsValue = Objects.requireNonNull(this.toNms).apply(value);
|
||||||
|
+ final Stat<M> nmsStat = this.nmsType.get(nmsValue);
|
||||||
|
+ return new PaperStatistic<>(nmsStat, value, nmsValue, this);
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @SuppressWarnings("unchecked")
|
||||||
|
+ public S registerCustomStatistic(S stat) {
|
||||||
|
+ if (this != StatisticType.CUSTOM) {
|
||||||
|
+ throw new IllegalArgumentException("Must be the CUSTOM_STATS stat type");
|
||||||
|
+ }
|
||||||
|
+ PaperStatisticType<CustomStatistic, ResourceLocation> cast = (PaperStatisticType<CustomStatistic, ResourceLocation>) this;
|
||||||
|
+ final Stat<ResourceLocation> nmsStat = cast.nmsType.get(CraftNamespacedKey.toMinecraft(stat.getKey()));
|
||||||
|
+ this.statisticMap.put(stat, new PaperStatistic<>(nmsStat, stat, CraftNamespacedKey.toMinecraft(stat.getKey()), this));
|
||||||
|
+ return stat;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public Registry<S> registry() {
|
||||||
|
+ return this.registry;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public NamespacedKey getKey() {
|
||||||
|
+ return this.key;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public String translationKey() {
|
||||||
|
+ Preconditions.checkArgument(this != StatisticType.CUSTOM, "CUSTOM_STATS does not have a translation key");
|
||||||
|
+ return "stat_type." + this.getKey().toString().replace(':', '.');
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public String toString() {
|
||||||
|
+ return this.key.toString();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/statistic/PaperStatistics.java b/src/main/java/io/papermc/paper/statistic/PaperStatistics.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..57bb4a61807c566036b1a594957c6ef243b1ce46
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/statistic/PaperStatistics.java
|
||||||
|
@@ -0,0 +1,99 @@
|
||||||
|
+package io.papermc.paper.statistic;
|
||||||
|
+
|
||||||
|
+import com.google.common.base.Preconditions;
|
||||||
|
+import java.util.Objects;
|
||||||
|
+import java.util.Set;
|
||||||
|
+import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
+import net.minecraft.resources.ResourceLocation;
|
||||||
|
+import net.minecraft.stats.ServerStatsCounter;
|
||||||
|
+import net.minecraft.stats.Stat;
|
||||||
|
+import net.minecraft.world.item.Item;
|
||||||
|
+import net.minecraft.world.level.block.Block;
|
||||||
|
+import org.bukkit.Material;
|
||||||
|
+import org.bukkit.Registry;
|
||||||
|
+import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||||
|
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||||
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
+
|
||||||
|
+@DefaultQualifier(NonNull.class)
|
||||||
|
+public final class PaperStatistics {
|
||||||
|
+
|
||||||
|
+ private PaperStatistics() {
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static final Set<CustomStatistic> IGNORED_STATS_FOR_EVENT = Set.of(
|
||||||
|
+ CustomStatistic.FALL_ONE_CM,
|
||||||
|
+ CustomStatistic.BOAT_ONE_CM,
|
||||||
|
+ CustomStatistic.CLIMB_ONE_CM,
|
||||||
|
+ CustomStatistic.WALK_ON_WATER_ONE_CM,
|
||||||
|
+ CustomStatistic.WALK_UNDER_WATER_ONE_CM,
|
||||||
|
+ CustomStatistic.FLY_ONE_CM,
|
||||||
|
+ CustomStatistic.HORSE_ONE_CM,
|
||||||
|
+ CustomStatistic.MINECART_ONE_CM,
|
||||||
|
+ CustomStatistic.PIG_ONE_CM,
|
||||||
|
+ CustomStatistic.PLAY_TIME,
|
||||||
|
+ CustomStatistic.SWIM_ONE_CM,
|
||||||
|
+ CustomStatistic.WALK_ONE_CM,
|
||||||
|
+ CustomStatistic.SPRINT_ONE_CM,
|
||||||
|
+ CustomStatistic.CROUCH_ONE_CM,
|
||||||
|
+ CustomStatistic.TIME_SINCE_DEATH,
|
||||||
|
+ CustomStatistic.SNEAK_TIME,
|
||||||
|
+ CustomStatistic.TOTAL_WORLD_TIME,
|
||||||
|
+ CustomStatistic.TIME_SINCE_REST,
|
||||||
|
+ CustomStatistic.AVIATE_ONE_CM,
|
||||||
|
+ CustomStatistic.STRIDER_ONE_CM
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ public static void changeStatistic(ServerStatsCounter manager, Statistic<?> statistic, int delta) {
|
||||||
|
+ if (delta == 0) return;
|
||||||
|
+ Preconditions.checkNotNull(statistic, "statistic cannot be null");
|
||||||
|
+ final Stat<?> stat = getNMSStatistic(statistic);
|
||||||
|
+ //noinspection ConstantConditions
|
||||||
|
+ manager.setValue(null, stat, manager.getValue(stat) + delta);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void setStatistic(ServerStatsCounter manager, Statistic<?> statistic, int newAmount) {
|
||||||
|
+ Preconditions.checkNotNull(statistic, "Statistic cannot be null");
|
||||||
|
+ Preconditions.checkArgument(newAmount >= 0, "New amount must be greater than or equal to 0");
|
||||||
|
+ //noinspection ConstantConditions
|
||||||
|
+ manager.setValue(null, getNMSStatistic(statistic), newAmount);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int getStatistic(ServerStatsCounter manager, Statistic<?> statistic) {
|
||||||
|
+ Preconditions.checkNotNull(statistic, "Statistic cannot be null");
|
||||||
|
+ return manager.getValue(getNMSStatistic(statistic));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static String getFormattedValue(ServerStatsCounter manager, Statistic<?> statistic) {
|
||||||
|
+ final Stat<?> nmsStat = getNMSStatistic(statistic);
|
||||||
|
+ return nmsStat.format(manager.getValue(nmsStat));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @SuppressWarnings("unchecked")
|
||||||
|
+ public static Statistic<?> getPaperStatistic(Stat<?> nmsStat) {
|
||||||
|
+ final ResourceLocation statTypeKey = Preconditions.checkNotNull(BuiltInRegistries.STAT_TYPE.getKey(nmsStat.getType()), "Could not get the stat type resource location from " + nmsStat);
|
||||||
|
+ final @Nullable StatisticType<?> type = Registry.STATISTIC_TYPE.get(CraftNamespacedKey.fromMinecraft(statTypeKey));
|
||||||
|
+ final Statistic<?> paperStat;
|
||||||
|
+ if (type == StatisticType.BLOCK_MINED) {
|
||||||
|
+ paperStat = StatisticType.BLOCK_MINED.of(CraftMagicNumbers.getMaterial((Block) nmsStat.getValue()));
|
||||||
|
+ } else if (type == StatisticType.ITEM_CRAFTED || type == StatisticType.ITEM_USED || type == StatisticType.ITEM_BROKEN || type == StatisticType.ITEM_PICKED_UP || type == StatisticType.ITEM_DROPPED) {
|
||||||
|
+ paperStat = ((StatisticType<Material>) type).of(CraftMagicNumbers.getMaterial((Item) nmsStat.getValue()));
|
||||||
|
+ } else if (type == StatisticType.ENTITY_KILLED) {
|
||||||
|
+ paperStat = StatisticType.ENTITY_KILLED.of(CraftMagicNumbers.getEntityType((net.minecraft.world.entity.EntityType<?>) nmsStat.getValue()));
|
||||||
|
+ } else if (type == StatisticType.ENTITY_KILLED_BY) {
|
||||||
|
+ paperStat = StatisticType.ENTITY_KILLED_BY.of(CraftMagicNumbers.getEntityType((net.minecraft.world.entity.EntityType<?>) nmsStat.getValue()));
|
||||||
|
+ } else if (type == StatisticType.CUSTOM) {
|
||||||
|
+ paperStat = StatisticType.CUSTOM.of(Objects.requireNonNull(Registry.CUSTOM_STATISTIC.get(CraftNamespacedKey.fromMinecraft((ResourceLocation) nmsStat.getValue()))));
|
||||||
|
+ } else {
|
||||||
|
+ throw new IllegalArgumentException("Did not recognize " + type + " as a statistic type");
|
||||||
|
+ }
|
||||||
|
+ return Objects.requireNonNull(paperStat, "Couldn't convert " + nmsStat + " to a stat of type " + type);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static Stat<?> getNMSStatistic(Statistic<?> paperStat) {
|
||||||
|
+ return ((PaperStatistic<?, ?>) paperStat).getHandle();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/net/minecraft/stats/ServerStatsCounter.java b/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
||||||
|
index 9bb8d4d7be6a937980aa653db82be084d066a563..4bc706cda11509edd0bc8da21718ba8bbfc41f9f 100644
|
||||||
|
--- a/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
||||||
|
+++ b/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
||||||
|
@@ -245,6 +245,20 @@ public class ServerStatsCounter extends StatsCounter {
|
||||||
|
|
||||||
|
object2intmap.put(statistic, this.getValue(statistic));
|
||||||
|
}
|
||||||
|
+ // Paper start
|
||||||
|
+ if (io.papermc.paper.event.player.PlayerRequestStatisticsEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||||
|
+ io.papermc.paper.event.player.PlayerRequestStatisticsEvent statEvent = new io.papermc.paper.event.player.PlayerRequestStatisticsEvent(
|
||||||
|
+ player.getBukkitEntity(),
|
||||||
|
+ object2intmap.object2IntEntrySet()
|
||||||
|
+ .stream()
|
||||||
|
+ .collect(Object2IntOpenHashMap::new, (map, entry) -> map.put(io.papermc.paper.statistic.PaperStatistics.getPaperStatistic(entry.getKey()), entry.getIntValue()), Object2IntOpenHashMap::putAll)
|
||||||
|
+ );
|
||||||
|
+ if (!statEvent.callEvent()) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ object2intmap = statEvent.getStatisticMap().object2IntEntrySet().stream().collect(Object2IntOpenHashMap::new, (map, entry) -> map.put(io.papermc.paper.statistic.PaperStatistics.getNMSStatistic(entry.getKey()), entry.getIntValue()), Object2IntOpenHashMap::putAll);
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
|
||||||
|
player.connection.send(new ClientboundAwardStatsPacket(object2intmap));
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||||
|
index 2bbc39c257965ad91ee360cdfcd3538a0f041c7e..2a0e49d6fcf63df10b56482462dcb025276a7e3b 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||||
|
@@ -376,6 +376,48 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
|
||||||
|
return this.server.getHandle().getPlayerStats(this.getUniqueId(), this.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start
|
||||||
|
+ @Override
|
||||||
|
+ public void incrementStatistic(io.papermc.paper.statistic.Statistic<?> statistic, int amount) {
|
||||||
|
+ if (this.isOnline()) {
|
||||||
|
+ this.getPlayer().incrementStatistic(statistic, amount);
|
||||||
|
+ } else {
|
||||||
|
+ ServerStatsCounter manager = getStatisticManager();
|
||||||
|
+ io.papermc.paper.statistic.PaperStatistics.changeStatistic(manager, statistic, amount);
|
||||||
|
+ manager.save();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void setStatistic(io.papermc.paper.statistic.Statistic<?> statistic, int newAmount) {
|
||||||
|
+ if (this.isOnline()) {
|
||||||
|
+ this.getPlayer().setStatistic(statistic, newAmount);
|
||||||
|
+ } else {
|
||||||
|
+ ServerStatsCounter manager = getStatisticManager();
|
||||||
|
+ io.papermc.paper.statistic.PaperStatistics.setStatistic(manager, statistic, newAmount);
|
||||||
|
+ manager.save();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public int getStatistic(io.papermc.paper.statistic.Statistic<?> statistic) {
|
||||||
|
+ if (isOnline()) {
|
||||||
|
+ return this.getPlayer().getStatistic(statistic);
|
||||||
|
+ } else {
|
||||||
|
+ return io.papermc.paper.statistic.PaperStatistics.getStatistic(getStatisticManager(), statistic);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public String getFormattedValue(io.papermc.paper.statistic.Statistic<?> statistic) {
|
||||||
|
+ if (this.isOnline()) {
|
||||||
|
+ return this.getPlayer().getFormattedValue(statistic);
|
||||||
|
+ } else {
|
||||||
|
+ return io.papermc.paper.statistic.PaperStatistics.getFormattedValue(getStatisticManager(), statistic);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
@Override
|
||||||
|
public void incrementStatistic(Statistic statistic) {
|
||||||
|
if (this.isOnline()) {
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
||||||
|
index 253b4cf66e94faf0bc8861318ae7549f52cd29d1..d3dfdbb7d1bbfc0e2a77a598ba03b2538a3ba76f 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
||||||
|
@@ -79,6 +79,15 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
|
||||||
|
+ // Paper start - better stats API
|
||||||
|
+ if (bukkitClass == io.papermc.paper.statistic.StatisticType.class) {
|
||||||
|
+ return new CraftRegistry<>(io.papermc.paper.statistic.StatisticType.class, BuiltInRegistries.STAT_TYPE, io.papermc.paper.statistic.PaperStatisticType::create);
|
||||||
|
+ }
|
||||||
|
+ if (bukkitClass == io.papermc.paper.statistic.CustomStatistic.class) {
|
||||||
|
+ return new CraftRegistry<>(io.papermc.paper.statistic.CustomStatistic.class, BuiltInRegistries.CUSTOM_STAT, io.papermc.paper.statistic.PaperCustomStatistic::new);
|
||||||
|
+ }
|
||||||
|
+ // Paper end - better stats API
|
||||||
|
+
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java b/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
|
||||||
|
index d17b9f62ea78f6328200f5478bfa6bc70af7bb2b..8f8046900424c3b2e3dfa36af61a03e2cb7afcf4 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
|
||||||
|
@@ -18,6 +18,7 @@ import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||||
|
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
|
+@Deprecated(forRemoval = true) // Paper
|
||||||
|
public enum CraftStatistic {
|
||||||
|
DAMAGE_DEALT(Stats.DAMAGE_DEALT),
|
||||||
|
DAMAGE_TAKEN(Stats.DAMAGE_TAKEN),
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
|
index 3be5e4df190bff0087c8450b16e4e37b07169040..9cbfccbc432894aba3701717873c7be802ff14e6 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
|
@@ -1507,6 +1507,27 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
|
return bukkitRecipeKeys.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start
|
||||||
|
+ @Override
|
||||||
|
+ public void incrementStatistic(io.papermc.paper.statistic.Statistic<?> statistic, int amount) {
|
||||||
|
+ io.papermc.paper.statistic.PaperStatistics.changeStatistic(this.getHandle().getStats(), statistic, amount);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void setStatistic(io.papermc.paper.statistic.Statistic<?> statistic, int newAmount) {
|
||||||
|
+ io.papermc.paper.statistic.PaperStatistics.setStatistic(this.getHandle().getStats(), statistic, newAmount);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public int getStatistic(io.papermc.paper.statistic.Statistic<?> statistic) {
|
||||||
|
+ return io.papermc.paper.statistic.PaperStatistics.getStatistic(this.getHandle().getStats(), statistic);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public String getFormattedValue(io.papermc.paper.statistic.Statistic<?> statistic) {
|
||||||
|
+ return io.papermc.paper.statistic.PaperStatistics.getFormattedValue(this.getHandle().getStats(), statistic);
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
@Override
|
||||||
|
public void incrementStatistic(Statistic statistic) {
|
||||||
|
CraftStatistic.incrementStatistic(this.getHandle().getStats(), statistic, this.getHandle());
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||||
|
index f67ec3f5f4b7e2f678609f2387cc8afa2adce161..421cc3b6c20af9f0325495b690c0a19bae2dd682 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||||
|
@@ -1738,45 +1738,14 @@ public class CraftEventFactory {
|
||||||
|
Player player = ((ServerPlayer) entityHuman).getBukkitEntity();
|
||||||
|
Event event;
|
||||||
|
if (true) {
|
||||||
|
- org.bukkit.Statistic stat = CraftStatistic.getBukkitStatistic(statistic);
|
||||||
|
- if (stat == null) {
|
||||||
|
- System.err.println("Unhandled statistic: " + statistic);
|
||||||
|
- return null;
|
||||||
|
- }
|
||||||
|
- switch (stat) {
|
||||||
|
- case FALL_ONE_CM:
|
||||||
|
- case BOAT_ONE_CM:
|
||||||
|
- case CLIMB_ONE_CM:
|
||||||
|
- case WALK_ON_WATER_ONE_CM:
|
||||||
|
- case WALK_UNDER_WATER_ONE_CM:
|
||||||
|
- case FLY_ONE_CM:
|
||||||
|
- case HORSE_ONE_CM:
|
||||||
|
- case MINECART_ONE_CM:
|
||||||
|
- case PIG_ONE_CM:
|
||||||
|
- case PLAY_ONE_MINUTE:
|
||||||
|
- case SWIM_ONE_CM:
|
||||||
|
- case WALK_ONE_CM:
|
||||||
|
- case SPRINT_ONE_CM:
|
||||||
|
- case CROUCH_ONE_CM:
|
||||||
|
- case TIME_SINCE_DEATH:
|
||||||
|
- case SNEAK_TIME:
|
||||||
|
- case TOTAL_WORLD_TIME:
|
||||||
|
- case TIME_SINCE_REST:
|
||||||
|
- case AVIATE_ONE_CM:
|
||||||
|
- case STRIDER_ONE_CM:
|
||||||
|
+ // Paper start - better stats api
|
||||||
|
+ io.papermc.paper.statistic.Statistic<?> stat = io.papermc.paper.statistic.PaperStatistics.getPaperStatistic(statistic);
|
||||||
|
+ if (stat.value() instanceof io.papermc.paper.statistic.CustomStatistic customStatistic && io.papermc.paper.statistic.PaperStatistics.IGNORED_STATS_FOR_EVENT.contains(customStatistic)) {
|
||||||
|
// Do not process event for these - too spammy
|
||||||
|
return null;
|
||||||
|
- default:
|
||||||
|
- }
|
||||||
|
- if (stat.getType() == Type.UNTYPED) {
|
||||||
|
- event = new PlayerStatisticIncrementEvent(player, stat, current, newValue);
|
||||||
|
- } else if (stat.getType() == Type.ENTITY) {
|
||||||
|
- EntityType entityType = CraftStatistic.getEntityTypeFromStatistic((net.minecraft.stats.Stat<net.minecraft.world.entity.EntityType<?>>) statistic);
|
||||||
|
- event = new PlayerStatisticIncrementEvent(player, stat, current, newValue, entityType);
|
||||||
|
- } else {
|
||||||
|
- Material material = CraftStatistic.getMaterialFromStatistic(statistic);
|
||||||
|
- event = new PlayerStatisticIncrementEvent(player, stat, current, newValue, material);
|
||||||
|
}
|
||||||
|
+ event = new PlayerStatisticIncrementEvent(player, stat, current, newValue);
|
||||||
|
+ // Paper end - better stats api
|
||||||
|
}
|
||||||
|
entityHuman.level().getCraftServer().getPluginManager().callEvent(event);
|
||||||
|
return (Cancellable) event;
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java
|
||||||
|
index 8464531a4ee400834d25c23b1eb723f49be8689e..64e7970de5cfb56309c71ce0eab0de4a34c86d9a 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java
|
||||||
|
@@ -8,21 +8,21 @@ import org.bukkit.scoreboard.Criteria;
|
||||||
|
import org.bukkit.scoreboard.RenderType;
|
||||||
|
|
||||||
|
public final class CraftCriteria implements Criteria {
|
||||||
|
- static final Map<String, CraftCriteria> DEFAULTS;
|
||||||
|
+ static final Map<String, Criteria> DEFAULTS; // Paper - stats api
|
||||||
|
static final CraftCriteria DUMMY;
|
||||||
|
|
||||||
|
static {
|
||||||
|
- ImmutableMap.Builder<String, CraftCriteria> defaults = ImmutableMap.builder();
|
||||||
|
+ ImmutableMap.Builder<String, Criteria> defaults = ImmutableMap.builder(); // Paper - stats api
|
||||||
|
|
||||||
|
for (Map.Entry<String, ObjectiveCriteria> entry : ObjectiveCriteria.CRITERIA_CACHE.entrySet()) {
|
||||||
|
String name = entry.getKey();
|
||||||
|
ObjectiveCriteria criteria = entry.getValue();
|
||||||
|
|
||||||
|
- defaults.put(name, new CraftCriteria(criteria));
|
||||||
|
+ defaults.put(name, convertFromNms(criteria)); // Paper - stats api
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULTS = defaults.build();
|
||||||
|
- DUMMY = DEFAULTS.get("dummy");
|
||||||
|
+ DUMMY = (CraftCriteria) DEFAULTS.get("dummy"); // Paper - stats api
|
||||||
|
}
|
||||||
|
|
||||||
|
final ObjectiveCriteria criteria;
|
||||||
|
@@ -53,17 +53,23 @@ public final class CraftCriteria implements Criteria {
|
||||||
|
return RenderType.values()[this.criteria.getDefaultRenderType().ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
- static CraftCriteria getFromNMS(Objective objective) {
|
||||||
|
- return java.util.Objects.requireNonNullElseGet(CraftCriteria.DEFAULTS.get(objective.getCriteria().getName()), () -> new CraftCriteria(objective.getCriteria())); // Paper
|
||||||
|
+ static Criteria getFromNMS(Objective objective) { // Paper - stats api
|
||||||
|
+ return java.util.Objects.requireNonNullElseGet(CraftCriteria.DEFAULTS.get(objective.getCriteria().getName()), () -> convertFromNms(objective.getCriteria())); // Paper
|
||||||
|
}
|
||||||
|
|
||||||
|
- public static CraftCriteria getFromBukkit(String name) {
|
||||||
|
- CraftCriteria criteria = CraftCriteria.DEFAULTS.get(name);
|
||||||
|
+ // Paper start - stats api
|
||||||
|
+ static Criteria convertFromNms(ObjectiveCriteria criteria) {
|
||||||
|
+ return criteria instanceof net.minecraft.stats.Stat<?> stat ? io.papermc.paper.statistic.PaperStatistics.getPaperStatistic(stat) : new CraftCriteria(criteria);
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
+
|
||||||
|
+ public static Criteria getFromBukkit(String name) { // Paper - stats api
|
||||||
|
+ Criteria criteria = CraftCriteria.DEFAULTS.get(name); // Paper - stats api
|
||||||
|
if (criteria != null) {
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return ObjectiveCriteria.byName(name).map(CraftCriteria::new).orElseGet(() -> new CraftCriteria(name));
|
||||||
|
+ return ObjectiveCriteria.byName(name).map(CraftCriteria::convertFromNms).orElseGet(() -> new CraftCriteria(name)); // Paper - stats api
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java
|
||||||
|
index 3157f3d2f9ce7af4a763203672817a7f5c7bd4fb..8e3a907c8172340aa456e8898cb5025c29dd18eb 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java
|
||||||
|
@@ -12,7 +12,7 @@ import org.bukkit.scoreboard.Score;
|
||||||
|
|
||||||
|
final class CraftObjective extends CraftScoreboardComponent implements Objective {
|
||||||
|
private final net.minecraft.world.scores.Objective objective;
|
||||||
|
- private final CraftCriteria criteria;
|
||||||
|
+ private final Criteria criteria; // Paper - stats api
|
||||||
|
|
||||||
|
CraftObjective(CraftScoreboard scoreboard, net.minecraft.world.scores.Objective objective) {
|
||||||
|
super(scoreboard);
|
||||||
|
@@ -65,7 +65,7 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective
|
||||||
|
public String getCriteria() {
|
||||||
|
this.checkState();
|
||||||
|
|
||||||
|
- return this.criteria.bukkitName;
|
||||||
|
+ return this.criteria.getName(); // Paper - stats api
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@@ -79,7 +79,7 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective
|
||||||
|
public boolean isModifiable() {
|
||||||
|
this.checkState();
|
||||||
|
|
||||||
|
- return !this.criteria.criteria.isReadOnly();
|
||||||
|
+ return !this.criteria.isReadOnly(); // Paper - stats api
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java
|
||||||
|
index bd8a5bb2b84daf013750aec9887dcb4b02b382ad..d4edd7f165c62b15e810ce4cc68b8bf424c108ba 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java
|
||||||
|
@@ -54,12 +54,15 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
|
||||||
|
Preconditions.checkArgument(name.length() <= Short.MAX_VALUE, "The name '%s' is longer than the limit of 32767 characters (%s)", name, name.length());
|
||||||
|
Preconditions.checkArgument(this.board.getObjective(name) == null, "An objective of name '%s' already exists", name);
|
||||||
|
// Paper start - lazily track plugin scoreboards
|
||||||
|
- if (((CraftCriteria) criteria).criteria != net.minecraft.world.scores.criteria.ObjectiveCriteria.DUMMY && !this.registeredGlobally) {
|
||||||
|
+ // Paper start - stats API
|
||||||
|
+ java.util.Optional<net.minecraft.world.scores.criteria.ObjectiveCriteria> nmsCriteria = net.minecraft.world.scores.criteria.ObjectiveCriteria.byName(criteria.getName());
|
||||||
|
+ if (nmsCriteria.isPresent() && nmsCriteria.get() != net.minecraft.world.scores.criteria.ObjectiveCriteria.DUMMY && !this.registeredGlobally) {
|
||||||
|
+ // Paper end - stats API
|
||||||
|
net.minecraft.server.MinecraftServer.getServer().server.getScoreboardManager().registerScoreboardForVanilla(this);
|
||||||
|
this.registeredGlobally = true;
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
- net.minecraft.world.scores.Objective objective = this.board.addObjective(name, ((CraftCriteria) criteria).criteria, io.papermc.paper.adventure.PaperAdventure.asVanilla(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType), true, null);
|
||||||
|
+ net.minecraft.world.scores.Objective objective = this.board.addObjective(name, nmsCriteria.orElse(net.minecraft.world.scores.criteria.ObjectiveCriteria.DUMMY), io.papermc.paper.adventure.PaperAdventure.asVanilla(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType), true, null); // Paper - stats API
|
||||||
|
return new CraftObjective(this, objective);
|
||||||
|
}
|
||||||
|
// Paper end - Adventure
|
||||||
|
diff --git a/src/test/java/io/papermc/paper/statistic/PaperStatsTest.java b/src/test/java/io/papermc/paper/statistic/PaperStatsTest.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..3584ed5fba7cfe8b8c5c91fa28a59ed40ddbc539
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/test/java/io/papermc/paper/statistic/PaperStatsTest.java
|
||||||
|
@@ -0,0 +1,62 @@
|
||||||
|
+package io.papermc.paper.statistic;
|
||||||
|
+
|
||||||
|
+import java.util.HashSet;
|
||||||
|
+import java.util.Locale;
|
||||||
|
+import java.util.Set;
|
||||||
|
+import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
+import net.minecraft.resources.ResourceLocation;
|
||||||
|
+import net.minecraft.stats.StatType;
|
||||||
|
+import org.bukkit.Material;
|
||||||
|
+import org.bukkit.Registry;
|
||||||
|
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||||
|
+import org.bukkit.support.AbstractTestingBase;
|
||||||
|
+import org.junit.jupiter.api.Test;
|
||||||
|
+
|
||||||
|
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
+import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
+import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
+
|
||||||
|
+public class PaperStatsTest extends AbstractTestingBase {
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ void testNMSCustomStatToPaperCustomStat() {
|
||||||
|
+ Set<ResourceLocation> missingKeys = new HashSet<>();
|
||||||
|
+ for (ResourceLocation minecraftKey : BuiltInRegistries.CUSTOM_STAT) {
|
||||||
|
+ if (Registry.CUSTOM_STATISTIC.get(CraftNamespacedKey.fromMinecraft(minecraftKey)) == null) {
|
||||||
|
+ missingKeys.add(minecraftKey);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ StringBuilder sb = new StringBuilder("\n");
|
||||||
|
+ for (ResourceLocation missingKey : missingKeys) {
|
||||||
|
+ sb.append("public static final CustomStatistic ").append(missingKey.getPath().toUpperCase(Locale.ENGLISH)).append(" = create(\"").append(missingKey.getPath()).append("\");\n");
|
||||||
|
+ }
|
||||||
|
+ if (!missingKeys.isEmpty()) {
|
||||||
|
+ System.out.println(sb);
|
||||||
|
+ }
|
||||||
|
+ assertEquals(0, missingKeys.size(), "Some stats are missing paper counterparts: " + missingKeys);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ void testPaperCustomStatToNMSCustomStat() {
|
||||||
|
+ Set<CustomStatistic> extraStats = new HashSet<>();
|
||||||
|
+ for (CustomStatistic paperCustomStat : Registry.CUSTOM_STATISTIC) {
|
||||||
|
+ ResourceLocation stat = BuiltInRegistries.CUSTOM_STAT.get(CraftNamespacedKey.toMinecraft(paperCustomStat.getKey()));
|
||||||
|
+ if (stat == null) {
|
||||||
|
+ extraStats.add(paperCustomStat);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ assertEquals(0, extraStats.size(), "These stats do not have NMS counterparts: " + extraStats);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ void checkAllStatTypes() {
|
||||||
|
+ for (StatType<?> stat : BuiltInRegistries.STAT_TYPE) {
|
||||||
|
+ assertNotNull(Registry.STATISTIC_TYPE.get(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.STAT_TYPE.getResourceKey(stat).orElseThrow().location())), BuiltInRegistries.STAT_TYPE.getKey(stat) + " is missing its paper counterpart");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ void testInvalidStat() {
|
||||||
|
+ assertThrows(IllegalArgumentException.class, () -> StatisticType.BLOCK_MINED.of(Material.DIAMOND_PICKAXE), "created a block mined stat for a pickaxe");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
|
||||||
|
index dbd1dc4453bd26fb6116b62f6ccbf69e92e09fc4..6eca15dcde875fdee50256ecfe8eb9e2dd2fb326 100644
|
||||||
|
--- a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
|
||||||
|
+++ b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
package io.papermc.paper.world;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.ClientOption;
|
||||||
|
+import io.papermc.paper.statistic.StatisticType;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||||
|
@@ -31,6 +32,14 @@ public class TranslationKeyTest extends AbstractTestingBase {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @Test
|
||||||
|
+ public void testStatType() {
|
||||||
|
+ for (StatisticType<?> statisticType : org.bukkit.Registry.STATISTIC_TYPE) {
|
||||||
|
+ if (statisticType == StatisticType.CUSTOM) continue;
|
||||||
|
+ Assertions.assertEquals(((TranslatableContents) BuiltInRegistries.STAT_TYPE.getOptional(CraftNamespacedKey.toMinecraft(statisticType.getKey())).orElseThrow().getDisplayName().getContents()).getKey(), statisticType.translationKey(), "translation key mismatch for " + statisticType);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
@Test
|
||||||
|
public void testDifficultyKeys() {
|
||||||
|
for (Difficulty bukkitDifficulty : Difficulty.values()) {
|
||||||
|
diff --git a/src/test/java/org/bukkit/StatisticsAndAchievementsTest.java b/src/test/java/org/bukkit/StatisticsAndAchievementsTest.java
|
||||||
|
index 0bc367b633a84fe00a168f40fd31061b5a0d9e35..87dc7bdcc0d0fa2f822cfe4455eb3e59d0a43df3 100644
|
||||||
|
--- a/src/test/java/org/bukkit/StatisticsAndAchievementsTest.java
|
||||||
|
+++ b/src/test/java/org/bukkit/StatisticsAndAchievementsTest.java
|
||||||
|
@@ -11,6 +11,7 @@ import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.support.AbstractTestingBase;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
+@Deprecated(forRemoval = true) // Paper
|
||||||
|
public class StatisticsAndAchievementsTest extends AbstractTestingBase {
|
||||||
|
|
||||||
|
@Test
|
Loading…
Reference in New Issue