diff --git a/patches/server/Clear-SyncLoadInfo.patch b/patches/server/Clear-SyncLoadInfo.patch new file mode 100644 index 0000000000..6b97609186 --- /dev/null +++ b/patches/server/Clear-SyncLoadInfo.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tom +Date: Fri, 26 Feb 2021 16:10:53 -0600 +Subject: [PATCH] Clear SyncLoadInfo + +This patch merely adds the extra argument "clear" after /paper syncloadinfo to clear currently stored syncload info. + +diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java ++++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java +@@ -0,0 +0,0 @@ public class PaperCommand extends Command { + sender.sendMessage(ChatColor.RED + "This command requires the server startup flag '-Dpaper.debug-sync-loads=true' to be set."); + return; + } ++ ++ if (args.length > 1 && args[1].equals("clear")) { ++ SyncLoadFinder.clear(); ++ sender.sendMessage(ChatColor.GRAY + "Sync load data cleared."); ++ return; ++ } ++ + File file = new File(new File(new File("."), "debug"), + "sync-load-info" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt"); + file.getParentFile().mkdirs(); +diff --git a/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java ++++ b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java +@@ -0,0 +0,0 @@ public class SyncLoadFinder { + public final Long2IntOpenHashMap coordinateTimes = new Long2IntOpenHashMap(); + } + ++ public static void clear() { ++ SYNC_LOADS.clear(); ++ } ++ + public static void logSyncLoad(final Level world, final int chunkX, final int chunkZ) { + if (!ENABLED) { + return; diff --git a/patches/server/Fix-Concurrency-issue-in-WeightedList.patch b/patches/server/Fix-Concurrency-issue-in-WeightedList.patch new file mode 100644 index 0000000000..8727b94f66 --- /dev/null +++ b/patches/server/Fix-Concurrency-issue-in-WeightedList.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Mon, 6 Jul 2020 18:36:41 -0400 +Subject: [PATCH] Fix Concurrency issue in WeightedList + +if multiple threads from worldgen sort at same time, it will crash. +So make a copy of the list for sorting purposes. + +diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java +@@ -0,0 +0,0 @@ public class GateBehavior extends Behavior { + private final Set> exitErasedMemories; + private final GateBehavior.OrderPolicy orderPolicy; + private final GateBehavior.RunningPolicy runningPolicy; +- private final ShufflingList> behaviors = new ShufflingList<>(); ++ private final ShufflingList> behaviors = new ShufflingList<>(false); // Paper - don't use a clone + + public GateBehavior(Map, MemoryStatus> requiredMemoryState, Set> memoriesToForgetWhenStopped, GateBehavior.OrderPolicy order, GateBehavior.RunningPolicy runMode, List, Integer>> tasks) { + super(requiredMemoryState); +diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java +@@ -0,0 +0,0 @@ import java.util.stream.Stream; + public class ShufflingList { + protected final List> entries; + private final Random random = new Random(); ++ private final boolean isUnsafe; // Paper + + public ShufflingList() { ++ // Paper start ++ this(true); ++ } ++ public ShufflingList(boolean isUnsafe) { ++ this.isUnsafe = isUnsafe; ++ // Paper end + this.entries = Lists.newArrayList(); + } + + private ShufflingList(List> list) { ++ // Paper start ++ this(list, true); ++ } ++ private ShufflingList(List> list, boolean isUnsafe) { ++ this.isUnsafe = isUnsafe; ++ // Paper end + this.entries = Lists.newArrayList(list); + } + +@@ -0,0 +0,0 @@ public class ShufflingList { + } + + public ShufflingList shuffle() { +- this.entries.forEach((entry) -> { +- entry.setRandom(this.random.nextFloat()); +- }); +- this.entries.sort(Comparator.comparingDouble(ShufflingList.WeightedEntry::getRandWeight)); +- return this; ++ // Paper start - make concurrent safe, work off a clone of the list ++ List> list = this.isUnsafe ? Lists.newArrayList(this.entries) : this.entries; ++ list.forEach(entry -> entry.setRandom(this.random.nextFloat())); ++ list.sort(Comparator.comparingDouble(ShufflingList.WeightedEntry::getRandWeight)); ++ return this.isUnsafe ? new ShufflingList<>(list, this.isUnsafe) : this; ++ // Paper end + } + + public Stream stream() { diff --git a/patches/server/Fix-Not-a-string-Map-Conversion-spam.patch b/patches/server/Fix-Not-a-string-Map-Conversion-spam.patch new file mode 100644 index 0000000000..273c3ef595 --- /dev/null +++ b/patches/server/Fix-Not-a-string-Map-Conversion-spam.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Thu, 8 Oct 2020 00:00:25 -0400 +Subject: [PATCH] Fix "Not a string" Map Conversion spam + +The maps did convert successfully, but had noisy logs due to Spigot +implementing this logic incorrectly. + +This stops the spam by converting the old format to new before +requesting the world. + +Track spigot issue to see when fixed: https://hub.spigotmc.org/jira/browse/SPIGOT-6181 + +diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java ++++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +@@ -0,0 +0,0 @@ import net.minecraft.core.BlockPos; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.nbt.ListTag; + import net.minecraft.nbt.NbtOps; ++import net.minecraft.nbt.NumericTag; ++import net.minecraft.nbt.StringTag; + import net.minecraft.nbt.Tag; + import net.minecraft.network.chat.Component; + import net.minecraft.network.protocol.Packet; +@@ -0,0 +0,0 @@ public class MapItemSavedData extends SavedData { + } + + public static MapItemSavedData load(CompoundTag nbt) { +- DataResult dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbt.get("dimension"))); ++ // Paper start - fix "Not a string" spam ++ Tag dimension = nbt.get("dimension"); ++ if (dimension instanceof NumericTag && ((NumericTag) dimension).getAsInt() >= CraftWorld.CUSTOM_DIMENSION_OFFSET) { ++ long least = nbt.getLong("UUIDLeast"); ++ long most = nbt.getLong("UUIDMost"); ++ ++ if (least != 0L && most != 0L) { ++ UUID uuid = new UUID(most, least); ++ CraftWorld world = (CraftWorld) Bukkit.getWorld(uuid); ++ if (world != null) { ++ dimension = StringTag.create("minecraft:" + world.getName().toLowerCase(java.util.Locale.ENGLISH)); ++ } else { ++ dimension = StringTag.create("bukkit:_invalidworld_"); ++ } ++ } else { ++ dimension = StringTag.create("bukkit:_invalidworld_"); ++ } ++ } ++ DataResult> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, dimension)); // CraftBukkit - decompile error ++ // Paper end - fix "Not a string" spam + Logger logger = MapItemSavedData.LOGGER; + + Objects.requireNonNull(logger); diff --git a/work/Bukkit b/work/Bukkit index ebb0e28d11..e9ce88b99c 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit ebb0e28d11747aa0bb4bb39fad8979ccfaa925b6 +Subproject commit e9ce88b99c08332877866313784cd84e9d9b54fb diff --git a/work/CraftBukkit b/work/CraftBukkit index f992ce6097..d7ef1e91fa 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit f992ce6097f846ed5967fc797d98ae3e84ef1b10 +Subproject commit d7ef1e91fa6431aa649b4bfcdabdbbef8ba41267