More more more more more more more more more more more more more more work

This commit is contained in:
Nassim Jahnke 2021-11-24 17:06:46 +01:00
parent b6be217e03
commit fa04d53cbf
32 changed files with 21 additions and 1672 deletions

View file

@ -15,8 +15,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- protected final int maxPlayers; - protected final int maxPlayers;
+ protected int maxPlayers; public final void setMaxPlayers(int maxPlayers) { this.maxPlayers = maxPlayers; } // Paper - remove final and add setter + protected int maxPlayers; public final void setMaxPlayers(int maxPlayers) { this.maxPlayers = maxPlayers; } // Paper - remove final and add setter
private int viewDistance; private int viewDistance;
private int simulationDistance;
private boolean allowCheatsForAllPlayers; private boolean allowCheatsForAllPlayers;
private static final boolean ALLOW_LOGOUTIVATOR = false;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java

View file

@ -16,9 +16,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GenericFutureListener;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry; import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry;
@@ -0,0 +0,0 @@ import net.minecraft.nbt.ListTag; @@ -0,0 +0,0 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.StringTag; import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.Connection; import net.minecraft.network.Connection;
+import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.ChatType;

View file

@ -12,15 +12,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -0,0 +0,0 @@ public class PaperConfig { @@ -0,0 +0,0 @@ public class PaperConfig {
maxPlayerAutoSavePerTick = (playerAutoSaveRate == -1 || playerAutoSaveRate > 100) ? 10 : 20;
} }
} }
+
+ public static int maxJoinsPerTick; + public static int maxJoinsPerTick;
+ private static void maxJoinsPerTick() { + private static void maxJoinsPerTick() {
+ maxJoinsPerTick = getInt("settings.max-joins-per-tick", 3); + maxJoinsPerTick = getInt("settings.max-joins-per-tick", 3);
+ } + }
} +
public static void registerCommands() {
for (Map.Entry<String, Command> entry : commands.entrySet()) {
MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "Paper", entry.getValue());
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/network/Connection.java --- a/src/main/java/net/minecraft/network/Connection.java

View file

@ -13,19 +13,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -0,0 +0,0 @@ public class ChunkSerializer { @@ -0,0 +0,0 @@ public class ChunkSerializer {
holder.tasks.forEach(Runnable::run);
return holder.protoChunk; return holder.protoChunk;
} }
+
+ // Paper start + // Paper start
+ private static final int CURRENT_DATA_VERSION = SharedConstants.getCurrentVersion().getWorldVersion(); + private static final int CURRENT_DATA_VERSION = SharedConstants.getCurrentVersion().getDataVersion().getVersion();
+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); + private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion");
+ // Paper end + // Paper end
+ public static InProgressChunkHolder loadChunk(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt, boolean distinguish) {
public static InProgressChunkHolder loadChunk(ServerLevel world, StructureManager structureManager, PoiManager poiStorage, ChunkPos pos, CompoundTag nbt, boolean distinguish) {
java.util.ArrayDeque<Runnable> tasksToExecuteOnMain = new java.util.ArrayDeque<>(); java.util.ArrayDeque<Runnable> tasksToExecuteOnMain = new java.util.ArrayDeque<>();
// Paper end // Paper end
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
+ // Paper start - Do NOT attempt to load chunks saved with newer versions + // Paper start - Do NOT attempt to load chunks saved with newer versions
+ if (nbt.contains("DataVersion", 99)) { + if (nbt.contains("DataVersion", 99)) {
+ int dataVersion = nbt.getInt("DataVersion"); + int dataVersion = nbt.getInt("DataVersion");
@ -35,6 +32,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ // Paper end + // Paper end
BiomeSource worldchunkmanager = chunkgenerator.getBiomeSource(); ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate
CompoundTag nbttagcompound1 = nbt.getCompound("Level"); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate
ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate if (!Objects.equals(chunkPos, chunkcoordintpair1)) {

View file

@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected abstract T createInstance(JsonObject obj, EntityPredicate.Composite playerPredicate, DeserializationContext predicateDeserializer); protected abstract T createInstance(JsonObject obj, EntityPredicate.Composite playerPredicate, DeserializationContext predicateDeserializer);
@@ -0,0 +0,0 @@ public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerI @@ -0,0 +0,0 @@ public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerI
protected void trigger(ServerPlayer player, Predicate<T> tester) { protected void trigger(ServerPlayer player, Predicate<T> predicate) {
PlayerAdvancements playerAdvancements = player.getAdvancements(); PlayerAdvancements playerAdvancements = player.getAdvancements();
- Set<CriterionTrigger.Listener<T>> set = this.players.get(playerAdvancements); - Set<CriterionTrigger.Listener<T>> set = this.players.get(playerAdvancements);
+ Set<CriterionTrigger.Listener<T>> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak + Set<CriterionTrigger.Listener<T>> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak

View file

@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else { } else {
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
} }
// entityplayer1.syncInventory(); // entityplayer1.initInventoryMenu();
entityplayer1.setHealth(entityplayer1.getHealth()); entityplayer1.setHealth(entityplayer1.getHealth());
- if (flag2) { - if (flag2) {
- entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 1.0F, 1.0F)); - entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 1.0F, 1.0F));

View file

@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
int i = this.player.level.getMaxBuildHeight(); int i = this.player.level.getMaxBuildHeight();
if (blockposition.getY() < i) { if (blockposition.getY() < i) {
if (this.awaitingPositionFromClient == null && this.player.distanceToSqr((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && worldserver.mayInteract((net.minecraft.world.entity.player.Player) this.player, blockposition)) { if (this.awaitingPositionFromClient == null && this.player.distanceToSqr((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && worldserver.mayInteract(this.player, blockposition)) {
// CraftBukkit start - Check if we can actually do something over this large a distance // CraftBukkit start - Check if we can actually do something over this large a distance
- Location eyeLoc = this.getCraftPlayer().getEyeLocation(); - Location eyeLoc = this.getCraftPlayer().getEyeLocation();
- double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ()); - double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ());

View file

@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class Varint21FrameDecoder extends ByteToMessageDecoder { public class Varint21FrameDecoder extends ByteToMessageDecoder {
+ private final byte[] lenBuf = new byte[3]; // Paper + private final byte[] lenBuf = new byte[3]; // Paper
@Override + @Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) { protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) {
+ // Paper start - if channel is not active just discard the packet + // Paper start - if channel is not active just discard the packet
+ if (!channelHandlerContext.channel().isActive()) { + if (!channelHandlerContext.channel().isActive()) {

View file

@ -18,22 +18,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ config.set("settings.unsupported-settings.allow-headless-pistons-readme", "This setting controls if players should be able to create headless pistons."); + config.set("settings.unsupported-settings.allow-headless-pistons-readme", "This setting controls if players should be able to create headless pistons.");
+ allowHeadlessPistons = getBoolean("settings.unsupported-settings.allow-headless-pistons", false); + allowHeadlessPistons = getBoolean("settings.unsupported-settings.allow-headless-pistons", false);
+ } + }
+ }
public static int playerAutoSaveRate = -1;
public static int maxPlayerAutoSavePerTick = 10;
private static void playerAutoSaveRate() {
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java --- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -0,0 +0,0 @@ import java.util.Random;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.BaseFireBlock; @@ -0,0 +0,0 @@ import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
@ -51,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (!com.destroystokyo.paper.PaperConfig.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) { + if (!com.destroystokyo.paper.PaperConfig.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) {
+ BlockEntity extension = this.level.getBlockEntity(blockposition); + BlockEntity extension = this.level.getBlockEntity(blockposition);
+ if (extension instanceof PistonMovingBlockEntity && ((PistonMovingBlockEntity) extension).isSourcePiston()) { + if (extension instanceof PistonMovingBlockEntity && ((PistonMovingBlockEntity) extension).isSourcePiston()) {
+ Direction direction = iblockdata.getValue(PistonHeadBlock.FACING); + net.minecraft.core.Direction direction = iblockdata.getValue(PistonHeadBlock.FACING);
+ set.add(blockposition.relative(direction.getOpposite())); + set.add(blockposition.relative(direction.getOpposite()));
+ } + }
+ } + }

View file

@ -29,23 +29,12 @@ diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
@@ -0,0 +0,0 @@ import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import java.util.Collection;
import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BinaryOperator;
import java.util.stream.Stream;
import javax.annotation.Nullable;
@@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy @@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy
private final ResultConsumer<CommandSourceStack> consumer; private final ResultConsumer<CommandSourceStack> consumer;
private final EntityAnchorArgument.Anchor anchor; private final EntityAnchorArgument.Anchor anchor;
private final Vec2 rotation; private final Vec2 rotation;
- public volatile CommandNode currentCommand; // CraftBukkit - public volatile CommandNode currentCommand; // CraftBukkit
+ public Map<Thread, CommandNode> currentCommand = new ConcurrentHashMap<>(); // CraftBukkit // Paper + public java.util.Map<Thread, CommandNode> currentCommand = new java.util.concurrent.ConcurrentHashMap<>(); // CraftBukkit // Paper
public CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity) { public CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity) {
this(output, pos, rot, world, level, name, displayName, server, entity, false, (commandcontext, flag, j) -> { this(output, pos, rot, world, level, name, displayName, server, entity, false, (commandcontext, flag, j) -> {

View file

@ -1,81 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 29 May 2020 23:32:14 -0400
Subject: [PATCH] Improve Chunk Status Transition Speed
When a chunk is loaded from disk that has already been generated,
the server has to promote the chunk through the system to reach
it's current desired status level.
This results in every single status transition going from the main thread
to the world gen threads, only to discover it has no work it actually
needs to do.... and then it returns back to main.
This back and forth costs a lot of time and can really delay chunk loads
when the server is under high TPS due to their being a lot of time in
between chunk load times, as well as hogs up the chunk threads from doing
actual generation and light work.
Additionally, the whole task system uses a lot of CPU on the server threads anyways.
So by optimizing status transitions for status's that are already complete,
we can run them to the desired level while on main thread (where it has
to happen anyways) instead of ever jumping to world gen thread.
This will improve chunk loading effeciency to be reduced down to the following
scenario / path:
1) MAIN: Chunk Requested, Load Request sent to ChunkTaskManager / IO Queue
2) IO: Once position in queue comes, submit read IO data and schedule to chunk task thread
3) CHUNK: Once IO is loaded and position in queue comes, deserialize the chunk data, process conversions, submit to main queue
4) MAIN: next Chunk Task process (Mid Tick or End Of Tick), load chunk data into world (POI, main thread tasks)
5) MAIN: process status transitions all the way to LIGHT, light schedules Threaded task
6) SERVER: Light tasks register light enablement for chunk and any lighting needing to be done
7) MAIN: Task returns to main, finish processing to FULL/TICKING status
Previously would have hopped to SERVER around 12+ times there extra.
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -0,0 +0,0 @@ public class ChunkHolder {
// Paper end - optimise isOutsideOfRange
long lastAutoSaveTime; // Paper - incremental autosave
long inactiveTimeStart; // Paper - incremental autosave
+ // Paper start - optimize chunk status progression without jumping through thread pool
+ public boolean canAdvanceStatus() {
+ ChunkStatus status = getChunkHolderStatus();
+ ChunkAccess chunk = getAvailableChunkNow();
+ return chunk != null && (status == null || chunk.getStatus().isOrAfter(getNextStatus(status)));
+ }
+ // Paper end
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return either.mapLeft((list) -> {
return (LevelChunk) list.get(list.size() / 2);
});
- }, this.mainThreadExecutor);
+ }, this.mainInvokingExecutor); // Paper
}
@Nullable
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return "chunkGenerate " + requiredStatus.getName();
});
Executor executor = (runnable) -> {
+ // Paper start - optimize chunk status progression without jumping through thread pool
+ if (holder.canAdvanceStatus()) {
+ this.mainInvokingExecutor.execute(runnable);
+ return;
+ }
+ // Paper end
this.worldgenMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable));
};