From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Mariell Hoversholm Date: Thu, 20 Aug 2020 17:57:02 +0200 Subject: [PATCH] PaperPR - Apply advancements async diff --git a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java index eaa1063ff2..a3b89a4f2a 100644 --- a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java +++ b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java @@ -63,6 +63,7 @@ public class AdvancementDataPlayer { this.d(advancementdataworld); } + public final void setPlayer(EntityPlayer entityPlayer) { this.a(entityPlayer); } // Paper - OBFHELPER public void a(EntityPlayer entityplayer) { this.player = entityplayer; } diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 50ea875a3b..cc6a54e06a 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -49,7 +49,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public final MinecraftServer server; public final PlayerInteractManager playerInteractManager; public final Deque removeQueue = new ArrayDeque<>(); // Paper - private final AdvancementDataPlayer advancementDataPlayer; + private AdvancementDataPlayer advancementDataPlayer; // Paper - remove final + private final java.util.concurrent.CompletableFuture advancementDataPlayerCompletableFuture; // Paper - async advancements private final ServerStatisticManager serverStatisticManager; private float lastHealthScored = Float.MIN_VALUE; private int lastFoodScored = Integer.MIN_VALUE; @@ -136,7 +137,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.playerInteractManager = playerinteractmanager; this.server = minecraftserver; this.serverStatisticManager = minecraftserver.getPlayerList().getStatisticManager(this); - this.advancementDataPlayer = minecraftserver.getPlayerList().f(this); + this.advancementDataPlayerCompletableFuture = minecraftserver.getPlayerList().loadAdvancementDataPlayerAsync(this); // Paper - async advancements this.G = 1.0F; //this.c(worldserver); // Paper - don't move to spawn on login, only first join this.co = minecraftserver.a(this); @@ -505,7 +506,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { CriterionTriggers.u.a(this, this.cf, this.ticksLived - this.cg); } - this.advancementDataPlayer.b(this); + if (areAdvancementsLoaded()) // Paper - async advancements: don't tick advancements until they're loaded + this.advancementDataPlayer.sendUpdateIfNeeded(this); // Paper - conflict on change // Purpur start if (this.world.purpurConfig.useNightVisionWhenRiding && this.getVehicle() != null && this.getVehicle().getRider() == this && world.getTime() % 100 == 0) { // 5 seconds @@ -2121,7 +2123,26 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.worldChangeInvuln = false; } + // Paper start - async advancements + public boolean areAdvancementsLoaded() { + return this.advancementDataPlayer != null + || this.advancementDataPlayerCompletableFuture.isDone(); + } + + public AdvancementDataPlayer getAdvancementDataIfLoadedImmediately() { + // We need a null check here because this method is called before the future is assigned. + // Once assigned, it will essentially be a no-op as the field is final. + if (this.advancementDataPlayer == null && this.advancementDataPlayerCompletableFuture != null && this.advancementDataPlayerCompletableFuture.isDone()) + this.advancementDataPlayer = this.advancementDataPlayerCompletableFuture.join(); + return this.advancementDataPlayer; + } + public AdvancementDataPlayer getAdvancementData() { + if (this.advancementDataPlayer == null) + synchronized (this.advancementDataPlayerCompletableFuture) { + if (this.advancementDataPlayer == null) this.advancementDataPlayer = this.advancementDataPlayerCompletableFuture.join(); + } + // Paper end return this.advancementDataPlayer; } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index fd75444cec..95d93cd8e5 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2315,6 +2315,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant loadAdvancementDataPlayerAsync(EntityPlayer entityPlayer) { + if (entityPlayer.getAdvancementDataIfLoadedImmediately() != null) { + entityPlayer.getAdvancementData().setPlayer(entityPlayer); + return java.util.concurrent.CompletableFuture.completedFuture(entityPlayer.getAdvancementData()); + } + + UUID uuid = entityPlayer.getUniqueID(); + File file = this.server.getSavedFilePath(SavedFile.ADVANCEMENTS).toFile(); + final File file1 = new File(file, uuid + ".json"); + return java.util.concurrent.CompletableFuture.supplyAsync( + () -> new AdvancementDataPlayer(this.server.getDataFixer(), this, this.server.getAdvancementData(), file1, entityPlayer), + server.executorService + ); + } + // Paper end + public AdvancementDataPlayer f(EntityPlayer entityplayer) { UUID uuid = entityplayer.getUniqueID(); - AdvancementDataPlayer advancementdataplayer = (AdvancementDataPlayer) entityplayer.getAdvancementData(); // CraftBukkit + AdvancementDataPlayer advancementdataplayer = (AdvancementDataPlayer) entityplayer.getAdvancementDataIfLoadedImmediately(); // CraftBukkit // Paper if (advancementdataplayer == null) { File file = this.server.a(SavedFile.ADVANCEMENTS).toFile();