more work work work

This commit is contained in:
Aurora 2021-06-14 12:42:08 +02:00
parent b018b48e2c
commit 578ec8c6fe
30 changed files with 131 additions and 444 deletions

View File

@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: ishland <ishlandmc@yeah.net>
Date: Sun, 23 Aug 2020 10:57:44 +0200
Subject: [PATCH] Fix MC-197271
This patch only fixes an issue for servers running OpenJ9.
diff --git a/src/main/java/net/minecraft/data/BuiltinRegistries.java b/src/main/java/net/minecraft/data/BuiltinRegistries.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/data/BuiltinRegistries.java
+++ b/src/main/java/net/minecraft/data/BuiltinRegistries.java
@@ -0,0 +0,0 @@ public class BuiltinRegistries {
public static final Registry<StructureProcessorList> PROCESSOR_LIST = registerSimple(Registry.PROCESSOR_LIST_REGISTRY, () -> {
return ProcessorLists.b;
});
- public static final Registry<StructureTemplatePool> TEMPLATE_POOL = registerSimple(Registry.TEMPLATE_POOL_REGISTRY, Pools::bootstrap);
+ public static final Registry<StructureTemplatePool> TEMPLATE_POOL = registerSimple(Registry.TEMPLATE_POOL_REGISTRY, () -> Pools.bootstrap()); // Paper - MC-197271
public static final Registry<Biome> BIOME = registerSimple(Registry.BIOME_REGISTRY, () -> {
return Biomes.PLAINS;
});
- public static final Registry<NoiseGeneratorSettings> NOISE_GENERATOR_SETTINGS = registerSimple(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY, NoiseGeneratorSettings::bootstrap);
+ public static final Registry<NoiseGeneratorSettings> NOISE_GENERATOR_SETTINGS = registerSimple(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY, () -> NoiseGeneratorSettings.bootstrap()); // Paper - MC-197271
private static <T> Registry<T> registerSimple(ResourceKey<? extends Registry<T>> registryRef, Supplier<T> defaultValueSupplier) {
return registerSimple(registryRef, Lifecycle.stable(), defaultValueSupplier);
@@ -0,0 +0,0 @@ public class BuiltinRegistries {
ResourceLocation minecraftkey = registryRef.location();
BuiltinRegistries.LOADERS.put(minecraftkey, defaultValueSupplier);
- WritableRegistry<R> iregistrywritable = BuiltinRegistries.WRITABLE_REGISTRY;
+ WritableRegistry<R> iregistrywritable = (WritableRegistry<R>) BuiltinRegistries.WRITABLE_REGISTRY; // Paper - decompile fix
- return (WritableRegistry) iregistrywritable.register(registryRef, (Object) registry, lifecycle);
+ return (R) iregistrywritable.register((ResourceKey<R>) registryRef, registry, lifecycle); // Paper - decompile fix
}
public static <T> T register(Registry<? super T> registry, String id, T object) {
@@ -0,0 +0,0 @@ public class BuiltinRegistries {
}
public static <V, T extends V> T register(Registry<V> registry, ResourceLocation id, T object) {
- return ((WritableRegistry) registry).register(ResourceKey.create(registry.key(), id), object, Lifecycle.stable());
+ return (T) ((WritableRegistry) registry).register(ResourceKey.create(registry.key(), id), object, Lifecycle.stable()); // Paper - decompile fix
}
public static <V, T extends V> T registerMapping(Registry<V> iregistry, int rawId, ResourceKey<V> resourcekey, T object) {
- return ((WritableRegistry) iregistry).registerMapping(rawId, resourcekey, object, Lifecycle.stable());
+ return (T) ((WritableRegistry) iregistry).registerMapping(rawId, resourcekey, object, Lifecycle.stable()); // Paper - decompile fix
}
public static void bootstrap() {}

View File

@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Thu, 20 Aug 2020 19:24:13 -0700
Subject: [PATCH] Fix MC-99259 Wither Boss Bar doesn't update until
invulnerability period is over
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -0,0 +0,0 @@ public class WitherBoss extends Monster implements RangedAttackMob {
this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
}
- this.bossEvent.setPercent(this.getHealth() / this.getMaxHealth());
+ //this.bossBattle.setProgress(this.getHealth() / this.getMaxHealth()); // Paper - Moved down
}
+ this.bossEvent.setPercent(this.getHealth() / this.getMaxHealth()); // Paper - Fix MC-99259 (Boss bar does not update until Wither invulnerability period ends)
}
public static boolean canDestroy(BlockState block) {

View File

@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Wed, 12 Aug 2020 11:33:04 +0200
Subject: [PATCH] Import fastutil classes
diff --git a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
+++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
@@ -0,0 +0,0 @@ import net.minecraft.CrashReport;
import net.minecraft.ReportedException;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.Entity;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; // Paper
import org.apache.commons.lang3.ObjectUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -0,0 +0,0 @@ public class SynchedEntityData {
private static final Logger LOGGER = LogManager.getLogger();
private static final Map<Class<? extends Entity>, Integer> ENTITY_ID_POOL = Maps.newHashMap();
private final Entity entity;
- private final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<SynchedEntityData.DataItem<?>> entries = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); // Spigot - use better map // PAIL
+ private final Int2ObjectOpenHashMap<DataItem<?>> entries = new Int2ObjectOpenHashMap<>(); // Spigot - use better map // PAIL
// private final ReadWriteLock lock = new ReentrantReadWriteLock(); // Spigot - not required
private boolean isEmpty = true;
private boolean isDirty;

View File

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 21 Aug 2020 21:05:28 -0400
Subject: [PATCH] MC-197883: Bandaid decode issue
Mojang has a mix of type and name in the data sets, but you can only
use one.
This will retry as name if type is asked for and not found.
diff --git a/src/main/java/com/mojang/serialization/codecs/KeyDispatchCodec.java b/src/main/java/com/mojang/serialization/codecs/KeyDispatchCodec.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/mojang/serialization/codecs/KeyDispatchCodec.java
+++ b/src/main/java/com/mojang/serialization/codecs/KeyDispatchCodec.java
@@ -0,0 +0,0 @@ public class KeyDispatchCodec<K, V> extends MapCodec<V> {
@Override
public <T> DataResult<V> decode(final DynamicOps<T> ops, final MapLike<T> input) {
- final T elementName = input.get(typeKey);
+ // Paper start - bandaid MC-197883
+ T elementName = input.get(typeKey);
+ if (elementName == null && "type".equals(typeKey)) {
+ elementName = input.get("name");
+ }
+ // Paper end
if (elementName == null) {
return DataResult.error("Input does not contain a key [" + typeKey + "]: " + input);
}

View File

@ -1,159 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 4 Aug 2020 22:24:15 +0200
Subject: [PATCH] Optimize Pathfinder - Remove Streams / Optimized collections
I utilized the IDE to convert streams to non streams code, so shouldn't
be any risk of behavior change. Only did minor optimization of the
generated code set to remove unnecessary things.
I expect us to just drop this patch on next major update and re-apply
it with the IDE again and re-apply the collections optimization.
Optimize collection by creating a list instead of a set of the key and value.
This lets us get faster foreach iteration, as well as avoids map lookups on
the values when needed.
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
@@ -0,0 +0,0 @@ public class PathFinder {
this.openSet.a();
this.nodeEvaluator.prepare(world, mob);
Node pathpoint = this.nodeEvaluator.getStart();
- Map<Target, BlockPos> map = (Map) positions.stream().collect(Collectors.toMap((blockposition) -> {
- return this.nodeEvaluator.getGoal((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
- }, Function.identity()));
- Path pathentity = this.findPath(pathpoint, map, followRange, distance, rangeMultiplier);
+ // Paper start - remove streams - and optimize collection
+ List<Map.Entry<Target, BlockPos>> map = Lists.newArrayList();
+ for (BlockPos blockposition : positions) {
+ map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getGoal((double) blockposition.getX(), blockposition.getY(), blockposition.getZ()), blockposition));
+ }
+ // Paper end
+ Path pathentity = this.a(pathpoint, map, followRange, distance, rangeMultiplier);
this.nodeEvaluator.done();
return pathentity;
}
@Nullable
- private Path findPath(Node startNode, Map<Target, BlockPos> positions, float followRange, int distance, float rangeMultiplier) {
- Set<Target> set = positions.keySet();
+ private Path a(Node pathpoint, List<Map.Entry<Target, BlockPos>> list, float f, int i, float f1) { // Paper - optimize collection
+ //Set<PathDestination> set = map.keySet(); // Paper
- startNode.g = 0.0F;
- startNode.h = this.getBestH(startNode, set);
- startNode.f = startNode.h;
+ pathpoint.g = 0.0F;
+ pathpoint.h = this.a(pathpoint, list); // Paper - optimize collection
+ pathpoint.f = pathpoint.h;
this.openSet.a();
- this.openSet.a(startNode);
+ this.openSet.a(pathpoint);
Set<Node> set1 = ImmutableSet.of();
int j = 0;
- Set<Target> set2 = Sets.newHashSetWithExpectedSize(set.size());
- int k = (int) ((float) this.maxVisitedNodes * rangeMultiplier);
+ List<Map.Entry<Target, BlockPos>> set2 = Lists.newArrayListWithExpectedSize(list.size()); // Paper - optimize collection
+ int k = (int) ((float) this.maxVisitedNodes * f1);
while (!this.openSet.e()) {
++j;
@@ -0,0 +0,0 @@ public class PathFinder {
Node pathpoint1 = this.openSet.c();
pathpoint1.closed = true;
- Iterator iterator = set.iterator();
-
- while (iterator.hasNext()) {
- Target pathdestination = (Target) iterator.next();
+ // Paper start - optimize collection
+ for (int i1 = 0; i1 < list.size(); i1++) {
+ Map.Entry<Target, BlockPos> entry = list.get(i1);
+ Target pathdestination = entry.getKey();
- if (pathpoint1.distanceManhattan((Node) pathdestination) <= (float) distance) {
+ if (pathpoint1.distanceManhattan((Node) pathdestination) <= (float) i) {
pathdestination.setReached();
- set2.add(pathdestination);
+ set2.add(entry);
+ // Paper end
}
}
@@ -0,0 +0,0 @@ public class PathFinder {
break;
}
- if (pathpoint1.distanceTo(startNode) < followRange) {
+ if (pathpoint1.distanceTo(pathpoint) < f) {
int l = this.nodeEvaluator.getNeighbors(this.neighbors, pathpoint1);
for (int i1 = 0; i1 < l; ++i1) {
@@ -0,0 +0,0 @@ public class PathFinder {
pathpoint2.walkedDistance = pathpoint1.walkedDistance + f2;
float f3 = pathpoint1.g + f2 + pathpoint2.costMalus;
- if (pathpoint2.walkedDistance < followRange && (!pathpoint2.inOpenSet() || f3 < pathpoint2.g)) {
+ if (pathpoint2.walkedDistance < f && (!pathpoint2.inOpenSet() || f3 < pathpoint2.g)) {
pathpoint2.cameFrom = pathpoint1;
pathpoint2.g = f3;
- pathpoint2.h = this.getBestH(pathpoint2, set) * 1.5F;
+ pathpoint2.h = this.a(pathpoint2, list) * 1.5F; // Paper - list instead of set
if (pathpoint2.inOpenSet()) {
this.openSet.a(pathpoint2, pathpoint2.g + pathpoint2.h);
} else {
@@ -0,0 +0,0 @@ public class PathFinder {
}
}
- Optional<Path> optional = !set2.isEmpty() ? set2.stream().map((pathdestination1) -> {
- return this.reconstructPath(pathdestination1.getBestNode(), (BlockPos) positions.get(pathdestination1), true);
- }).min(Comparator.comparingInt(Path::getNodeCount)) : set.stream().map((pathdestination1) -> {
- return this.reconstructPath(pathdestination1.getBestNode(), (BlockPos) positions.get(pathdestination1), false);
- }).min(Comparator.comparingDouble(Path::getDistToTarget).thenComparingInt(Path::getNodeCount));
-
- if (!optional.isPresent()) {
- return null;
- } else {
- Path pathentity = (Path) optional.get();
-
- return pathentity;
+ // Paper start - remove streams - and optimize collection
+ Path best = null;
+ boolean useSet1 = set2.isEmpty();
+ Comparator<Path> comparator = useSet1 ? Comparator.comparingInt(Path::getNodeCount)
+ : Comparator.comparingDouble(Path::getDistToTarget).thenComparingInt(Path::getNodeCount);
+ for (Map.Entry<Target, BlockPos> entry : useSet1 ? list : set2) {
+ Path pathEntity = this.reconstructPath(entry.getKey().getBestNode(), entry.getValue(), !useSet1);
+ if (best == null || comparator.compare(pathEntity, best) < 0)
+ best = pathEntity;
}
+ return best;
+ // Paper end
}
- private float getBestH(Node node, Set<Target> targets) {
+ private float a(Node pathpoint, List<Map.Entry<Target, BlockPos>> list) { // Paper - optimize collection
float f = Float.MAX_VALUE;
float f1;
- for (Iterator iterator = targets.iterator(); iterator.hasNext(); f = Math.min(f1, f)) {
- Target pathdestination = (Target) iterator.next();
+ // Paper start - optimize collection
+ for (int i = 0, listSize = list.size(); i < listSize; f = Math.min(f1, f), i++) { // Paper
+ Target pathdestination = list.get(i).getKey(); // Paper
+ // Paper end
- f1 = node.distanceTo(pathdestination);
- pathdestination.updateBest(f1, node);
+ f1 = pathpoint.distanceTo(pathdestination);
+ pathdestination.updateBest(f1, pathpoint);
}
return f;

View File

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Fri, 14 Aug 2020 23:59:26 +0200
Subject: [PATCH] Remove armour stand double add to world
diff --git a/src/main/java/net/minecraft/world/item/ArmorStandItem.java b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/ArmorStandItem.java
+++ b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
@@ -0,0 +0,0 @@ public class ArmorStandItem extends Item {
return InteractionResult.FAIL;
}
- worldserver.addFreshEntityWithPassengers(entityarmorstand);
+ // Paper - moved down
float f = (float) Mth.floor((Mth.wrapDegrees(context.getRotation() - 180.0F) + 22.5F) / 45.0F) * 45.0F;
entityarmorstand.moveTo(entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), f, 0.0F);
@@ -0,0 +0,0 @@ public class ArmorStandItem extends Item {
return InteractionResult.FAIL;
}
// CraftBukkit end
- world.addFreshEntity(entityarmorstand);
+ worldserver.addFreshEntityWithPassengers(entityarmorstand); // Paper - moved down
world.playSound((Player) null, entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F);
}

View File

@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
public int getPlayerCount() {
return world.players.size();
return world.players().size();
}
+
+ @Override

View File

@ -15,14 +15,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- protected final int maxPlayers;
+ protected int maxPlayers; public final void setMaxPlayers(int maxPlayers) { this.maxPlayers = maxPlayers; } // Paper - remove final and add setter
private int viewDistance;
private GameType overrideGameMode;
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
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
return playerList.getMaxPlayers();
return this.playerList.getMaxPlayers();
}
+ // Paper start

View File

@ -8,14 +8,14 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ import com.google.common.primitives.Doubles;
@@ -0,0 +0,0 @@ import com.google.common.collect.Lists;
import com.google.common.primitives.Floats;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.StringReader;
+import io.netty.buffer.Unpooled;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import it.unimi.dsi.fastutil.ints.Int2ShortMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry;
@@ -0,0 +0,0 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
private static final int MAX_SIGN_LINE_LENGTH = Integer.getInteger("Paper.maxSignLength", 80);
private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
@ -33,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player) {
this.server = server;
this.connection = connection;
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
private static final ResourceLocation CUSTOM_REGISTER = new ResourceLocation("register");
private static final ResourceLocation CUSTOM_UNREGISTER = new ResourceLocation("unregister");
@ -42,24 +42,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
try {
byte[] data = new byte[packet.data.readableBytes()];
packet.data.readBytes(data);
+
+ // Paper start - Brand support
+ if (packet.identifier.equals(MINECRAFT_BRAND)) {
+ try {
+ this.clientBrandName = new FriendlyByteBuf(Unpooled.copiedBuffer(data)).readUTF(256);
+ this.clientBrandName = new FriendlyByteBuf(Unpooled.copiedBuffer(data)).readUtf(256);
+ } catch (StringIndexOutOfBoundsException ex) {
+ this.clientBrandName = "illegal";
+ }
+ }
+ // Paper end
craftServer.getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), packet.identifier.toString(), data);
this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), packet.identifier.toString(), data);
} catch (Exception ex) {
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex);
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
}
@ -89,4 +88,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
public Player.Spigot spigot()
{
return spigot;
return this.spigot;

View File

@ -13,21 +13,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/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 {
holder.tasks.forEach(Runnable::run);
return holder.protoChunk;
}
+
+ // Paper start
+ private static final int CURRENT_DATA_VERSION = SharedConstants.getCurrentVersion().getWorldVersion();
+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion");
+ // Paper end
+
public static InProgressChunkHolder loadChunk(ServerLevel worldserver, StructureManager definedstructuremanager, PoiManager villageplace, ChunkPos chunkcoordintpair, CompoundTag nbttagcompound, boolean distinguish) {
ArrayDeque<Runnable> tasksToExecuteOnMain = new ArrayDeque<>();
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<>();
// Paper end
ChunkGenerator chunkgenerator = worldserver.getChunkSource().getGenerator();
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
+ // Paper start - Do NOT attempt to load chunks saved with newer versions
+ if (nbttagcompound.contains("DataVersion", 99)) {
+ int dataVersion = nbttagcompound.getInt("DataVersion");
+ if (nbt.contains("DataVersion", 99)) {
+ int dataVersion = nbt.getInt("DataVersion");
+ if (!JUST_CORRUPT_IT && dataVersion > CURRENT_DATA_VERSION) {
+ new RuntimeException("Server attempted to load chunk saved with newer version of minecraft! " + dataVersion + " > " + CURRENT_DATA_VERSION).printStackTrace();
+ System.exit(1);
@ -35,5 +36,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end
BiomeSource worldchunkmanager = chunkgenerator.getBiomeSource();
CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Level"); // Paper - diff on change, see ChunkRegionLoader#getChunkCoordinate
ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); // Paper - diff on change, see ChunkRegionLoader#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

View File

@ -9,9 +9,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- 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 {
this.broadcastBlockEntityIfNeeded(world, blockposition, iblockdata);
this.a(world, blockposition, iblockdata);
} else {
LevelChunkSection chunksection = chunk.getSections()[sectionposition.getY()];
LevelChunkSection chunksection = chunk.getSections()[j];
+ if (chunksection == null) chunksection = new LevelChunkSection(sectionposition.getY(), chunk, world, true); // Paper - make a new chunk section if none was found
ClientboundSectionBlocksUpdatePacket packetplayoutmultiblockchange = new ClientboundSectionBlocksUpdatePacket(sectionposition, shortset, chunksection, this.resendLight);

View File

@ -12,33 +12,32 @@ diff --git a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionT
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
+++ b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.storage.loot.LootContext;
@@ -0,0 +0,0 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.storage.loot.LootContext;
public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerInstance> implements CriterionTrigger<T> {
- private final Map<PlayerAdvancements, Set<CriterionTrigger.Listener<T>>> a = Maps.newIdentityHashMap();
+ //private final Map<AdvancementDataPlayer, Set<CriterionTrigger.a<T>>> a = Maps.newIdentityHashMap(); // Paper - moved into AdvancementDataPlayer to fix memory leak
public SimpleCriterionTrigger() {}
- private final Map<PlayerAdvancements, Set<CriterionTrigger.Listener<T>>> players = Maps.newIdentityHashMap();
+ //private final Map<PlayerAdvancements, Set<CriterionTrigger.Listener<T>>> players = Maps.newIdentityHashMap(); // Paper - moved into AdvancementDataPlayer to fix memory leak
+
+ public SimpleCriterionTrigger() {}
@Override
public final void a(PlayerAdvancements advancementdataplayer, CriterionTrigger.Listener<T> criteriontrigger_a) {
- ((Set) this.a.computeIfAbsent(advancementdataplayer, (advancementdataplayer1) -> {
+ (advancementdataplayer.criterionData.computeIfAbsent(this, (advancementdataplayer1) -> { // Paper - fix AdvancementDataPlayer leak
public final void addPlayerListener(PlayerAdvancements manager, CriterionTrigger.Listener<T> conditions) {
- this.players.computeIfAbsent(manager, (managerx) -> {
+ manager.criterionData.computeIfAbsent(this, (managerx) -> { // Paper - fix AdvancementDataPlayer leak
return Sets.newHashSet();
})).add(criteriontrigger_a);
}).add(conditions);
}
@Override
public final void b(PlayerAdvancements advancementdataplayer, CriterionTrigger.Listener<T> criteriontrigger_a) {
- Set<CriterionTrigger.Listener<T>> set = (Set) this.a.get(advancementdataplayer);
+ Set<CriterionTrigger.Listener<T>> set = (Set) advancementdataplayer.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
public final void removePlayerListener(PlayerAdvancements manager, CriterionTrigger.Listener<T> conditions) {
- Set<CriterionTrigger.Listener<T>> set = this.players.get(manager);
+ Set<CriterionTrigger.Listener<T>> set = (Set) manager.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
if (set != null) {
set.remove(criteriontrigger_a);
set.remove(conditions);
if (set.isEmpty()) {
- this.a.remove(advancementdataplayer);
+ advancementdataplayer.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
- this.players.remove(manager);
+ manager.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
}
}
@ -46,29 +45,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public final void removePlayerListeners(PlayerAdvancements tracker) {
- this.a.remove(tracker);
+ advancementdataplayer.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
- this.players.remove(tracker);
+ tracker.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
}
protected abstract T createInstance(JsonObject obj, EntityPredicate.Composite playerPredicate, DeserializationContext predicateDeserializer);
@@ -0,0 +0,0 @@ public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerI
protected void trigger(ServerPlayer player, Predicate<T> tester) {
PlayerAdvancements advancementdataplayer = player.getAdvancements();
- Set<CriterionTrigger.Listener<T>> set = (Set) this.a.get(advancementdataplayer);
+ Set<CriterionTrigger.Listener<T>> set = (Set) advancementdataplayer.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
PlayerAdvancements playerAdvancements = player.getAdvancements();
- Set<CriterionTrigger.Listener<T>> set = this.players.get(playerAdvancements);
+ Set<CriterionTrigger.Listener<T>> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
if (set != null && !set.isEmpty()) {
LootContext loottableinfo = EntityPredicate.createContext(player, player);
@@ -0,0 +0,0 @@ public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerI
while (iterator.hasNext()) {
criteriontrigger_a = (CriterionTrigger.Listener) iterator.next();
- T t0 = (AbstractCriterionTriggerInstance) criteriontrigger_a.a();
+ T t0 = (T) criteriontrigger_a.a(); // Paper - decompile fix
if (t0.getPlayerPredicate().matches(loottableinfo) && tester.test(t0)) {
if (list == null) {
LootContext lootContext = EntityPredicate.createContext(player, player);
List<CriterionTrigger.Listener<T>> list = null;
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
@ -85,10 +75,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private Advancement lastSelectedTab;
private boolean isFirstPacket = true;
+ // Paper start - fix advancement data player leakage
+ public final Map<SimpleCriterionTrigger, Set<CriterionTrigger.Listener>> criterionData = Maps.newIdentityHashMap();
+ // Paper end - fix advancement data player leakage
+ public final Map<SimpleCriterionTrigger, Set<CriterionTrigger.Listener>> criterionData = Maps.newIdentityHashMap(); // Paper - fix advancement data player leakage
+
public PlayerAdvancements(DataFixer datafixer, PlayerList playerlist, ServerAdvancementManager advancementdataworld, File file, ServerPlayer entityplayer) {
this.dataFixer = datafixer;
this.playerList = playerlist;
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerManager, ServerAdvancementManager advancementLoader, File advancementFile, ServerPlayer owner) {
this.dataFixer = dataFixer;
this.playerList = playerManager;

View File

@ -8,38 +8,44 @@ diff --git a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/Ne
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherCappedSurfaceBuilder.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherCappedSurfaceBuilder.java
@@ -0,0 +0,0 @@ public abstract class NetherCappedSurfaceBuilder extends SurfaceBuilder<SurfaceB
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
BlockState iblockdata4 = chunk.getBlockState(blockposition_mutableblockposition.set(k1, 128, l1));
@@ -0,0 +0,0 @@
package net.minecraft.world.level.levelgen.surfacebuilders;
+<<<<<<< found
- for (int k2 = 127; k2 >= 0; --k2) {
+ for (int k2 = height; k2 >= 0; --k2) { // Paper - fix MC-187716 - use configured height
blockposition_mutableblockposition.set(k1, k2, l1);
BlockState iblockdata5 = chunk.getBlockState(blockposition_mutableblockposition);
int l2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -0,0 +0,0 @@ public abstract class NetherCappedSurfaceBuilder extends SurfaceBuilder<SurfaceB
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
BlockState blockState3 = chunk.getBlockState(mutableBlockPos.set(k, 128, m));
- for(int p = 127; p >= i; --p) {
+ for(int p = height; p >= i; --p) { // Paper - fix MC-187716 - use configured height
mutableBlockPos.set(k, p, m);
BlockState blockState4 = chunk.getBlockState(mutableBlockPos);
if (blockState3.is(defaultBlock.getBlock()) && (blockState4.isAir() || blockState4 == defaultFluid)) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherForestSurfaceBuilder.java b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherForestSurfaceBuilder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherForestSurfaceBuilder.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherForestSurfaceBuilder.java
@@ -0,0 +0,0 @@ public class NetherForestSurfaceBuilder extends SurfaceBuilder<SurfaceBuilderBas
int j2 = -1;
BlockState iblockdata2 = surfaceBlocks.getUnderMaterial();
int o = -1;
BlockState blockState = surfaceBuilderBaseConfiguration.getUnderMaterial();
- for (int k2 = 127; k2 >= 0; --k2) {
+ for (int k2 = height; k2 >= 0; --k2) { // Paper - fix MC-187716 - use configured height
blockposition_mutableblockposition.set(k1, k2, l1);
BlockState iblockdata3 = surfaceBlocks.getTopMaterial();
BlockState iblockdata4 = chunk.getBlockState(blockposition_mutableblockposition);
- for(int p = 127; p >= i; --p) {
+ for(int p = height; p >= i; --p) { // Paper - fix MC-187716 - use configured height
mutableBlockPos.set(k, p, m);
BlockState blockState2 = surfaceBuilderBaseConfiguration.getTopMaterial();
BlockState blockState3 = chunk.getBlockState(mutableBlockPos);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherSurfaceBuilder.java b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherSurfaceBuilder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherSurfaceBuilder.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/surfacebuilders/NetherSurfaceBuilder.java
@@ -0,0 +0,0 @@ public class NetherSurfaceBuilder extends SurfaceBuilder<SurfaceBuilderBaseConfi
BlockState iblockdata2 = surfaceBlocks.getTopMaterial();
BlockState iblockdata3 = surfaceBlocks.getUnderMaterial();
- for (int k2 = 127; k2 >= 0; --k2) {
+ for (int k2 = height; k2 >= 0; --k2) { // Paper - fix MC-187716 - use configured height
blockposition_mutableblockposition.set(k1, k2, l1);
BlockState iblockdata4 = chunk.getBlockState(blockposition_mutableblockposition);
BlockState blockState = surfaceBuilderBaseConfiguration.getTopMaterial();
BlockState blockState2 = surfaceBuilderBaseConfiguration.getUnderMaterial();
- for(int p = 127; p >= i; --p) {
+ for(int p = height; p >= i; --p) { // Paper - fix MC-187716 - use configured height
mutableBlockPos.set(k, p, m);
BlockState blockState3 = chunk.getBlockState(mutableBlockPos);
if (blockState3.isAir()) {

View File

@ -29,5 +29,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- GameProfileCache usercache = new GameProfileCache(gameprofilerepository, new File(file, MinecraftServer.USERID_CACHE_FILE.getName()));
+ GameProfileCache usercache = new GameProfileCache(gameprofilerepository, userCacheFile); // Paper - only move usercache.json into folder if --universe is used, not world-container
// CraftBukkit start
String s = (String) Optional.ofNullable(optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName);
String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName);
LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath());

View File

@ -13,7 +13,7 @@ diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.GameType;
@@ -0,0 +0,0 @@ import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.block.Blocks;
@ -66,4 +66,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
}
// Added from changeDimension
sendAllPlayerInfo(entityplayer); // Update health, etc...
this.sendAllPlayerInfo(entityplayer); // Update health, etc...

View File

@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public final void setSpawn(BlockPos blockposition, float f) { this.setDefaultSpawnPos(blockposition, f); } // Paper - OBFHELPER
public void setDefaultSpawnPos(BlockPos pos, float angle) {
// Paper - configurable spawn radius
BlockPos prevSpawn = this.getSpawn();
BlockPos prevSpawn = this.getSharedSpawnPos();
//ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(this.worldData.a(), 0, this.worldData.c()));
this.levelData.setSpawn(pos, angle);
@ -30,14 +30,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
public boolean setSpawnLocation(int x, int y, int z, float angle) {
try {
Location previousLocation = getSpawnLocation();
Location previousLocation = this.getSpawnLocation();
- world.levelData.setSpawn(new BlockPos(x, y, z), angle);
+ world.setSpawn(new BlockPos(x, y, z), angle); // Paper - use WorldServer#setSpawn
+ // Paper start - move to nms.World
// Notify anyone who's listening.
- SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
- server.getPluginManager().callEvent(event);
- this.server.getPluginManager().callEvent(event);
+ // SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
+ // server.getPluginManager().callEvent(event);
+ // Paper end

View File

@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java b/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
@@ -0,0 +0,0 @@ public abstract class BaseRailBlock extends Block {
@@ -0,0 +0,0 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl
state = this.updateDir(world, pos, state, true);
if (this.isStraight) {
state.neighborChanged(world, pos, this, pos, notify);
@ -27,15 +27,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (state.getBlock() != this) { return; } // Paper - not our block, don't do anything
boolean flag = (Boolean) state.getValue(DetectorRailBlock.POWERED);
boolean flag1 = false;
List<AbstractMinecart> list = this.getInteractingMinecartOfType(world, pos, AbstractMinecart.class, (Predicate) null);
List<AbstractMinecart> list = this.getInteractingMinecartOfType(world, pos, AbstractMinecart.class, (entity) -> {
diff --git a/src/main/java/net/minecraft/world/level/block/RailState.java b/src/main/java/net/minecraft/world/level/block/RailState.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/RailState.java
+++ b/src/main/java/net/minecraft/world/level/block/RailState.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.state.properties.RailShape;
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.RailShape;
public class RailState {
- private final Level level;
- private final BlockPos pos;
+ private final Level level; public final Level getWorld() { return this.level; } // Paper - OBFHELPER
@ -65,10 +65,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end - prevent desync
this.connections.add(placementHelper.pos);
BlockPos blockposition = this.pos.north();
BlockPos blockposition1 = this.pos.south();
BlockPos blockPos = this.pos.north();
BlockPos blockPos2 = this.pos.south();
@@ -0,0 +0,0 @@ public class RailState {
this.state = (BlockState) this.state.setValue(this.block.getShapeProperty(), blockpropertytrackposition1);
this.state = this.state.setValue(this.block.getShapeProperty(), railShape2);
if (forceUpdate || this.level.getBlockState(this.pos) != this.state) {
this.level.setBlock(this.pos, this.state, 3);
+ // Paper start - prevent desync
@ -77,14 +77,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end - prevent desync
for (int i = 0; i < this.connections.size(); ++i) {
RailState minecarttracklogic = this.getRail((BlockPos) this.connections.get(i));
- if (minecarttracklogic != null) {
+ if (minecarttracklogic != null && minecarttracklogic.isValid()) { // Paper - prevent desync
minecarttracklogic.removeSoftConnections();
if (minecarttracklogic.canConnectTo(this)) {
minecarttracklogic.connectTo(this);
for(int i = 0; i < this.connections.size(); ++i) {
RailState railState = this.getRail(this.connections.get(i));
- if (railState != null) {
+ if (railState != null && railState.isValid()) { // Paper - prevent desync
railState.removeSoftConnections();
if (railState.canConnectTo(this)) {
railState.connectTo(this);
@@ -0,0 +0,0 @@ public class RailState {
}

View File

@ -29,35 +29,43 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
//if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit // Paper - move down
//MinecraftServer.LOGGER.debug("Autosave started"); // Paper
serverAutoSave = (autosavePeriod > 0 && this.tickCount % autosavePeriod == 0); // Paper
+ // Paper start
+ int playerSaveInterval = com.destroystokyo.paper.PaperConfig.playerAutoSaveRate;
+ if (playerSaveInterval < 0) {
+ playerSaveInterval = autosavePeriod;
+ }
+ // Paper end
this.profiler.push("save");
- if (autosavePeriod > 0 && this.tickCount % autosavePeriod == 0) { // Paper
if (this.playerList != null) {
MinecraftServer.LOGGER.info("Saving players");
- this.playerList.saveAll();
+ if (playerSaveInterval > 0) { // Paper
this.playerList.removeAll(this.isRestarting); // Paper
try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets
}
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// if (this.autosavePeriod > 0 && this.tickCount % this.autosavePeriod == 0) { // CraftBukkit // Paper - move down
// MinecraftServer.LOGGER.debug("Autosave started"); // Paper
serverAutoSave = (autosavePeriod > 0 && this.tickCount % autosavePeriod == 0); // Paper
+ // Paper start
+ int playerSaveInterval = com.destroystokyo.paper.PaperConfig.playerAutoSaveRate;
+ if (playerSaveInterval < 0) {
+ playerSaveInterval = autosavePeriod;
+ }
+ // Paper end
this.profiler.push("save");
- if (this.autosavePeriod > 0 && this.tickCount % this.autosavePeriod == 0) { // Paper - moved from above
- this.playerList.saveAll();
+ if (playerSaveInterval > 0) { // Paper
+ this.playerList.savePlayers(playerSaveInterval); // Paper
}// Paper
// Paper start
for (ServerLevel world : getAllLevels()) {
// this.saveAllChunks(true, false, false); // Paper - saved incrementally below
} // Paper start
for (ServerLevel level : this.getAllLevels()) {
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ import org.bukkit.inventory.MainHand;
public class ServerPlayer extends Player implements ContainerListener {
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
public final int getViewDistance() { return this.getLevel().getChunkSource().chunkMap.viewDistance - 1; } // Paper - placeholder
private static final Logger LOGGER = LogManager.getLogger();
+ public long lastSave = MinecraftServer.currentTick; // Paper
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
public ServerGamePacketListenerImpl connection;
public Connection networkManager; // Paper
public final MinecraftServer server;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
@ -74,16 +82,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public void saveAll() {
- net.minecraft.server.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
+ // Paper start - incremental player saving
+ savePlayers(null);
+ }
+ public void savePlayers(Integer interval) {
MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
+ MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
MinecraftTimings.savePlayers.startTiming(); // Paper
+ int numSaved = 0;
+ long now = MinecraftServer.currentTick;
for (int i = 0; i < this.players.size(); ++i) {
- this.save((ServerPlayer) this.players.get(i));
- this.save(this.players.get(i));
+ ServerPlayer entityplayer = this.players.get(i);
+ if (interval == null || now - entityplayer.lastSave >= interval) {
+ this.save(entityplayer);

View File

@ -41,11 +41,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.minecraft.world.level.block.piston.PistonHeadBlock;
+import net.minecraft.world.level.block.piston.PistonMovingBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.storage.loot.LootContext;
@@ -0,0 +0,0 @@ public class Explosion {
if (f > 0.0F && this.damageCalculator.a(this, this.level, blockposition, iblockdata, f) && blockposition.getY() < 256 && blockposition.getY() >= 0) { // CraftBukkit - don't wrap explosions
if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f) && blockposition.getY() < 256 && blockposition.getY() >= 0) { // CraftBukkit - don't wrap explosions
set.add(blockposition);
+ // Paper start - prevent headless pistons from forming
+ if (!com.destroystokyo.paper.PaperConfig.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) {
@ -63,7 +63,7 @@ diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBl
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -0,0 +0,0 @@ public class PistonMovingBlockEntity extends BlockEntity implements TickableBloc
@@ -0,0 +0,0 @@ public class PistonMovingBlockEntity extends BlockEntity {
return this.direction;
}