From 17ba164cbcf426b911801be9c64e9d353886ef41 Mon Sep 17 00:00:00 2001 From: Sotr Date: Sat, 4 Aug 2018 23:27:42 +0800 Subject: [PATCH] Upstream Paper --- .../main/java/net/minecraft/server/World.java | 27 +++++++++++-------- .../net/minecraft/server/WorldServer.java | 2 +- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/sources/src/main/java/net/minecraft/server/World.java b/sources/src/main/java/net/minecraft/server/World.java index 55b881c50..eeaf0bc44 100644 --- a/sources/src/main/java/net/minecraft/server/World.java +++ b/sources/src/main/java/net/minecraft/server/World.java @@ -1,4 +1,4 @@ - package net.minecraft.server; +package net.minecraft.server; import com.destroystokyo.paper.event.server.ServerExceptionEvent; import com.destroystokyo.paper.exception.ServerInternalException; @@ -1149,23 +1149,25 @@ public abstract class World implements IBlockAccess { if (radius > 0) { // Paper start - Maximum exp value when merging - Whole section has been tweaked, see comments for specifics 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 List entities = this.getEntities(entity, entity.getBoundingBox().grow(radius, radius, radius)); for (Entity e : entities) { if (e instanceof EntityExperienceOrb) { EntityExperienceOrb loopItem = (EntityExperienceOrb) e; - 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 - xp.value += loopItem.value; - // Paper start - if (!mergeUnconditionally && xp.value > maxValue) { - loopItem.value = xp.value - maxValue; + // 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()) { + long newTotal = (long)xp.value + (long)loopItem.value; + if ((int) newTotal < 0) continue; // Overflow + if (maxValue > 0 && newTotal > (long)maxValue) { + loopItem.value = (int) (newTotal - maxValue); xp.value = maxValue; - break; + } else { + xp.value += loopItem.value; + loopItem.die(); } // Paper end - loopItem.die(); } } } @@ -1206,7 +1208,8 @@ public abstract class World implements IBlockAccess { } this.getChunkAt(i, j).a(entity); - if (!entity.dead) this.entityList.add(entity); // Paper - don't add dead entities, chunk registration may of killed it + if (entity.dead) return false; // Paper - don't add dead entities, chunk registration may of killed it + this.entityList.add(entity); this.b(entity); return true; } @@ -1218,6 +1221,7 @@ public abstract class World implements IBlockAccess { } entity.valid = true; // CraftBukkit + entity.shouldBeRemoved = false; // Paper - shouldn't be removed after being re-added new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid } @@ -2745,6 +2749,7 @@ public abstract class World implements IBlockAccess { return i; } + public void addChunkEntities(Collection collection) { a(collection); } // Paper - OBFHELPER public void a(Collection collection) { org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot // CraftBukkit start @@ -2754,7 +2759,7 @@ public abstract class World implements IBlockAccess { while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); - if (entity == null) { + if (entity == null || entity.dead || entity.valid) { // Paper - prevent adding already added or dead entities continue; } this.entityList.add(entity); diff --git a/sources/src/main/java/net/minecraft/server/WorldServer.java b/sources/src/main/java/net/minecraft/server/WorldServer.java index 262dcce6d..c471b2672 100644 --- a/sources/src/main/java/net/minecraft/server/WorldServer.java +++ b/sources/src/main/java/net/minecraft/server/WorldServer.java @@ -1194,7 +1194,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { if (this.entitiesByUUID.containsKey(uuid)) { Entity entity1 = this.entitiesByUUID.get(uuid); - if (this.f.contains(entity1) || entity1.dead) { // Paper - overwrite the current dead one + if (this.f.contains(entity1) || entity1.dead) { // Paper - if dupe is dead, overwrite this.f.remove(entity1); } else { if (!(entity instanceof EntityHuman)) {