Fix EXP orb merging causing values to go negative - Closes #1169

This commit is contained in:
Aikar 2018-08-03 00:06:20 -04:00
parent 4128c348c2
commit 712ded51a2
6 changed files with 27 additions and 24 deletions

View file

@ -8,7 +8,7 @@ which can keep them in the chunk when they shouldnt be if done
during entity ticking. during entity ticking.
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index d2d2ab794..df98a4f44 100644 index 0aa2f99838..8822d17745 100644
--- a/src/main/java/net/minecraft/server/World.java --- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { @@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {

View file

@ -10,7 +10,7 @@ to the object directly on the Entity/TileEntity object we can directly grab.
Use that local value instead to reduce lookups in many hot places. Use that local value instead to reduce lookups in many hot places.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 81bf60efa..04adf4e3c 100644 index d24d45fdd3..4757081090 100644
--- a/src/main/java/net/minecraft/server/Chunk.java --- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk { @@ -0,0 +0,0 @@ public class Chunk {
@ -22,7 +22,7 @@ index 81bf60efa..04adf4e3c 100644
this.a(entity, entity.ac); this.a(entity, entity.ac);
} }
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index c0816b9f8..52adee880 100644 index 986670f689..a01488e985 100644
--- a/src/main/java/net/minecraft/server/World.java --- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { @@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {

View file

@ -8,16 +8,16 @@ Plugins can cancel this if they want to ensure experience orbs do not lose impor
metadata such as spawn reason, or conditionally move data from source to target. metadata such as spawn reason, or conditionally move data from source to target.
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 39b90fb4c..c0816b9f8 100644 index c0e79796bd..986670f689 100644
--- a/src/main/java/net/minecraft/server/World.java --- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { @@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
for (Entity e : entities) {
if (e instanceof EntityExperienceOrb) { if (e instanceof EntityExperienceOrb) {
EntityExperienceOrb loopItem = (EntityExperienceOrb) e; EntityExperienceOrb loopItem = (EntityExperienceOrb) e;
- if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue)) { // Paper // Paper start
+ if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue) && new com.destroystokyo.paper.event.entity.ExperienceOrbMergeEvent((org.bukkit.entity.ExperienceOrb) entity.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) loopItem.getBukkitEntity()).callEvent()) { // Paper - if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue)) {
xp.value += loopItem.value; + if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue) && new com.destroystokyo.paper.event.entity.ExperienceOrbMergeEvent((org.bukkit.entity.ExperienceOrb) entity.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) loopItem.getBukkitEntity()).callEvent()) {
// Paper start long newTotal = (long)xp.value + (long)loopItem.value;
if (!mergeUnconditionally && xp.value > maxValue) { if (newTotal > (long)maxValue) {
loopItem.value = xp.value - maxValue;
-- --

View file

@ -11,7 +11,7 @@ This will ensure that dead entities are skipped from iteration since
they shouldn't of been in the list in the first place. they shouldn't of been in the list in the first place.
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
index ecd1c65a9..1898ab897 100644 index ecd1c65a98..1898ab897c 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java --- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java +++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -0,0 +0,0 @@ public class PaperCommand extends Command { @@ -0,0 +0,0 @@ public class PaperCommand extends Command {
@ -23,7 +23,7 @@ index ecd1c65a9..1898ab897 100644
MutablePair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap())); MutablePair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.getChunkX(), e.getChunkZ()); ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.getChunkX(), e.getChunkZ());
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 1e64d5fcd..45e149f4a 100644 index 1e64d5fcd6..45e149f4a3 100644
--- a/src/main/java/net/minecraft/server/Entity.java --- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper @@ -0,0 +0,0 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper
@ -35,7 +35,7 @@ index 1e64d5fcd..45e149f4a 100644
public float length; public float length;
public float I; public float I;
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0dca11b2c..dadd4b839 100644 index 8822d17745..3ce6f9778b 100644
--- a/src/main/java/net/minecraft/server/World.java --- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { @@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
@ -71,7 +71,7 @@ index 0dca11b2c..dadd4b839 100644
if (entity instanceof EntityInsentient) { if (entity instanceof EntityInsentient) {
EntityInsentient entityinsentient = (EntityInsentient) entity; EntityInsentient entityinsentient = (EntityInsentient) entity;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 210e3bc4e..e6ecd1796 100644 index 210e3bc4e6..e6ecd1796c 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld implements World { @@ -0,0 +0,0 @@ public class CraftWorld implements World {

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Option for maximum exp value when merging orbs
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 4d30cdbc8..535a8d3ed 100644 index 4d30cdbc8b..535a8d3ed1 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -0,0 +0,0 @@ public class PaperWorldConfig {
@ -20,7 +20,7 @@ index 4d30cdbc8..535a8d3ed 100644
+ } + }
} }
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 29dffc3ac..2c69ae748 100644 index 3561507de1..b6b4d52718 100644
--- a/src/main/java/net/minecraft/server/World.java --- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { @@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
@ -29,7 +29,7 @@ index 29dffc3ac..2c69ae748 100644
if (radius > 0) { if (radius > 0) {
+ // Paper start - Maximum exp value when merging - Whole section has been tweaked, see comments for specifics + // Paper start - Maximum exp value when merging - Whole section has been tweaked, see comments for specifics
+ final int maxValue = paperConfig.expMergeMaxValue; + final int maxValue = paperConfig.expMergeMaxValue;
+ final boolean mergeUnconditionally = maxValue <= 0; + final boolean mergeUnconditionally = paperConfig.expMergeMaxValue <= 0;
+ if (mergeUnconditionally || xp.value < maxValue) { // Paper - Skip iteration if unnecessary + if (mergeUnconditionally || xp.value < maxValue) { // Paper - Skip iteration if unnecessary
+ +
List<Entity> entities = this.getEntities(entity, entity.getBoundingBox().grow(radius, radius, radius)); List<Entity> entities = this.getEntities(entity, entity.getBoundingBox().grow(radius, radius, radius));
@ -37,16 +37,19 @@ index 29dffc3ac..2c69ae748 100644
if (e instanceof EntityExperienceOrb) { if (e instanceof EntityExperienceOrb) {
EntityExperienceOrb loopItem = (EntityExperienceOrb) e; EntityExperienceOrb loopItem = (EntityExperienceOrb) e;
- if (!loopItem.dead) { - if (!loopItem.dead) {
+ if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue)) { // Paper - xp.value += loopItem.value;
xp.value += loopItem.value; - loopItem.die();
+ // Paper start + // Paper start
+ if (!mergeUnconditionally && xp.value > maxValue) { + if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue)) {
+ long newTotal = (long)xp.value + (long)loopItem.value;
+ if (newTotal > (long)maxValue) {
+ loopItem.value = xp.value - maxValue; + loopItem.value = xp.value - maxValue;
+ xp.value = maxValue; + xp.value = maxValue;
+ break; + } else {
+ xp.value += loopItem.value;
+ loopItem.die();
+ } + }
+ // Paper end + // Paper end
loopItem.die();
} }
} }
} }

View file

@ -57,7 +57,7 @@ index bcce5e8b7e..bad287fca4 100644
nbttagcompound.set("Entities", nbttaglist1); nbttagcompound.set("Entities", nbttaglist1);
NBTTagList nbttaglist2 = new NBTTagList(); NBTTagList nbttaglist2 = new NBTTagList();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index b4de3b515a..d2d2ab794b 100644 index 3012768cb9..0aa2f99838 100644
--- a/src/main/java/net/minecraft/server/World.java --- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { @@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {