diff --git a/patches/server/0023-Shared-DataStorage-for-maps.patch b/patches/server/0023-Shared-DataStorage-for-maps.patch new file mode 100644 index 000000000..508529e47 --- /dev/null +++ b/patches/server/0023-Shared-DataStorage-for-maps.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Fri, 18 Nov 2022 08:37:19 -0600 +Subject: [PATCH] Shared DataStorage for maps + + +diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +index a1bd848bbf924267e74e61dabdb840628712b1ad..8ffacd63c964b823ac607a05d3388e036fab0b52 100644 +--- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java ++++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +@@ -356,6 +356,7 @@ public class WorldConfiguration extends ConfigurationPart { + public class Maps extends ConfigurationPart { + public int itemFrameCursorLimit = 128; + public int itemFrameCursorUpdateInterval = 10; ++ public String sharedDataFolder; // Slice + } + + public Fixes fixes; +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index 571753395ecfe82e3c95ad7f322981991ab0c94d..3aac19995956d0d0116cba0bc1412fb9e8f4c2ad 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -227,6 +227,8 @@ public class ServerLevel extends Level implements WorldGenLevel { + return thr; + } + ++ private @Nullable DimensionDataStorage sharedDataStorage; // Slice ++ + @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI + return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper + } +@@ -605,6 +607,13 @@ public class ServerLevel extends Level implements WorldGenLevel { + + this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system + this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system ++ ++ String sharedDataFolder = paperConfig().maps.sharedDataFolder; ++ if (sharedDataFolder != "") { ++ java.io.File sharedDir = new java.io.File(sharedDataFolder); ++ sharedDir.mkdirs(); ++ this.sharedDataStorage = new DimensionDataStorage(sharedDir, datafixer); ++ } + } + + public void setWeatherParameters(int clearDuration, int rainDuration, boolean raining, boolean thundering) { +@@ -1318,6 +1327,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + }// Paper + // Paper - rewrite chunk system - entity saving moved into ChunkHolder + ++ if (sharedDataStorage != null) sharedDataStorage.save(); + } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system + + // CraftBukkit start - moved from MinecraftServer.saveChunks +@@ -1944,11 +1954,17 @@ public class ServerLevel extends Level implements WorldGenLevel { + return this.getChunkSource().getDataStorage(); + } + ++ // Slice start ++ public DimensionDataStorage getMapDataStorage() { ++ return sharedDataStorage != null ? sharedDataStorage : this.getChunkSource().getDataStorage(); ++ } ++ // Slice end ++ + @Nullable + @Override + public MapItemSavedData getMapData(String id) { + // CraftBukkit start +- return (MapItemSavedData) this.getServer().overworld().getDataStorage().get((nbttagcompound) -> { ++ return (MapItemSavedData) getMapDataStorage().get((nbttagcompound) -> { // Slice + // We only get here when the data file exists, but is not a valid map + MapItemSavedData newMap = MapItemSavedData.load(nbttagcompound); + newMap.id = id; +@@ -1962,12 +1978,22 @@ public class ServerLevel extends Level implements WorldGenLevel { + @Override + public void setMapData(String id, MapItemSavedData state) { + state.id = id; // CraftBukkit +- this.getServer().overworld().getDataStorage().set(id, state); ++ getMapDataStorage().set(id, state); // Slice + } + + @Override + public int getFreeMapId() { +- return ((MapIndex) this.getServer().overworld().getDataStorage().computeIfAbsent(MapIndex::load, MapIndex::new, "idcounts")).getFreeAuxValueForMap(); ++ // Slice start ++ DimensionDataStorage storage = getMapDataStorage(); ++ MapIndex mapIndex = storage.readSavedData(MapIndex::load, "idcounts"); ++ if (mapIndex == null) { ++ mapIndex = new MapIndex(); ++ } ++ int newId = mapIndex.getFreeAuxValueForMap(); ++ storage.set("idcounts", mapIndex); ++ storage.save(); ++ return newId; ++ // Slice end + } + + // Paper start - helper function for configurable spawn radius +diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +index 2513069f4ffe594857762ef51f1b9a078b8b1d17..88b13bfa3393d9901c8a1b62bcc37f03919d747b 100644 +--- a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java ++++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +@@ -58,7 +58,7 @@ public class DimensionDataStorage { + } + + @Nullable +- private T readSavedData(Function readFunction, String id) { ++ public T readSavedData(Function readFunction, String id) { // Slice private -> public + try { + File file = this.getDataFile(id); + if (file.exists()) {