Update fluid chunk loading patch

This commit is contained in:
Bjarne Koll
2023-06-08 11:18:51 +02:00
parent 53f112de49
commit ff68512997
6 changed files with 30 additions and 30 deletions

View File

@@ -1,114 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
Date: Sat, 22 Sep 2018 15:56:59 -0400
Subject: [PATCH] Catch JsonParseException in Entity and TE names
As a result, data that no longer parses correctly will not crash the server
instead just logging the exception and continuing (and in most cases should
fix the data)
Player data is fixed pretty much immediately but some block data (like
Shulkers) may need to be changed in order for it to re-save properly
No more crashing though.
diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/io/papermc/paper/util/MCUtil.java
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
@@ -0,0 +0,0 @@ import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.MinecraftServer;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.DistanceManager;
@@ -0,0 +0,0 @@ public final class MCUtil {
}
}
+ @Nullable
+ public static Component getBaseComponentFromNbt(String key, CompoundTag compound) {
+ if (!compound.contains(key)) {
+ return null;
+ }
+ String string = compound.getString(key);
+ try {
+ return Component.Serializer.fromJson(string);
+ } catch (com.google.gson.JsonParseException e) {
+ org.bukkit.Bukkit.getLogger().warning("Unable to parse " + key + " from " + compound +": " + e.getMessage());
+ }
+
+ return null;
+ }
+
public static ChunkStatus getChunkStatus(ChunkHolder chunk) {
return chunk.getChunkHolderStatus();
}
diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
+++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
@@ -0,0 +0,0 @@ public abstract class BaseCommandBlock implements CommandSource {
this.command = nbt.getString("Command");
this.successCount = nbt.getInt("SuccessCount");
if (nbt.contains("CustomName", 8)) {
- this.setName(Component.Serializer.fromJson(nbt.getString("CustomName")));
+ this.setName(io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt)); // Paper - Catch ParseException
}
if (nbt.contains("TrackOutput", 1)) {
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
@@ -0,0 +0,0 @@ public class BannerBlockEntity extends BlockEntity implements Nameable {
public void load(CompoundTag nbt) {
super.load(nbt);
if (nbt.contains("CustomName", 8)) {
- this.name = Component.Serializer.fromJson(nbt.getString("CustomName"));
+ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException
}
this.itemPatterns = nbt.getList("Patterns", 10);
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
@@ -0,0 +0,0 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
super.load(nbt);
this.lockKey = LockCode.fromTag(nbt);
if (nbt.contains("CustomName", 8)) {
- this.name = Component.Serializer.fromJson(nbt.getString("CustomName"));
+ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
this.levels = nbt.getInt("Levels"); // SPIGOT-5053, use where available
// CraftBukkit end
if (nbt.contains("CustomName", 8)) {
- this.name = Component.Serializer.fromJson(nbt.getString("CustomName"));
+ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException
}
this.lockKey = LockCode.fromTag(nbt);
diff --git a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java
@@ -0,0 +0,0 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable
public void load(CompoundTag nbt) {
super.load(nbt);
if (nbt.contains("CustomName", 8)) {
- this.name = Component.Serializer.fromJson(nbt.getString("CustomName"));
+ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException
}
}

View File

@@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 4 Mar 2013 23:46:10 -0500
Subject: [PATCH] Chunk Save Reattempt
We commonly have "Stream Closed" errors on chunk saving, so this code should re-try to save the chunk in the event of failure and hopefully prevent rollbacks.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
return true;
}
} catch (IOException ioexception) {
- com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(ioexception); // Paper
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioexception); // Paper - we want the upper try/catch to retry this
return false;
}
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
}
// Paper end - rewrite chunk system
try { // Paper
+ int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
if (nbt == null) {
regionfile.clear(pos);
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
dataoutputstream.close();
}
}
+ // Paper start
+ return;
+ } catch (Exception ex) {
+ laste = ex;
+ }
+ }
+ if (laste != null) {
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(laste);
+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk " + pos, laste);
+ }
+ // Paper end
} finally { // Paper start
regionfile.fileLock.unlock();
} // Paper end

View File

@@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 0x22 <0x22@futureclient.net>
Date: Thu, 26 Apr 2018 04:41:11 -0400
Subject: [PATCH] Fix exploit that allowed colored signs to be created
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
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 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
FilteredText filteredtext = (FilteredText) signText.get(i);
if (this.player.isTextFilteringEnabled()) {
- lines.add(net.kyori.adventure.text.Component.text(filteredtext.filteredOrEmpty())); // Paper - adventure
+ lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(filteredtext.filteredOrEmpty()))); // Paper - adventure
} else {
- lines.add(net.kyori.adventure.text.Component.text(filteredtext.raw())); // Paper - adventure
+ lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(filteredtext.raw()))); // Paper - adventure
}
}
SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(x, y, z), this.player.getBukkitEntity(), lines);

View File

@@ -1,76 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 10 Sep 2018 23:36:16 -0400
Subject: [PATCH] Prevent chunk loading from Fluid Flowing
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
Direction enumdirection = (Direction) entry.getKey();
FluidState fluid1 = (FluidState) entry.getValue();
BlockPos blockposition1 = pos.relative(enumdirection);
- BlockState iblockdata1 = world.getBlockState(blockposition1);
+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper
+ if (iblockdata1 == null) continue; // Paper
if (this.canSpreadTo(world, pos, blockState, enumdirection, blockposition1, iblockdata1, world.getFluidState(blockposition1), fluid1.getType())) {
// CraftBukkit start
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
while (iterator.hasNext()) {
Direction enumdirection = (Direction) iterator.next();
BlockPos blockposition1 = pos.relative(enumdirection);
- BlockState iblockdata1 = world.getBlockState(blockposition1);
+
+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper
+ if (iblockdata1 == null) continue; // Paper
FluidState fluid = iblockdata1.getFluidState();
if (fluid.getType().isSame(this) && this.canPassThroughWall(enumdirection, world, pos, state, blockposition1, iblockdata1)) {
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
if (enumdirection1 != enumdirection) {
BlockPos blockposition2 = blockposition.relative(enumdirection1);
short short0 = FlowingFluid.getCacheKey(blockposition1, blockposition2);
- Pair<BlockState, FluidState> pair = (Pair) short2objectmap.computeIfAbsent(short0, (short1) -> {
- BlockState iblockdata1 = world.getBlockState(blockposition2);
+ // Paper start - avoid loading chunks
+ Pair<BlockState, FluidState> pair = short2objectmap.get(short0);
+ if (pair == null) {
+ BlockState iblockdatax = world.getBlockStateIfLoaded(blockposition2);
+ if (iblockdatax == null) {
+ continue;
+ }
- return Pair.of(iblockdata1, iblockdata1.getFluidState());
- });
+ pair = Pair.of(iblockdatax, iblockdatax.getFluidState());
+ short2objectmap.put(short0, pair);
+ }
+ // Paper end
BlockState iblockdata1 = (BlockState) pair.getFirst();
FluidState fluid = (FluidState) pair.getSecond();
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
Direction enumdirection = (Direction) iterator.next();
BlockPos blockposition1 = pos.relative(enumdirection);
short short0 = FlowingFluid.getCacheKey(pos, blockposition1);
- Pair<BlockState, FluidState> pair = (Pair) short2objectmap.computeIfAbsent(short0, (short1) -> {
- BlockState iblockdata1 = world.getBlockState(blockposition1);
-
- return Pair.of(iblockdata1, iblockdata1.getFluidState());
- });
+ // Paper start
+ Pair pair = (Pair) short2objectmap.get(short0);
+ if (pair == null) {
+ BlockState iblockdatax = world.getBlockStateIfLoaded(blockposition1);
+ if (iblockdatax == null) continue;
+
+ pair = Pair.of(iblockdatax, iblockdatax.getFluidState());
+ short2objectmap.put(short0, pair);
+ }
+ // Paper end
BlockState iblockdata1 = (BlockState) pair.getFirst();
FluidState fluid = (FluidState) pair.getSecond();
FluidState fluid1 = this.getNewLiquid(world, blockposition1, iblockdata1);