Skip to content

Commit 4d44c9f

Browse files
committed
Upstream Paper fully
1 parent 3d34b1e commit 4d44c9f

File tree

5 files changed

+145
-9
lines changed

5 files changed

+145
-9
lines changed

sources/src/main/java/net/minecraft/server/Chunk.java

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
package net.minecraft.server;
22

3+
import com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode;
34
import com.destroystokyo.paper.exception.ServerInternalException;
45
import com.google.common.base.Predicate;
56
import com.google.common.collect.Queues;
67

78
import java.util.Arrays;
89
import java.util.Collection;
10+
import java.util.HashMap;
911
import java.util.Iterator;
1012
import java.util.List;
1113
import java.util.Map;
1214
import java.util.Random;
15+
import java.util.UUID;
1316
import java.util.concurrent.ConcurrentLinkedQueue;
1417
import javax.annotation.Nullable;
1518
import org.apache.logging.log4j.LogManager;
@@ -36,6 +39,7 @@ public class Chunk {
3639
public final World world;
3740
public final int[] heightMap;
3841
public Long scheduledForUnload; // Paper - delay chunk unloads
42+
private static final Logger logger = LogManager.getLogger(); // Paper
3943
public final int locX;
4044
public final int locZ;
4145
private boolean m;
@@ -679,8 +683,34 @@ public void a(Entity entity) {
679683
entity.ab = this.locX;
680684
entity.ac = k;
681685
entity.ad = this.locZ;
682-
this.entitySlices[k].add(entity);
686+
683687
// Paper start
688+
List<Entity> entitySlice = this.entitySlices[k];
689+
boolean inThis = entitySlice.contains(entity);
690+
if (entity.entitySlice != null || inThis) {
691+
if (entity.entitySlice == entitySlice || inThis) {
692+
LogManager.getLogger().warn(entity + " was already in this chunk section! Report this to https://github.com/PaperMC/Paper/issues/1223");
693+
new Throwable().printStackTrace();
694+
return;
695+
} else {
696+
LogManager.getLogger().warn(entity + " is still in another ChunkSection! Report this to https://github.com/PaperMC/Paper/issues/1223");
697+
698+
Chunk chunk = entity.getCurrentChunk();
699+
if (chunk != null) {
700+
if (chunk != this) {
701+
LogManager.getLogger().warn(entity + " was in another chunk at that! " + chunk.locX + "," + chunk.locZ);
702+
}
703+
chunk.removeEntity(entity);
704+
} else {
705+
removeEntity(entity);
706+
}
707+
new Throwable().printStackTrace();
708+
}
709+
}
710+
entity.entitySlice = entitySlice;
711+
entitySlice.add(entity);
712+
713+
this.markDirty();
684714
entity.setCurrentChunk(this);
685715
entityCounts.increment(entity.entityKeyString);
686716
if (entity instanceof EntityItem) {
@@ -723,6 +753,13 @@ public void a(Entity entity, int i) {
723753

724754
// Paper start
725755
if (!this.entitySlices[i].remove(entity)) { return; }
756+
if (entitySlices[i] == entity.entitySlice) {
757+
entity.entitySlice = null;
758+
} else {
759+
LogManager.getLogger().warn(entity + " was removed from a entitySlice we did not expect. Report this to https://github.com/PaperMC/Paper/issues/1223");
760+
new Throwable().printStackTrace();
761+
}
762+
this.markDirty();
726763
entity.setCurrentChunk(null);
727764
entityCounts.decrement(entity.entityKeyString);
728765
if (entity instanceof EntityItem) {
@@ -856,6 +893,36 @@ public void addEntities() {
856893

857894
for (int j = 0; j < i; ++j) {
858895
List entityslice = aentityslice[j]; // Spigot
896+
// Paper start
897+
DuplicateUUIDMode mode = world.paperConfig.duplicateUUIDMode;
898+
if (mode == DuplicateUUIDMode.DELETE || mode == DuplicateUUIDMode.REGEN) {
899+
Map<UUID, Entity> thisChunk = new HashMap<>();
900+
for (Iterator<Entity> iterator = ((List<Entity>) entityslice).iterator(); iterator.hasNext(); ) {
901+
Entity entity = iterator.next();
902+
if (entity.dead) continue;
903+
Entity other = ((WorldServer) world).entitiesByUUID.get(entity.uniqueID);
904+
if (other == null) {
905+
other = thisChunk.get(entity.uniqueID);
906+
}
907+
if (other != null && !other.dead) {
908+
switch (mode) {
909+
case REGEN: {
910+
entity.setUUID(UUID.randomUUID());
911+
logger.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", regenerated UUID for " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about.");
912+
break;
913+
}
914+
case DELETE: {
915+
logger.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about.");
916+
entity.die();
917+
iterator.remove();
918+
break;
919+
}
920+
}
921+
}
922+
thisChunk.put(entity.uniqueID, entity);
923+
}
924+
}
925+
// Paper end
859926

860927
this.world.a((Collection) entityslice);
861928
}

sources/src/main/java/net/minecraft/server/Entity.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,21 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper
5050

5151
// CraftBukkit start
5252
private static final int CURRENT_LEVEL = 2;
53-
public static Random SHARED_RANDOM = new io.akarin.api.internal.utils.random.LightRandom(); // Paper // Akarin - LightRNG
53+
// Paper start
54+
public static Random SHARED_RANDOM = new io.akarin.api.internal.utils.random.LightRandom() { // Akarin - LightRNG
55+
private boolean locked = false;
56+
@Override
57+
public synchronized void setSeed(long seed) {
58+
if (locked) {
59+
LogManager.getLogger().error("Ignoring setSeed on Entity.SHARED_RANDOM", new Throwable());
60+
} else {
61+
super.setSeed(seed);
62+
locked = true;
63+
}
64+
}
65+
};
66+
Object entitySlice = null;
67+
// Paper end
5468
static boolean isLevelAtLeast(NBTTagCompound tag, int level) {
5569
return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
5670
}
@@ -64,6 +78,7 @@ public CraftEntity getBukkitEntity() {
6478
}
6579
return bukkitEntity;
6680
}
81+
Throwable addedToWorldStack; // Paper - entity debug
6782
// CraftBukikt end
6883

6984
private static final Logger a = LogManager.getLogger();
@@ -2352,7 +2367,7 @@ public boolean t(Entity entity) {
23522367
}
23532368

23542369
public String toString() {
2355-
return String.format("%s[\'%s\'/%d, uuid=\'%s\', l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.uniqueID.toString(), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ)}); // Paper - add UUID
2370+
return String.format("%s[\'%s\'/%d, uuid=\'%s\', l=\'%s\', x=%.2f, y=%.2f, z=%.2f, cx=%d, cd=%d, tl=%d, v=%b, d=%b]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.uniqueID.toString(), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ), getChunkX(), getChunkZ(), this.ticksLived, this.valid, this.dead}); // Paper - add more information
23562371
}
23572372

23582373
public boolean isInvulnerable(DamageSource damagesource) {
@@ -2604,6 +2619,7 @@ public Object call() throws Exception {
26042619
});
26052620
}
26062621

2622+
public void setUUID(UUID uuid) { a(uuid); } // Paper - OBFHELPER
26072623
public void a(UUID uuid) {
26082624
this.uniqueID = uuid;
26092625
this.ar = this.uniqueID.toString();

sources/src/main/java/net/minecraft/server/WorldServer.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.io.File;
77
import java.util.ArrayList;
88
import java.util.Collection;
9+
import java.util.Date;
910
import java.util.Iterator;
1011
import java.util.List;
1112
import java.util.Map;
@@ -40,7 +41,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
4041
public final PlayerChunkMap manager; // Akarin - private -> public
4142
// private final Set<NextTickListEntry> nextTickListHash = Sets.newHashSet();
4243
private final HashTreeSet<NextTickListEntry> nextTickList = new HashTreeSet<NextTickListEntry>(); // CraftBukkit - HashTreeSet
43-
private final Map<UUID, Entity> entitiesByUUID = Maps.newHashMap();
44+
public final Map<UUID, Entity> entitiesByUUID = Maps.newHashMap(); // Paper
4445
public boolean savingDisabled;
4546
private boolean Q;
4647
private int emptyTime;
@@ -52,6 +53,10 @@ public class WorldServer extends World implements IAsyncTaskHandler {
5253
private final List<NextTickListEntry> W = Lists.newArrayList();
5354

5455
// CraftBukkit start
56+
private static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper
57+
private static Throwable getAddToWorldStackTrace(Entity entity) {
58+
return new Throwable(entity + " Added to world at " + new Date());
59+
}
5560
public final int dimension;
5661

5762
// Add env and gen to constructor
@@ -1181,19 +1186,29 @@ public void a(Collection<Entity> collection) {
11811186
private boolean j(Entity entity) {
11821187
if (entity.dead) {
11831188
WorldServer.a.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.a(entity)); // CraftBukkit // Paper
1189+
if (DEBUG_ENTITIES) getAddToWorldStackTrace(entity).printStackTrace();
11841190
return false;
11851191
} else {
11861192
UUID uuid = entity.getUniqueID();
11871193

11881194
if (this.entitiesByUUID.containsKey(uuid)) {
11891195
Entity entity1 = this.entitiesByUUID.get(uuid);
11901196

1191-
if (this.f.contains(entity1)) {
1197+
if (this.f.contains(entity1) || entity1.dead) { // Paper - overwrite the current dead one
11921198
this.f.remove(entity1);
11931199
} else {
11941200
if (!(entity instanceof EntityHuman)) {
1195-
WorldServer.a.error("Keeping entity {} that already exists with UUID {} - " + entity1, EntityTypes.a(entity1), uuid.toString()); // CraftBukkit // Paper
1196-
WorldServer.a.error("Deleting duplicate entity {}", entity); // Paper
1201+
if (entity.world.paperConfig.duplicateUUIDMode != com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode.NOTHING) {
1202+
WorldServer.a.error("Keeping entity {} that already exists with UUID {}", entity1, uuid.toString()); // CraftBukkit // Paper
1203+
WorldServer.a.error("Duplicate entity {} will not be added to the world. See paper.yml duplicate-uuid-resolver and set this to either regen, delete or nothing to get rid of this message", entity); // Paper
1204+
if (DEBUG_ENTITIES) {
1205+
if (entity1.addedToWorldStack != null) {
1206+
entity1.addedToWorldStack.printStackTrace();
1207+
}
1208+
getAddToWorldStackTrace(entity).printStackTrace();
1209+
}
1210+
}
1211+
11971212
return false;
11981213
}
11991214

@@ -1211,7 +1226,24 @@ private boolean j(Entity entity) {
12111226
protected void b(Entity entity) {
12121227
super.b(entity);
12131228
this.entitiesById.a(entity.getId(), entity);
1214-
this.entitiesByUUID.put(entity.getUniqueID(), entity);
1229+
// Paper start
1230+
if (DEBUG_ENTITIES) {
1231+
entity.addedToWorldStack = getAddToWorldStackTrace(entity);
1232+
}
1233+
Entity old = this.entitiesByUUID.put(entity.getUniqueID(), entity);
1234+
if (old != null && old.getId() != entity.getId() && old.valid && entity.world.paperConfig.duplicateUUIDMode != com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode.NOTHING) {
1235+
Logger logger = LogManager.getLogger();
1236+
logger.error("Overwrote an existing entity " + old + " with " + entity);
1237+
if (DEBUG_ENTITIES) {
1238+
if (old.addedToWorldStack != null) {
1239+
old.addedToWorldStack.printStackTrace();
1240+
} else {
1241+
logger.error("Oddly, the old entity was not added to the world in the normal way. Plugins?");
1242+
}
1243+
entity.addedToWorldStack.printStackTrace();
1244+
}
1245+
}
1246+
// Paper end
12151247
Entity[] aentity = entity.bb();
12161248

12171249
if (aentity != null) {

sources/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,11 +1179,32 @@ public void setPlayerProfile(PlayerProfile profile) {
11791179
for (EntityPlayer player : players) {
11801180
player.getBukkitEntity().reregisterPlayer(self);
11811181
}
1182+
refreshPlayer();
11821183
}
11831184
@Override
11841185
public PlayerProfile getPlayerProfile() {
11851186
return new CraftPlayerProfile(this).clone();
11861187
}
1188+
1189+
private void refreshPlayer() {
1190+
EntityPlayer handle = getHandle();
1191+
1192+
Location loc = getLocation();
1193+
1194+
PlayerConnection connection = handle.playerConnection;
1195+
reregisterPlayer(handle);
1196+
1197+
//Respawn the player then update their position and selected slot
1198+
connection.sendPacket(new PacketPlayOutRespawn(handle.dimension, handle.world.getDifficulty(), handle.world.getWorldData().getType(), handle.playerInteractManager.getGameMode()));
1199+
handle.updateAbilities();
1200+
connection.sendPacket(new PacketPlayOutPosition(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), new HashSet<>(), 0));
1201+
MinecraftServer.getServer().getPlayerList().updateClient(handle);
1202+
1203+
if (this.isOp()) {
1204+
this.setOp(false);
1205+
this.setOp(true);
1206+
}
1207+
}
11871208
// Paper end
11881209

11891210
public void removeDisconnectingPlayer(Player player) {

0 commit comments

Comments
 (0)