Paper/Spigot-Server-Patches/0141-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch
Shane Freeder f8fd607e04
Updated Upstream (Bukkit/CraftBukkit/Spigot)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
bbfd13dd Hyperlink 'Events' in raid event package documentation
b2095bed SPIGOT-5413: Add TrustedPlayer API for foxes
1bf1f3f4 Block trace methods do not require hash sets
abf0cfdc Javadoc improvements per checkstyle
c4a2b425 Add TimeSkipEvent

CraftBukkit Changes:
817116de SPIGOT-5413: Add TrustedPlayer API for foxes
062680a8 SPIGOT-5467: Calm down bees that cannot exit hive
75fac431 SPIGOT-5472: Spurious warning when using clone command on tile entities
85106731 SPIGOT-5471: Allow empty title/author for books
2d9db47f Add TimeSkipEvent
384225c2 Add thread name to TerminalConsoleWriterThread

Spigot Changes:
05bb8bcf Postpone stopping the watchdog until the server is completely stopped
18e2b9be Add package-info.java for Spigot APIs
2019-12-23 02:37:47 +00:00

306 lines
18 KiB
Diff

From 54c157582993362948f295ca0fd3a629db0318fc Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 19 Dec 2017 16:31:46 -0500
Subject: [PATCH] ExperienceOrbs API for Reason/Source/Triggering player
Adds lots of information about why this orb exists.
Replaces isFromBottle() with logic that persists entity reloads too.
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
index 5de881371..5f261b9b9 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -511,13 +511,13 @@ public class Block implements IMaterial {
}
}
- protected void dropExperience(World world, BlockPosition blockposition, int i) {
+ protected void dropExperience(World world, BlockPosition blockposition, int i, EntityPlayer player) { // Paper
if (!world.isClientSide && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) {
while (i > 0) {
int j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- world.addEntity(new EntityExperienceOrb(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, j));
+ world.addEntity(new EntityExperienceOrb(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, j, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, player)); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/ContainerGrindstone.java b/src/main/java/net/minecraft/server/ContainerGrindstone.java
index 2d2cd09ad..ed88e208d 100644
--- a/src/main/java/net/minecraft/server/ContainerGrindstone.java
+++ b/src/main/java/net/minecraft/server/ContainerGrindstone.java
@@ -81,7 +81,7 @@ public class ContainerGrindstone extends Container {
int k = EntityExperienceOrb.getOrbValue(j);
j -= k;
- world.addEntity(new EntityExperienceOrb(world, (double) blockposition.getX(), (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, k));
+ world.addEntity(new EntityExperienceOrb(world, (double) blockposition.getX(), (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, k, org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, entityhuman)); // Paper
}
world.triggerEffect(1042, blockposition, 0);
diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java
index e0d240a89..07abcc1e2 100644
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -616,7 +616,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
int j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY(), this.locZ(), j));
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY(), this.locZ(), j, org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, this.killer, this)); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
index 0447800d9..d4275e733 100644
--- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java
+++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
@@ -16,9 +16,59 @@ public class EntityExperienceOrb extends Entity {
public int value;
private EntityHuman targetPlayer;
private int targetTime;
+ // Paper start
+ public java.util.UUID sourceEntityId;
+ public java.util.UUID triggerEntityId;
+ public org.bukkit.entity.ExperienceOrb.SpawnReason spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
+
+ private void loadPaperNBT(NBTTagCompound nbttagcompound) {
+ if (!nbttagcompound.hasKeyOfType("Paper.ExpData", 10)) { // 10 = compound
+ return;
+ }
+ NBTTagCompound comp = nbttagcompound.getCompound("Paper.ExpData");
+ if (comp.hasUUID("source")) {
+ this.sourceEntityId = comp.getUUID("source");
+ }
+ if (comp.hasUUID("trigger")) {
+ this.triggerEntityId = comp.getUUID("trigger");
+ }
+ if (comp.hasKey("reason")) {
+ String reason = comp.getString("reason");
+ try {
+ this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason);
+ } catch (Exception e) {
+ this.world.getServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason);
+ }
+ }
+ }
+ private void savePaperNBT(NBTTagCompound nbttagcompound) {
+ NBTTagCompound comp = new NBTTagCompound();
+ if (this.sourceEntityId != null) {
+ comp.setUUID("source", this.sourceEntityId);
+ }
+ if (this.triggerEntityId != null) {
+ comp.setUUID("trigger", triggerEntityId);
+ }
+ if (this.spawnReason != null && this.spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) {
+ comp.setString("reason", this.spawnReason.name());
+ }
+ nbttagcompound.set("Paper.ExpData", comp);
+ }
public EntityExperienceOrb(World world, double d0, double d1, double d2, int i) {
+ this(world, d0, d1, d2, i, null, null);
+ }
+
+ public EntityExperienceOrb(World world, double d0, double d1, double d2, int i, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId) {
+ this(world, d0, d1, d2, i, reason, triggerId, null);
+ }
+
+ public EntityExperienceOrb(World world, double d0, double d1, double d2, int i, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId, Entity sourceId) {
this(EntityTypes.EXPERIENCE_ORB, world);
+ this.sourceEntityId = sourceId != null ? sourceId.getUniqueID() : null;
+ this.triggerEntityId = triggerId != null ? triggerId.getUniqueID() : null;
+ this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
+ // Paper end
this.setPosition(d0, d1, d2);
this.yaw = (float) (this.random.nextDouble() * 360.0D);
this.setMot((this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D, this.random.nextDouble() * 0.2D * 2.0D, (this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D);
@@ -158,6 +208,7 @@ public class EntityExperienceOrb extends Entity {
nbttagcompound.setShort("Health", (short) this.e);
nbttagcompound.setShort("Age", (short) this.c);
nbttagcompound.setShort("Value", (short) this.value);
+ this.savePaperNBT(nbttagcompound); // Paper
}
@Override
@@ -165,6 +216,7 @@ public class EntityExperienceOrb extends Entity {
this.e = nbttagcompound.getShort("Health");
this.c = nbttagcompound.getShort("Age");
this.value = nbttagcompound.getShort("Value");
+ this.loadPaperNBT(nbttagcompound); // Paper
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/main/java/net/minecraft/server/EntityFishingHook.java
index 8ad0d0db1..8d48154e5 100644
--- a/src/main/java/net/minecraft/server/EntityFishingHook.java
+++ b/src/main/java/net/minecraft/server/EntityFishingHook.java
@@ -401,7 +401,7 @@ public class EntityFishingHook extends Entity {
this.world.addEntity(entityitem);
// CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop()
if (playerFishEvent.getExpToDrop() > 0) {
- this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX(), this.owner.locY() + 0.5D, this.owner.locZ() + 0.5D, playerFishEvent.getExpToDrop()));
+ this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX(), this.owner.locY() + 0.5D, this.owner.locZ() + 0.5D, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.owner, this)); // Paper
}
// CraftBukkit end
if (itemstack1.getItem().a(TagsItem.FISHES)) {
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 191e7dfaf..be85a76ac 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -1377,7 +1377,8 @@ public abstract class EntityLiving extends Entity {
int j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY(), this.locZ(), j));
+ EntityLiving attacker = killer != null ? killer : lastDamager; // Paper
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY(), this.locZ(), j, this instanceof EntityPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, attacker, this)); // Paper
}
this.expToDrop = 0;
}
diff --git a/src/main/java/net/minecraft/server/EntityThrownExpBottle.java b/src/main/java/net/minecraft/server/EntityThrownExpBottle.java
index 0bfc0a773..ba2f90cc6 100644
--- a/src/main/java/net/minecraft/server/EntityThrownExpBottle.java
+++ b/src/main/java/net/minecraft/server/EntityThrownExpBottle.java
@@ -43,7 +43,7 @@ public class EntityThrownExpBottle extends EntityProjectileThrowable {
int j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY(), this.locZ(), j));
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY(), this.locZ(), j, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, getShooter(), this)); // Paper
}
this.die();
diff --git a/src/main/java/net/minecraft/server/EntityTurtle.java b/src/main/java/net/minecraft/server/EntityTurtle.java
index c73cc9ae4..76296119a 100644
--- a/src/main/java/net/minecraft/server/EntityTurtle.java
+++ b/src/main/java/net/minecraft/server/EntityTurtle.java
@@ -510,7 +510,7 @@ public class EntityTurtle extends EntityAnimal {
Random random = this.animal.getRandom();
if (this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) {
- this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), random.nextInt(7) + 1));
+ this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), random.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper;
}
}
diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java
index 8b85956e5..8b0c40147 100644
--- a/src/main/java/net/minecraft/server/EntityVillager.java
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
@@ -509,7 +509,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
}
if (merchantrecipe.isRewardExp()) {
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY() + 0.5D, this.locZ(), i));
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY() + 0.5D, this.locZ(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.getTrader(), this)); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java
index 530c69996..2ad8dba5c 100644
--- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java
+++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java
@@ -147,7 +147,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract {
if (merchantrecipe.isRewardExp()) {
int i = 3 + this.random.nextInt(4);
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY() + 0.5D, this.locZ(), i));
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX(), this.locY() + 0.5D, this.locZ(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.getTrader(), this)); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalBreed.java b/src/main/java/net/minecraft/server/PathfinderGoalBreed.java
index 1ab2668e9..2b708761d 100644
--- a/src/main/java/net/minecraft/server/PathfinderGoalBreed.java
+++ b/src/main/java/net/minecraft/server/PathfinderGoalBreed.java
@@ -117,7 +117,7 @@ public class PathfinderGoalBreed extends PathfinderGoal {
if (this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) {
// CraftBukkit start - use event experience
if (experience > 0) {
- this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), experience));
+ this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityageable)); // Paper
}
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
index 46154b281..56f249c43 100644
--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
@@ -374,7 +374,7 @@ public class PlayerInteractManager {
// Drop event experience
if (flag && event != null) {
- iblockdata.getBlock().dropExperience(this.world, blockposition, event.getExpToDrop());
+ iblockdata.getBlock().dropExperience(this.world, blockposition, event.getExpToDrop(), this.player); // Paper
}
return true;
diff --git a/src/main/java/net/minecraft/server/SlotFurnaceResult.java b/src/main/java/net/minecraft/server/SlotFurnaceResult.java
index d2698e847..edc4a5c34 100644
--- a/src/main/java/net/minecraft/server/SlotFurnaceResult.java
+++ b/src/main/java/net/minecraft/server/SlotFurnaceResult.java
@@ -2,7 +2,7 @@ package net.minecraft.server;
public class SlotFurnaceResult extends Slot {
- private final EntityHuman a;
+ private final EntityHuman a; public final EntityHuman getPlayer() { return this.a; } // Paper OBFHELPER
private int b;
public SlotFurnaceResult(EntityHuman entityhuman, IInventory iinventory, int i, int j, int k) {
diff --git a/src/main/java/net/minecraft/server/TileEntityFurnace.java b/src/main/java/net/minecraft/server/TileEntityFurnace.java
index 2a51a241e..0419aea92 100644
--- a/src/main/java/net/minecraft/server/TileEntityFurnace.java
+++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java
@@ -554,7 +554,7 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I
while (i > 0) {
j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- entityhuman.world.addEntity(new EntityExperienceOrb(entityhuman.world, entityhuman.locX(), entityhuman.locY() + 0.5D, entityhuman.locZ() + 0.5D, j));
+ entityhuman.world.addEntity(new EntityExperienceOrb(entityhuman.world, entityhuman.locX(), entityhuman.locY() + 0.5D, entityhuman.locZ() + 0.5D, j, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, entityhuman)); // Paper
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 7b182498c..3fd589a53 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1781,7 +1781,7 @@ public class CraftWorld implements World {
} else if (TNTPrimed.class.isAssignableFrom(clazz)) {
entity = new EntityTNTPrimed(world, x, y, z, null);
} else if (ExperienceOrb.class.isAssignableFrom(clazz)) {
- entity = new EntityExperienceOrb(world, x, y, z, 0);
+ entity = new EntityExperienceOrb(world, x, y, z, 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null); // Paper
} else if (LightningStrike.class.isAssignableFrom(clazz)) {
entity = new EntityLightning(world, x, y, z, false);
} else if (Firework.class.isAssignableFrom(clazz)) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
index 1b512cc45..fbad04567 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
@@ -20,6 +20,18 @@ public class CraftExperienceOrb extends CraftEntity implements ExperienceOrb {
getHandle().value = value;
}
+ // Paper start
+ public java.util.UUID getTriggerEntityId() {
+ return getHandle().triggerEntityId;
+ }
+ public java.util.UUID getSourceEntityId() {
+ return getHandle().sourceEntityId;
+ }
+ public SpawnReason getSpawnReason() {
+ return getHandle().spawnReason;
+ }
+ // Paper end
+
@Override
public EntityExperienceOrb getHandle() {
return (EntityExperienceOrb) entity;
--
2.24.1