mirror of
https://github.com/PaperMC/Paper.git
synced 2025-09-02 05:13:51 -07:00
[Bleeding] Fix Achievements and Statistics API. Fixes BUKKIT-5305
This commit is contained in:
@@ -20,6 +20,12 @@ public class StatisticManager {
|
||||
|
||||
public void b(EntityHuman entityhuman, Statistic statistic, int i) {
|
||||
if (!statistic.d() || this.b((Achievement) statistic)) {
|
||||
// CraftBukkit start
|
||||
org.bukkit.event.Cancellable cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.handleStatisticsIncrease(entityhuman, statistic, a(statistic), i);
|
||||
if (cancellable != null && cancellable.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
this.a(entityhuman, statistic, this.a(statistic) + i);
|
||||
}
|
||||
}
|
||||
|
@@ -1,44 +0,0 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import org.bukkit.Achievement;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
public class CraftAchievement {
|
||||
private static final BiMap<String, Achievement> achievements;
|
||||
static {
|
||||
ImmutableMap<String, Achievement> specialCases = ImmutableMap.<String, Achievement>builder()
|
||||
.put("achievement.buildWorkBench", Achievement.BUILD_WORKBENCH)
|
||||
.put("achievement.diamonds", Achievement.GET_DIAMONDS)
|
||||
.put("achievement.portal", Achievement.NETHER_PORTAL)
|
||||
.put("achievement.ghast", Achievement.GHAST_RETURN)
|
||||
.put("achievement.theEnd", Achievement.END_PORTAL)
|
||||
.put("achievement.theEnd2", Achievement.THE_END)
|
||||
.put("achievement.blazeRod", Achievement.GET_BLAZE_ROD)
|
||||
.put("achievement.potion", Achievement.BREW_POTION)
|
||||
.build();
|
||||
|
||||
ImmutableBiMap.Builder<String, Achievement> builder = ImmutableBiMap.<String, Achievement>builder();
|
||||
for (Achievement achievement : Achievement.values()) {
|
||||
if (specialCases.values().contains(achievement)) {
|
||||
continue;
|
||||
}
|
||||
builder.put("achievement."+CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, achievement.name()), achievement);
|
||||
}
|
||||
|
||||
builder.putAll(specialCases);
|
||||
|
||||
achievements = builder.build();
|
||||
}
|
||||
|
||||
public static String getAchievementName(Achievement material) {
|
||||
return achievements.inverse().get(material);
|
||||
}
|
||||
|
||||
public static Achievement getAchievement(String name) {
|
||||
return achievements.get(name);
|
||||
}
|
||||
}
|
142
src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
Normal file
142
src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
Normal file
@@ -0,0 +1,142 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import net.minecraft.server.EntityTypes;
|
||||
import net.minecraft.server.MonsterEggInfo;
|
||||
import net.minecraft.server.StatisticList;
|
||||
|
||||
import org.bukkit.Achievement;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
public class CraftStatistic {
|
||||
private static final BiMap<String, org.bukkit.Statistic> statistics;
|
||||
private static final BiMap<String, org.bukkit.Achievement> achievements;
|
||||
|
||||
static {
|
||||
ImmutableMap<String, org.bukkit.Achievement> specialCases = ImmutableMap.<String, org.bukkit.Achievement> builder()
|
||||
.put("achievement.buildWorkBench", Achievement.BUILD_WORKBENCH)
|
||||
.put("achievement.diamonds", Achievement.GET_DIAMONDS)
|
||||
.put("achievement.portal", Achievement.NETHER_PORTAL)
|
||||
.put("achievement.ghast", Achievement.GHAST_RETURN)
|
||||
.put("achievement.theEnd", Achievement.END_PORTAL)
|
||||
.put("achievement.theEnd2", Achievement.THE_END)
|
||||
.put("achievement.blazeRod", Achievement.GET_BLAZE_ROD)
|
||||
.put("achievement.potion", Achievement.BREW_POTION)
|
||||
.build();
|
||||
ImmutableBiMap.Builder<String, org.bukkit.Statistic> statisticBuilder = ImmutableBiMap.<String, org.bukkit.Statistic>builder();
|
||||
ImmutableBiMap.Builder<String, org.bukkit.Achievement> achievementBuilder = ImmutableBiMap.<String, org.bukkit.Achievement>builder();
|
||||
for (Statistic statistic : Statistic.values()) {
|
||||
if (statistic == Statistic.PLAY_ONE_TICK) {
|
||||
statisticBuilder.put("stat.playOneMinute", statistic);
|
||||
} else {
|
||||
statisticBuilder.put("stat." + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, statistic.name()), statistic);
|
||||
}
|
||||
}
|
||||
for (Achievement achievement : Achievement.values()) {
|
||||
if (specialCases.values().contains(achievement)) {
|
||||
continue;
|
||||
}
|
||||
achievementBuilder.put("achievement." + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, achievement.name()), achievement);
|
||||
}
|
||||
|
||||
achievementBuilder.putAll(specialCases);
|
||||
|
||||
statistics = statisticBuilder.build();
|
||||
achievements = achievementBuilder.build();
|
||||
}
|
||||
|
||||
private CraftStatistic() {}
|
||||
|
||||
public static org.bukkit.Achievement getBukkitAchievement(net.minecraft.server.Achievement achievement) {
|
||||
return getBukkitAchievementByName(achievement.e);
|
||||
}
|
||||
|
||||
public static org.bukkit.Achievement getBukkitAchievementByName(String name) {
|
||||
return achievements.get(name);
|
||||
}
|
||||
|
||||
public static org.bukkit.Statistic getBukkitStatistic(net.minecraft.server.Statistic statistic) {
|
||||
return getBukkitStatisticByName(statistic.e);
|
||||
}
|
||||
|
||||
public static org.bukkit.Statistic getBukkitStatisticByName(String name) {
|
||||
if (name.startsWith("stat.killEntity")) {
|
||||
name = "stat.killEntity";
|
||||
}
|
||||
if (name.startsWith("stat.entityKilledBy")) {
|
||||
name = "stat.entityKilledBy";
|
||||
}
|
||||
if (name.startsWith("stat.breakItem")) {
|
||||
name = "stat.breakItem";
|
||||
}
|
||||
if (name.startsWith("stat.useItem")) {
|
||||
name = "stat.useItem";
|
||||
}
|
||||
if (name.startsWith("stat.mineBlock")) {
|
||||
name = "stat.mineBlock";
|
||||
}
|
||||
if (name.startsWith("stat.craftItem")) {
|
||||
name = "stat.craftItem";
|
||||
}
|
||||
return statistics.get(name);
|
||||
}
|
||||
|
||||
public static net.minecraft.server.Statistic getNMSStatistic(org.bukkit.Statistic statistic) {
|
||||
return StatisticList.a(statistics.inverse().get(statistic));
|
||||
}
|
||||
|
||||
public static net.minecraft.server.Achievement getNMSAchievement(org.bukkit.Achievement achievement) {
|
||||
return (net.minecraft.server.Achievement) StatisticList.a(achievements.inverse().get(achievement));
|
||||
}
|
||||
|
||||
public static net.minecraft.server.Statistic getMaterialStatistic(org.bukkit.Statistic stat, Material material) {
|
||||
try {
|
||||
if (stat == Statistic.MINE_BLOCK) {
|
||||
return StatisticList.C[material.getId()];
|
||||
}
|
||||
if (stat == Statistic.CRAFT_ITEM) {
|
||||
return StatisticList.D[material.getId()];
|
||||
}
|
||||
if (stat == Statistic.USE_ITEM) {
|
||||
return StatisticList.E[material.getId()];
|
||||
}
|
||||
if (stat == Statistic.BREAK_ITEM) {
|
||||
return StatisticList.F[material.getId()];
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static net.minecraft.server.Statistic getEntityStatistic(org.bukkit.Statistic stat, EntityType entity) {
|
||||
MonsterEggInfo monsteregginfo = (MonsterEggInfo) EntityTypes.a.get(Integer.valueOf(entity.getTypeId()));
|
||||
|
||||
if (monsteregginfo != null) {
|
||||
return monsteregginfo.d;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static EntityType getEntityTypeFromStatistic(net.minecraft.server.Statistic statistic) {
|
||||
String statisticString = statistic.e;
|
||||
return EntityType.fromName(statisticString.substring(statisticString.lastIndexOf(".") + 1));
|
||||
}
|
||||
|
||||
public static Material getMaterialFromStatistic(net.minecraft.server.Statistic statistic) {
|
||||
String statisticString = statistic.e;
|
||||
int id;
|
||||
try {
|
||||
id = Integer.valueOf(statisticString.substring(statisticString.lastIndexOf(".") + 1));
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
return Material.getMaterial(id);
|
||||
}
|
||||
}
|
@@ -20,11 +20,11 @@ import net.minecraft.server.*;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Achievement;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic.Type;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.serialization.DelegateDeserialization;
|
||||
import org.bukkit.conversations.Conversation;
|
||||
@@ -35,6 +35,7 @@ import org.bukkit.craftbukkit.CraftEffect;
|
||||
import org.bukkit.craftbukkit.CraftOfflinePlayer;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftSound;
|
||||
import org.bukkit.craftbukkit.CraftStatistic;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.map.CraftMapView;
|
||||
import org.bukkit.craftbukkit.map.RenderData;
|
||||
@@ -51,7 +52,6 @@ import org.bukkit.inventory.InventoryView.Property;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.messaging.Messenger;
|
||||
import org.bukkit.plugin.messaging.StandardMessenger;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
|
||||
@@ -517,7 +517,29 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void awardAchievement(Achievement achievement) {
|
||||
// TODO - non-functional as of ID purge
|
||||
Validate.notNull(achievement, "Achievement cannot be null");
|
||||
if (achievement.hasParent() && !hasAchievement(achievement.getParent())) {
|
||||
awardAchievement(achievement.getParent());
|
||||
}
|
||||
getHandle().x().a(getHandle(), CraftStatistic.getNMSAchievement(achievement), 1);
|
||||
getHandle().x().b(getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAchievement(Achievement achievement) {
|
||||
Validate.notNull(achievement, "Achievement cannot be null");
|
||||
for (Achievement achieve : Achievement.values()) {
|
||||
if (achieve.getParent() == achievement && hasAchievement(achieve)) {
|
||||
removeAchievement(achieve);
|
||||
}
|
||||
}
|
||||
getHandle().x().a(getHandle(), CraftStatistic.getNMSAchievement(achievement), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAchievement(Achievement achievement) {
|
||||
Validate.notNull(achievement, "Achievement cannot be null");
|
||||
return getHandle().x().a(CraftStatistic.getNMSAchievement(achievement));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -525,9 +547,37 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
incrementStatistic(statistic, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrementStatistic(Statistic statistic) {
|
||||
decrementStatistic(statistic, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatistic(Statistic statistic) {
|
||||
Validate.notNull(statistic, "Statistic cannot be null");
|
||||
Validate.isTrue(statistic.getType() == Type.UNTYPED, "Must supply additional paramater for this statistic");
|
||||
return getHandle().x().a(CraftStatistic.getNMSStatistic(statistic));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementStatistic(Statistic statistic, int amount) {
|
||||
// TODO - non-functional as of ID purge
|
||||
Validate.isTrue(amount > 0, "Amount must be greater than 0");
|
||||
setStatistic(statistic, getStatistic(statistic) + amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrementStatistic(Statistic statistic, int amount) {
|
||||
Validate.isTrue(amount > 0, "Amount must be greater than 0");
|
||||
setStatistic(statistic, getStatistic(statistic) - amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatistic(Statistic statistic, int newValue) {
|
||||
Validate.notNull(statistic, "Statistic cannot be null");
|
||||
Validate.isTrue(statistic.getType() == Type.UNTYPED, "Must supply additional paramater for this statistic");
|
||||
Validate.isTrue(newValue >= 0, "Value must be greater than or equal to 0");
|
||||
net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getNMSStatistic(statistic);
|
||||
getHandle().x().a(getHandle(), nmsStatistic, newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -535,9 +585,85 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
incrementStatistic(statistic, material, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrementStatistic(Statistic statistic, Material material) {
|
||||
decrementStatistic(statistic, material, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatistic(Statistic statistic, Material material) {
|
||||
Validate.notNull(statistic, "Statistic cannot be null");
|
||||
Validate.notNull(material, "Material cannot be null");
|
||||
Validate.isTrue(statistic.getType() == Type.BLOCK || statistic.getType() == Type.ITEM, "This statistic does not take a Material parameter");
|
||||
net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getMaterialStatistic(statistic, material);
|
||||
Validate.notNull(nmsStatistic, "The supplied Material does not have a corresponding statistic");
|
||||
return getHandle().x().a(nmsStatistic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementStatistic(Statistic statistic, Material material, int amount) {
|
||||
// TODO - non-functional as of ID purge
|
||||
Validate.isTrue(amount > 0, "Amount must be greater than 0");
|
||||
setStatistic(statistic, material, getStatistic(statistic, material) + amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrementStatistic(Statistic statistic, Material material, int amount) {
|
||||
Validate.isTrue(amount > 0, "Amount must be greater than 0");
|
||||
setStatistic(statistic, material, getStatistic(statistic, material) - amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatistic(Statistic statistic, Material material, int newValue) {
|
||||
Validate.notNull(statistic, "Statistic cannot be null");
|
||||
Validate.notNull(material, "Material cannot be null");
|
||||
Validate.isTrue(newValue >= 0, "Value must be greater than or equal to 0");
|
||||
Validate.isTrue(statistic.getType() == Type.BLOCK || statistic.getType() == Type.ITEM, "This statistic does not take a Material parameter");
|
||||
net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getMaterialStatistic(statistic, material);
|
||||
Validate.notNull(nmsStatistic, "The supplied Material does not have a corresponding statistic");
|
||||
getHandle().x().a(getHandle(), nmsStatistic, newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementStatistic(Statistic statistic, EntityType entityType) {
|
||||
incrementStatistic(statistic, entityType, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrementStatistic(Statistic statistic, EntityType entityType) {
|
||||
decrementStatistic(statistic, entityType, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatistic(Statistic statistic, EntityType entityType) {
|
||||
Validate.notNull(statistic, "Statistic cannot be null");
|
||||
Validate.notNull(entityType, "EntityType cannot be null");
|
||||
Validate.isTrue(statistic.getType() == Type.ENTITY, "This statistic does not take an EntityType parameter");
|
||||
net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getEntityStatistic(statistic, entityType);
|
||||
Validate.notNull(nmsStatistic, "The supplied EntityType does not have a corresponding statistic");
|
||||
return getHandle().x().a(nmsStatistic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementStatistic(Statistic statistic, EntityType entityType, int amount) {
|
||||
Validate.isTrue(amount > 0, "Amount must be greater than 0");
|
||||
setStatistic(statistic, entityType, getStatistic(statistic, entityType) + amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrementStatistic(Statistic statistic, EntityType entityType, int amount) {
|
||||
Validate.isTrue(amount > 0, "Amount must be greater than 0");
|
||||
setStatistic(statistic, entityType, getStatistic(statistic, entityType) - amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatistic(Statistic statistic, EntityType entityType, int newValue) {
|
||||
Validate.notNull(statistic, "Statistic cannot be null");
|
||||
Validate.notNull(entityType, "EntityType cannot be null");
|
||||
Validate.isTrue(newValue >= 0, "Value must be greater than or equal to 0");
|
||||
Validate.isTrue(statistic.getType() == Type.ENTITY, "This statistic does not take an EntityType parameter");
|
||||
net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getEntityStatistic(statistic, entityType);
|
||||
Validate.notNull(nmsStatistic, "The supplied EntityType does not have a corresponding statistic");
|
||||
getHandle().x().a(getHandle(), nmsStatistic, newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -32,10 +32,12 @@ import net.minecraft.server.WorldServer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Statistic.Type;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftStatistic;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||
@@ -47,6 +49,7 @@ import org.bukkit.craftbukkit.util.CraftDamageSource;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.LightningStrike;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
@@ -56,6 +59,7 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.ThrownExpBottle;
|
||||
import org.bukkit.entity.ThrownPotion;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.block.*;
|
||||
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
|
||||
@@ -729,4 +733,44 @@ public class CraftEventFactory {
|
||||
entity.world.getServer().getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static Cancellable handleStatisticsIncrease(EntityHuman entityHuman, net.minecraft.server.Statistic statistic, int current, int incrementation) {
|
||||
Player player = ((EntityPlayer) entityHuman).getBukkitEntity();
|
||||
Event event;
|
||||
if (statistic instanceof net.minecraft.server.Achievement) {
|
||||
if (current != 0) {
|
||||
return null;
|
||||
}
|
||||
event = new PlayerAchievementAwardedEvent(player, CraftStatistic.getBukkitAchievement((net.minecraft.server.Achievement) statistic));
|
||||
} else {
|
||||
org.bukkit.Statistic stat = CraftStatistic.getBukkitStatistic(statistic);
|
||||
switch (stat) {
|
||||
case FALL_ONE_CM:
|
||||
case BOAT_ONE_CM:
|
||||
case CLIMB_ONE_CM:
|
||||
case DIVE_ONE_CM:
|
||||
case FLY_ONE_CM:
|
||||
case HORSE_ONE_CM:
|
||||
case MINECART_ONE_CM:
|
||||
case PIG_ONE_CM:
|
||||
case PLAY_ONE_TICK:
|
||||
case SWIM_ONE_CM:
|
||||
case WALK_ONE_CM:
|
||||
// Do not process event for these - too spammy
|
||||
return null;
|
||||
default:
|
||||
}
|
||||
if (stat.getType() == Type.UNTYPED) {
|
||||
event = new PlayerStatisticIncrementEvent(player, stat, current, current + incrementation);
|
||||
} else if (stat.getType() == Type.ENTITY) {
|
||||
EntityType entityType = CraftStatistic.getEntityTypeFromStatistic(statistic);
|
||||
event = new PlayerStatisticIncrementEvent(player, stat, current, current + incrementation, entityType);
|
||||
} else {
|
||||
Material material = CraftStatistic.getMaterialFromStatistic(statistic);
|
||||
event = new PlayerStatisticIncrementEvent(player, stat, current, current + incrementation, material);
|
||||
}
|
||||
}
|
||||
entityHuman.world.getServer().getPluginManager().callEvent(event);
|
||||
return (Cancellable) event;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user