Compare commits

...

21 commits

Author SHA1 Message Date
sulu5890
9a521c3f56
Update Log4J (1.15.2) (#7157)
* Update Log4j

* update log4j (again)
2021-12-19 16:10:35 -08:00
Jake Potrebic
d52a9ed0fb
fixed spawn reason for spawners (#4843) 2020-12-03 11:54:50 -08:00
Andrew Steinborn
9bc721428f
[1.15] Improve performance of matching ingredients for shapeless recipes (#4695) 2020-10-27 13:14:23 -04:00
Aikar
87de40926f
Backport some light and priority changs from 1.16 to 1.15 2020-10-11 18:45:46 -04:00
ForceUpdate1
d131395aeb
Fix distance in checkHighPriorityChunks (Fixes #4582) (#4605) 2020-10-11 18:39:53 -04:00
chickeneer
dd276c632c
MC-147729: Drop items that are extra from a crafting recipe (#1766) 2020-10-11 14:18:11 -04:00
Shane Freeder
cebec202f8
fix config option in last commit 2020-08-25 13:27:56 +01:00
Shane Freeder
a964eb39eb
Buffer joins to world
This patch buffers the number of logins which will attempt to join
the world per tick, this attempts to reduce the impact that join floods
has on the server
2020-08-25 12:45:38 +01:00
Zach Brown
f65f95ce3f
Do not let the server load chunks from newer versions
If the server attempts to load a chunk generated by a newer version of
the game, immediately stop the server to prevent data corruption.

You can override this functionality at your own peril.

This restores patch we had for older versions.
2020-08-06 20:24:26 -04:00
Aikar
1799ef1408
Apply 1.16's light optimizations to 1.15.2 too 2020-08-06 20:19:45 -04:00
Aikar
5a28de6662
Further optimize chunk light prioritization 2020-07-29 01:54:58 -04:00
Aikar
4e364423e0
Fix deadlock issue with watchdog stopping
Fixes #4008
2020-07-28 22:18:02 -04:00
Aikar
82e048ebcb
Remove ability to disable async chunks unless single core cpu
Too many people try to disable async chunks thinking its the cure
to some mysterious problem.

It is not possible to fully disable async chunks, and the portion
that this config controls is so minor in the grand scheme of things.

People are needlessly hurting their server following bad advice, so
just kill this config except for the people who might actually benefit from it.
2020-07-28 21:41:45 -04:00
Spottedleaf
b317f0dc4f
[1.15] Fix off by one error for scheduling block ticks (#4013)
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
2020-07-28 01:18:43 -04:00
Spottedleaf
51741a1806
[1.15] Tighten logic for handling target tick times in tick scheduler (#4011)
No longer rely on world time as plugins like to screw it up.

Add a new flag -Dpaper.ticklist-max-tick-delay= that
will automatically drop any tick entries that have a delay
exceeding the specified amount. This is only useful
for cleaning up a world that has been corrupted by
certain blocks having a huge tick delay.

Also fix an issue with some rails connecting incorrectly
that I found when testing.

Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
2020-07-27 22:42:59 -04:00
Aikar
5657364b45
Fix Light Prioritization Issues
Ensures light priorities are properly processed before processing new
work, skipping the threads queue.

also stops processing work on task submission.

Also drops dead chunks light work to not waste time on work thats going to be discarded.
2020-07-27 22:40:54 -04:00
Spottedleaf
0133746291
Fix AdvancementDataPlayer leak due from quitting early in login
Move the criterion storage to the AdvancementDataPlayer object
itself, so the criterion object stores no references - and thus
needs no cleanup.

Fixes #3050
2020-07-22 01:51:26 -04:00
Spottedleaf
74231d422f
[1.15] Move range check for block placing up (#3918)
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
2020-07-16 03:39:18 +01:00
Wyatt Childers
48ea17fa19
Optimize the advancement data player iteration to be O(N) rather than O(N^2) 2020-07-07 01:25:53 -04:00
CDFN
be4d74d933
Fix Explosion location - Fixes #3574 2020-07-06 15:28:58 -04:00
Andrew Steinborn
31e5f66881
[1.15] Optimize NetworkManager exception handling (#3820) 2020-07-06 00:28:16 -04:00
27 changed files with 934 additions and 175 deletions

View file

@ -99,7 +99,7 @@ index 4cf22afc3c1f1cc19b6e5350043431215908a612..ac3c8eef58872c2de840a4b7ba7d77c2
+ * @return false if explosion was canceled, otherwise true
+ */
+ public boolean createExplosion(@NotNull Entity source, float power, boolean setFire, boolean breakBlocks) {
+ return this.getWorld().createExplosion(source, source.getLocation(), power, setFire, breakBlocks);
+ return this.getWorld().createExplosion(source, this, power, setFire, breakBlocks);
+ }
+
/**

File diff suppressed because one or more lines are too long

View file

@ -10,10 +10,10 @@ This made the Bukkit RecipeChoice API not work for Shapeless.
This reimplements vanilla logic using the same test logic as Shaped
diff --git a/src/main/java/net/minecraft/server/ShapelessRecipes.java b/src/main/java/net/minecraft/server/ShapelessRecipes.java
index fe03a35cc862d58fffa88325e34bad011a0a0ff7..fb481e65862b4aaa08e2302a517fdd8253d63812 100644
index fe03a35cc862d58fffa88325e34bad011a0a0ff7..852e114e94665956f43232cf4a65ea1fd1d9b761 100644
--- a/src/main/java/net/minecraft/server/ShapelessRecipes.java
+++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java
@@ -63,16 +63,46 @@ public class ShapelessRecipes implements RecipeCrafting {
@@ -63,16 +63,49 @@ public class ShapelessRecipes implements RecipeCrafting {
AutoRecipeStackManager autorecipestackmanager = new AutoRecipeStackManager();
int i = 0;
@ -43,6 +43,9 @@ index fe03a35cc862d58fffa88325e34bad011a0a0ff7..fb481e65862b4aaa08e2302a517fdd82
- return i == this.ingredients.size() && autorecipestackmanager.a(this, (IntList) null);
+ // Paper start
+ if (matchedProvided.isEmpty() || matchedIngredients.isEmpty()) {
+ return false;
+ }
+ java.util.List<RecipeItemStack> ingredients = new java.util.ArrayList<>(this.ingredients);
+ providedItems.sort(java.util.Comparator.comparingInt((ItemStack c) -> (int) matchedProvided.getCount(c)).reversed());
+ ingredients.sort(java.util.Comparator.comparingInt((RecipeItemStack c) -> (int) matchedIngredients.getCount(c)));

View file

@ -28,7 +28,7 @@ and then catch exceptions and close if they fire.
Part of this commit was authored by: Spottedleaf
diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java
index b1dededc15cce686ead74a99bee64c89ac1de22c..32886109d03f9991446381160d5406056d2bf860 100644
index b1dededc15cce686ead74a99bee64c89ac1de22c..ed63bf3648153ce9ecab75e960c612337cbcbfe8 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -64,6 +64,10 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
@ -55,7 +55,7 @@ index b1dededc15cce686ead74a99bee64c89ac1de22c..32886109d03f9991446381160d540605
this.packetListener = packetlistener;
}
+ // Paper start
+ private EntityPlayer getPlayer() {
+ EntityPlayer getPlayer() {
+ if (packetListener instanceof PlayerConnection) {
+ return ((PlayerConnection) packetListener).player;
+ } else {
@ -331,7 +331,7 @@ index 2d8e6a2f4a0c3c5d74a647d7164b0028781d3bf5..c5edf8c4b01cc7ddac06797133e6fd13
return false;
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 707b4523536dd6c3192451982e6e33ea4e263053..dc86dae6ff15d38fcc3af2a5f65119aa2daf08f0 100644
index 6d7eb21fb05b2771084ab634ff4d32997b62ee9e..133a6eb9785baa0720ae254636d1ecafb5ee0217 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -143,6 +143,7 @@ public abstract class PlayerList {

View file

@ -58,8 +58,20 @@ index 9368c4afa7bbb336894d73069b3c0858231d1e81..ae0f5e5a71502c432a4dcaa42a3fc9ee
// Paper end
} catch (Throwable throwable) {
diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
index cb7cb789b82461093fbbb4c8ae6d03fcbfe57383..f606382963f79fba8c282fa6ca820a10e9ec598d 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
@@ -162,6 +162,7 @@ public abstract class MobSpawnerAbstract {
// Spigot End
}
entity.spawnedViaMobSpawner = true; // Paper
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper
// Spigot Start
flag = true; // Paper
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, blockposition).isCancelled()) {
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 68ec2ef427bee5940c62b61964b5436e6ef425f6..79ab45540081c8e2f5dd1d84c6ae602f3664920f 100644
index 6c0bd57a75f7fc65f412054529793273940d9ff4..c673f3579f868b4a25a46815877289c568e7763b 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -240,7 +240,7 @@ public abstract class PlayerList {

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Mob Spawner API Enhancements
diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
index cb7cb789b82461093fbbb4c8ae6d03fcbfe57383..41001b02a654194c4a8e25ad5f7af8fdd91090b2 100644
index f606382963f79fba8c282fa6ca820a10e9ec598d..820e470cdf5e6d32edae75520a5f6a5d5462b222 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
@@ -47,6 +47,7 @@ public abstract class MobSpawnerAbstract {
@ -16,7 +16,7 @@ index cb7cb789b82461093fbbb4c8ae6d03fcbfe57383..41001b02a654194c4a8e25ad5f7af8fd
private boolean h() {
BlockPosition blockposition = this.b();
@@ -207,6 +208,7 @@ public abstract class MobSpawnerAbstract {
@@ -208,6 +209,7 @@ public abstract class MobSpawnerAbstract {
}
}
@ -24,7 +24,7 @@ index cb7cb789b82461093fbbb4c8ae6d03fcbfe57383..41001b02a654194c4a8e25ad5f7af8fd
private void i() {
if (this.maxSpawnDelay <= this.minSpawnDelay) {
this.spawnDelay = this.minSpawnDelay;
@@ -224,7 +226,13 @@ public abstract class MobSpawnerAbstract {
@@ -225,7 +227,13 @@ public abstract class MobSpawnerAbstract {
}
public void a(NBTTagCompound nbttagcompound) {
@ -38,7 +38,7 @@ index cb7cb789b82461093fbbb4c8ae6d03fcbfe57383..41001b02a654194c4a8e25ad5f7af8fd
this.mobs.clear();
if (nbttagcompound.hasKeyOfType("SpawnPotentials", 9)) {
NBTTagList nbttaglist = nbttagcompound.getList("SpawnPotentials", 10);
@@ -239,10 +247,15 @@ public abstract class MobSpawnerAbstract {
@@ -240,10 +248,15 @@ public abstract class MobSpawnerAbstract {
} else if (!this.mobs.isEmpty()) {
this.setSpawnData((MobSpawnerData) WeightedRandom.a(this.a().random, this.mobs));
}
@ -57,7 +57,7 @@ index cb7cb789b82461093fbbb4c8ae6d03fcbfe57383..41001b02a654194c4a8e25ad5f7af8fd
this.spawnCount = nbttagcompound.getShort("SpawnCount");
}
@@ -267,9 +280,20 @@ public abstract class MobSpawnerAbstract {
@@ -268,9 +281,20 @@ public abstract class MobSpawnerAbstract {
if (minecraftkey == null) {
return nbttagcompound;
} else {

View file

@ -199,7 +199,7 @@ index af810987846efcd2bffbd23c31481b2d31c168dd..331493a172f58e71b464d635efdba461
doChunkInfo(sender, args);
break;
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index dbd14399707cdd43f98af40191be8ff3e76edf43..74295466e53db06d0d019a13768f3575ac61d699 100644
index dbd14399707cdd43f98af40191be8ff3e76edf43..0acb1ee0ea0ad69af17db00f13bc2540bc612872 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -1,5 +1,6 @@
@ -209,12 +209,12 @@ index dbd14399707cdd43f98af40191be8ff3e76edf43..74295466e53db06d0d019a13768f3575
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
@@ -367,4 +368,54 @@ public class PaperConfig {
@@ -367,4 +368,53 @@ public class PaperConfig {
maxBookPageSize = getInt("settings.book-size.page-max", maxBookPageSize);
maxBookTotalSizeMultiplier = getDouble("settings.book-size.total-multiplier", maxBookTotalSizeMultiplier);
}
+
+ public static boolean asyncChunks = false;
+ public static boolean asyncChunks = true;
+ private static void asyncChunks() {
+ ConfigurationSection section;
+ if (version < 15) {
@ -238,7 +238,6 @@ index dbd14399707cdd43f98af40191be8ff3e76edf43..74295466e53db06d0d019a13768f3575
+ section.set("generation", null);
+ section.set("thread-per-world-generation", null);
+
+ asyncChunks = getBoolean("settings.async-chunks.enable", true);
+ int threads = getInt("settings.async-chunks.threads", -1);
+ int cpus = Runtime.getRuntime().availableProcessors();
+ if (threads <= 0) {

View file

@ -5,10 +5,10 @@ Subject: [PATCH] only add passanger entities once from spawners
diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
index 41001b02a654194c4a8e25ad5f7af8fdd91090b2..df494d37be687860878c2709ae7996510118a559 100644
index 820e470cdf5e6d32edae75520a5f6a5d5462b222..699e4d0d7349a50ee106209c394cdab85356d50b 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
@@ -196,7 +196,7 @@ public abstract class MobSpawnerAbstract {
@@ -197,7 +197,7 @@ public abstract class MobSpawnerAbstract {
}
private void a(Entity entity) {

View file

@ -42,7 +42,7 @@ sets the excessive tick delay to the specified ticks (defaults to
60 * 20 ticks, aka 60 seconds)
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 74295466e53db06d0d019a13768f3575ac61d699..f1b41e16c8ce8323a896339c5d822f8ff7d8f7e6 100644
index 0acb1ee0ea0ad69af17db00f13bc2540bc612872..974613ed7ad6dc64f0cd66c004e3187a40134e1b 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -369,6 +369,13 @@ public class PaperConfig {
@ -56,15 +56,15 @@ index 74295466e53db06d0d019a13768f3575ac61d699..f1b41e16c8ce8323a896339c5d822f8f
+ }
+ }
+
public static boolean asyncChunks = false;
public static boolean asyncChunks = true;
private static void asyncChunks() {
ConfigurationSection section;
diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8c8759e25
index 0000000000000000000000000000000000000000..1587424c88fa3fbfc5e41e2232160abbdf6c9d9b
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java
@@ -0,0 +1,622 @@
@@ -0,0 +1,634 @@
+package com.destroystokyo.paper.server.ticklist;
+
+import net.minecraft.server.MCUtil;
@ -72,7 +72,6 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
+import net.minecraft.server.BaseBlockPosition;
+import net.minecraft.server.BlockPosition;
+import net.minecraft.server.ChunkCoordIntPair;
+import net.minecraft.server.ChunkProviderServer;
@ -139,7 +138,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ }
+ private int shortScheduledIndex;
+
+ private long nextTick;
+ private long currentTick;
+
+ private static final boolean WARN_ON_EXCESSIVE_DELAY = Boolean.getBoolean("paper.ticklist-warn-on-excessive-delay");
+ private static final long EXCESSIVE_DELAY_THRESHOLD = Long.getLong("paper.ticklist-excessive-delay-threshold", 60 * 20).longValue(); // 1 min dfl
@ -166,7 +165,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Cleanup"); // Paper
+ this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Ticking"); // Paper
+ this.timingFinished = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Finish");
+ this.nextTick = this.world.getTime();
+ this.currentTick = this.world.getTime();
+ }
+
+ private void queueEntryForTick(final NextTickListEntry<T> entry, final ChunkProviderServer chunkProvider) {
@ -188,7 +187,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ }
+
+ private void addToSchedule(final NextTickListEntry<T> entry) {
+ long delay = entry.getTargetTick() - this.nextTick;
+ long delay = entry.getTargetTick() - (this.currentTick + 1);
+ if (delay < SHORT_SCHEDULE_TICK_THRESHOLD) {
+ if (delay < 0) {
+ // longScheduled orders by tick time, short scheduled does not
@ -249,7 +248,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ }
+ }
+
+ long delay = entry.getTargetTick() - this.nextTick;
+ long delay = entry.getTargetTick() - (this.currentTick + 1);
+ if (delay >= SHORT_SCHEDULE_TICK_THRESHOLD) {
+ this.longScheduled.remove(entry);
+ }
@ -269,7 +268,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ }
+
+ private void prepare() {
+ final long currentTick = this.world.getTime();
+ final long currentTick = this.currentTick;
+
+ final ChunkProviderServer chunkProvider = this.world.getChunkProvider();
+
@ -334,6 +333,20 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ }
+ }
+
+ private boolean warnedAboutDesync;
+
+ @Override
+ protected void nextTick() {
+ ++this.currentTick;
+ if (this.currentTick != this.world.getTime()) {
+ if (!this.warnedAboutDesync) {
+ this.warnedAboutDesync = true;
+ MinecraftServer.LOGGER.error("World tick desync detected! Expected " + this.currentTick + " ticks, but got " + this.world.getTime() + " ticks for world '" + this.world.getWorld().getName() + "'", new Throwable());
+ MinecraftServer.LOGGER.error("Preventing redstone from breaking by refusing to accept new tick time");
+ }
+ }
+ }
+
+ @Override
+ public void tick() {
+ final ChunkProviderServer chunkProvider = this.world.getChunkProvider();
@ -346,7 +359,6 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ // this must be done here in case something schedules in the tick code
+ this.shortScheduled[this.shortScheduledIndex].clear();
+ this.shortScheduledIndex = getNextIndex(this.shortScheduledIndex, SHORT_SCHEDULE_TICK_THRESHOLD);
+ this.nextTick = this.world.getTime() + 1;
+
+ this.timingCleanup.stopTiming();
+ this.world.getMethodProfiler().exitEnter("ticking");
@ -473,7 +485,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+
+ @Override
+ public void schedule(BlockPosition blockPosition, T t, int i, TickListPriority tickListPriority) {
+ this.schedule(blockPosition, t, i + this.world.getTime(), tickListPriority);
+ this.schedule(blockPosition, t, i + this.currentTick, tickListPriority);
+ }
+
+ public void schedule(final NextTickListEntry<T> entry) {
@ -487,7 +499,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ }
+
+ if (WARN_ON_EXCESSIVE_DELAY) {
+ final long delay = entry.getTargetTick() - this.nextTick;
+ final long delay = entry.getTargetTick() - this.currentTick;
+ if (delay >= EXCESSIVE_DELAY_THRESHOLD) {
+ MinecraftServer.LOGGER.warn("Entry " + entry.toString() + " has been scheduled with an excessive delay of: " + delay, new Throwable());
+ }
@ -649,7 +661,7 @@ index 0000000000000000000000000000000000000000..ce653f6b4be3ab6c6d35cb3e9222e7f8
+ // start copy from TickListServer // TODO check on update
+ List<NextTickListEntry<T>> list = this.getEntriesInChunk(chunkcoordintpair, false, true);
+
+ return TickListServer.serialize(this.getMinecraftKeyFrom, list, this.world.getTime());
+ return TickListServer.serialize(this.getMinecraftKeyFrom, list, this.currentTick);
+ // end copy from TickListServer
+ }
+
@ -883,7 +895,7 @@ index 0000000000000000000000000000000000000000..118988c39e58f28e8a2851792b9c014f
+ }
+}
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
index 3fcfe416d26808fa1c9bfdc5b413b149764c544a..3bf17ccdaef21322b787db538d569e0bc614ef22 100644
index 9fc34246a845168d158a6b2793d8e344f2d2b008..8c3e09a5a3b4e6c38790735db4b3b316d7cdd39a 100644
--- a/src/main/java/net/minecraft/server/BlockPosition.java
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
@@ -126,6 +126,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
@ -895,7 +907,7 @@ index 3fcfe416d26808fa1c9bfdc5b413b149764c544a..3bf17ccdaef21322b787db538d569e0b
return this.b(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
}
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 6688b1340e2cc8fb13a7e80c9b7c37b8822dcecd..d53b34ba552771bf271131ce0a56ebb992ccc84c 100644
index e467cd8123dafc46a8c894f1ffa9440de0d45340..9e3471be219b5e061486c8a3e4b638a45e6f28f5 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -200,6 +200,13 @@ public class ChunkProviderServer extends IChunkProvider {
@ -1037,13 +1049,48 @@ index dbb565e74d211ef35d5d40b3d024e2f07cef9031..185658e230688a9939c89dae9167217c
public boolean b(BaseBlockPosition baseblockposition) {
return baseblockposition.getX() >= this.a && baseblockposition.getX() <= this.d && baseblockposition.getZ() >= this.c && baseblockposition.getZ() <= this.f && baseblockposition.getY() >= this.b && baseblockposition.getY() <= this.e;
}
diff --git a/src/main/java/net/minecraft/server/TickListChunk.java b/src/main/java/net/minecraft/server/TickListChunk.java
index eb526530fba30c313482355b74a01258b9b79410..485a029790ea91e61c2bb1a43d75317ecf40b317 100644
--- a/src/main/java/net/minecraft/server/TickListChunk.java
+++ b/src/main/java/net/minecraft/server/TickListChunk.java
@@ -51,6 +51,8 @@ public class TickListChunk<T> implements TickList<T> {
return TickListServer.a(this.b, this.a, i);
}
+ private static final int MAX_TICK_DELAY = Integer.getInteger("paper.ticklist-max-tick-delay", -1).intValue(); // Paper - clean up broken entries
+
public static <T> TickListChunk<T> a(NBTTagList nbttaglist, Function<T, MinecraftKey> function, Function<MinecraftKey, T> function1) {
Set<NextTickListEntry<T>> set = Sets.newHashSet();
@@ -59,7 +61,15 @@ public class TickListChunk<T> implements TickList<T> {
T t0 = function1.apply(new MinecraftKey(nbttagcompound.getString("i")));
if (t0 != null) {
- set.add(new NextTickListEntry<>(new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")), t0, (long) nbttagcompound.getInt("t"), TickListPriority.a(nbttagcompound.getInt("p"))));
+ // Paper start - clean up broken entries
+ NextTickListEntry<T> pending = new NextTickListEntry<>(new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")), t0, (long) nbttagcompound.getInt("t"), TickListPriority.a(nbttagcompound.getInt("p")));
+ long delay = pending.getTargetTick();
+ if (MAX_TICK_DELAY > 0 && delay > MAX_TICK_DELAY) {
+ MinecraftServer.LOGGER.warn("Dropping tick for pos " + pending.getPosition() + ", tick delay " + delay);
+ continue;
+ }
+ set.add(pending);
+ // Paper end - clean up broken entries
}
}
diff --git a/src/main/java/net/minecraft/server/TickListServer.java b/src/main/java/net/minecraft/server/TickListServer.java
index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5dc98b8166 100644
index f533860bbed19ff2915c90186c259b466f41ce90..2888ff74ba1e8e9b29f6e521f7eabc37a5b62920 100644
--- a/src/main/java/net/minecraft/server/TickListServer.java
+++ b/src/main/java/net/minecraft/server/TickListServer.java
@@ -42,6 +42,11 @@ public class TickListServer<T> implements TickList<T> {
@@ -41,7 +41,16 @@ public class TickListServer<T> implements TickList<T> {
private final co.aikar.timings.Timing timingTicking; // Paper
// Paper end
+ // Paper start
+ protected void nextTick() {}
+ // Paper end
+
public void b() {
+ // Paper start - allow overriding
+ this.tick();
@ -1053,7 +1100,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
int i = this.nextTickList.size();
if (false) { // CraftBukkit
@@ -109,15 +114,30 @@ public class TickListServer<T> implements TickList<T> {
@@ -109,15 +118,30 @@ public class TickListServer<T> implements TickList<T> {
@Override
public boolean b(BlockPosition blockposition, T t0) {
@ -1084,7 +1131,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
int i = (chunkcoordintpair.x << 4) - 2;
int j = i + 16 + 2;
int k = (chunkcoordintpair.z << 4) - 2;
@@ -127,6 +147,11 @@ public class TickListServer<T> implements TickList<T> {
@@ -127,6 +151,11 @@ public class TickListServer<T> implements TickList<T> {
}
public List<NextTickListEntry<T>> a(StructureBoundingBox structureboundingbox, boolean flag, boolean flag1) {
@ -1096,7 +1143,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
List<NextTickListEntry<T>> list = this.a((List) null, this.nextTickList, structureboundingbox, flag);
if (flag && list != null) {
@@ -166,6 +191,11 @@ public class TickListServer<T> implements TickList<T> {
@@ -166,6 +195,11 @@ public class TickListServer<T> implements TickList<T> {
}
public void a(StructureBoundingBox structureboundingbox, BlockPosition blockposition) {
@ -1108,7 +1155,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
List<NextTickListEntry<T>> list = this.a(structureboundingbox, false, false);
Iterator iterator = list.iterator();
@@ -183,11 +213,17 @@ public class TickListServer<T> implements TickList<T> {
@@ -183,11 +217,17 @@ public class TickListServer<T> implements TickList<T> {
}
public NBTTagList a(ChunkCoordIntPair chunkcoordintpair) {
@ -1126,7 +1173,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
public static <T> NBTTagList a(Function<T, MinecraftKey> function, Iterable<NextTickListEntry<T>> iterable, long i) {
NBTTagList nbttaglist = new NBTTagList();
Iterator iterator = iterable.iterator();
@@ -210,11 +246,21 @@ public class TickListServer<T> implements TickList<T> {
@@ -210,11 +250,21 @@ public class TickListServer<T> implements TickList<T> {
@Override
public boolean a(BlockPosition blockposition, T t0) {
@ -1148,7 +1195,7 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
if (!this.a.test(t0)) {
this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.f.getTime(), ticklistpriority));
}
@@ -230,6 +276,11 @@ public class TickListServer<T> implements TickList<T> {
@@ -230,6 +280,11 @@ public class TickListServer<T> implements TickList<T> {
}
public int a() {
@ -1160,6 +1207,21 @@ index f533860bbed19ff2915c90186c259b466f41ce90..3f1aa5ced697490b5481ba992cf5af5d
return this.nextTickListHash.size();
}
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index a52d8a27cee6721c32444d9d2bd81135b7d4b859..cbcd41108cda2294275d1843bc24b681145b4767 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1380,7 +1380,9 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
}
protected void a() {
- this.a(this.worldData.getTime() + 1L);
+ this.a(this.worldData.getTime() + 1L); // Paper - diff on change, we want the below to be ran right after this
+ ((TickListServer)this.getBlockTickList()).nextTick(); // Paper
+ ((TickListServer)this.getFluidTickList()).nextTick(); // Paper
if (this.worldData.v().getBoolean(GameRules.DO_DAYLIGHT_CYCLE)) {
this.setDayTime(this.worldData.getDayTime() + 1L);
}
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 7fded15f14a3f5c04a676e9e25413718b9922c13..642b5b485df28149f255ae9b5e43083821b20a0a 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java

View file

@ -42,10 +42,10 @@ index a58ef60d9976b3afc50e94364cf474bd2e5fdfd6..dd07223978c9aa648673d96ba7b3db11
public static final Timing commandFunctionsTimer = Timings.ofSafe("Command Functions");
public static final Timing connectionTimer = Timings.ofSafe("Connection Handler");
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index f1b41e16c8ce8323a896339c5d822f8ff7d8f7e6..f8f225e18fa38cad917f52a379233e0a7a869b07 100644
index 974613ed7ad6dc64f0cd66c004e3187a40134e1b..3e54951d00672ca820333cd6e484271fabc6e1d2 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -425,4 +425,9 @@ public class PaperConfig {
@@ -424,4 +424,9 @@ public class PaperConfig {
log("Async Chunks: Enabled - Chunks will be loaded much faster, without lag.");
}
}

View file

@ -109,7 +109,7 @@ index cfe43e882e524b6ab3d9702e81269c97e6b75eba..2632c7c3ec77918be7979f2aa49209e5
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index a0e33d42a158defc8b4a72de5d01b9395dca42eb..2c9ae5c46a39639fd9f842df23993a47b31c8585 100644
index a0e33d42a158defc8b4a72de5d01b9395dca42eb..e719a1d06f119483db9a891bacaf1bbb665c6b90 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -144,6 +144,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -137,31 +137,27 @@ index a0e33d42a158defc8b4a72de5d01b9395dca42eb..2c9ae5c46a39639fd9f842df23993a47
private final Object stopLock = new Object();
public final boolean hasStopped() {
synchronized (stopLock) {
@@ -725,10 +727,22 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// CraftBukkit start - prevent double stopping on multiple threads
synchronized(stopLock) {
@@ -727,6 +729,19 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
if (hasStopped) return;
+ shutdownThread = Thread.currentThread();
hasStopped = true;
+ org.spigotmc.WatchdogThread.doStop(); // Paper
+ // Paper start - kill main thread, and kill it hard
+ if (!isMainThread()) {
+ while (this.getThread().isAlive()) {
+ this.getThread().stop();
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {}
+ }
+ }
+ // Paper end
}
+ // Paper start - kill main thread, and kill it hard
+ shutdownThread = Thread.currentThread();
+ org.spigotmc.WatchdogThread.doStop(); // Paper
+ if (!isMainThread()) {
+ MinecraftServer.LOGGER.info("Stopping main thread (Ignore any thread death message you see! - DO NOT REPORT THREAD DEATH TO PAPER)");
+ while (this.getThread().isAlive()) {
+ this.getThread().stop();
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {}
+ }
+ }
+ // Paper end
// CraftBukkit end
- MinecraftServer.LOGGER.info("Stopping server");
+ MinecraftServer.LOGGER.info("Stopping server (Ignore any thread death message you see! - DO NOT REPORT THREAD DEATH TO PAPER)"); // Paper
MinecraftServer.LOGGER.info("Stopping server");
MinecraftTimings.stopServer(); // Paper
// CraftBukkit start
if (this.server != null) {
@@ -785,7 +799,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -785,7 +800,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.getUserCache().c(false); // Paper
}
// Spigot end
@ -180,7 +176,7 @@ index a0e33d42a158defc8b4a72de5d01b9395dca42eb..2c9ae5c46a39639fd9f842df23993a47
}
public String getServerIp() {
@@ -878,6 +903,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -878,6 +904,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
public void run() {
try {
@ -188,7 +184,7 @@ index a0e33d42a158defc8b4a72de5d01b9395dca42eb..2c9ae5c46a39639fd9f842df23993a47
if (this.init()) {
this.nextTick = SystemUtils.getMonotonicMillis();
this.serverPing.setMOTD(new ChatComponentText(this.motd));
@@ -885,6 +911,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -885,6 +912,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.a(this.serverPing);
// Spigot start
@ -207,7 +203,7 @@ index a0e33d42a158defc8b4a72de5d01b9395dca42eb..2c9ae5c46a39639fd9f842df23993a47
org.spigotmc.WatchdogThread.hasStarted = true; // Paper
Arrays.fill( recentTps, 20 );
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
@@ -941,6 +979,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -941,6 +980,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.a((CrashReport) null);
}
} catch (Throwable throwable) {
@ -220,7 +216,7 @@ index a0e33d42a158defc8b4a72de5d01b9395dca42eb..2c9ae5c46a39639fd9f842df23993a47
MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable);
// Spigot Start
if ( throwable.getCause() != null )
@@ -972,14 +1016,14 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -972,14 +1017,14 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
} catch (Throwable throwable1) {
MinecraftServer.LOGGER.error("Exception stopping the server", throwable1);
} finally {
@ -238,7 +234,7 @@ index a0e33d42a158defc8b4a72de5d01b9395dca42eb..2c9ae5c46a39639fd9f842df23993a47
}
}
@@ -1035,6 +1079,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1035,6 +1080,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@Override
protected TickTask postToMainThread(Runnable runnable) {
@ -251,7 +247,7 @@ index a0e33d42a158defc8b4a72de5d01b9395dca42eb..2c9ae5c46a39639fd9f842df23993a47
return new TickTask(this.ticks, runnable);
}
@@ -1278,6 +1328,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1278,6 +1329,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
midTickLoadChunks(); // Paper
} catch (Throwable throwable) {
// Spigot Start
@ -297,7 +293,7 @@ index 20d803ad68ea65fd725d6eb3317b998c1692a7b3..aa399e7f6518ff70f2214161319170b1
SystemUtils.c.shutdown();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index a52d8a27cee6721c32444d9d2bd81135b7d4b859..bdd0908adb7d3cd5370b43be196c975e6c48a70f 100644
index cbcd41108cda2294275d1843bc24b681145b4767..e5a023b44562bb0c5f125d43c77936eab4994310 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -793,6 +793,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {

View file

@ -10,10 +10,10 @@ Adds a 5 second grace period for any async tasks to finish and warns
if any are still running after that delay just as reload does.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 2c9ae5c46a39639fd9f842df23993a47b31c8585..4ab6579032043f570c20befa7fef8931babd2355 100644
index e719a1d06f119483db9a891bacaf1bbb665c6b90..5c71efe494faaf7427f82036d60cc81447e4b12c 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -747,6 +747,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -748,6 +748,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// CraftBukkit start
if (this.server != null) {
this.server.disablePlugins();

View file

@ -13,10 +13,10 @@ A config is provided if you rather let players use these exploits, and let
them destroy the worlds End Portals and get on top of the nether easy.
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 3ee7e5671dd2519cec72b81211f1f39176a228ba..cf9b9de8688e3f655631451409096d7ec0471910 100644
index f51c29d73835f8453507b32b954278cbef7fbc50..26f12b3033971f796aaf734d3b4a8709a2b726af 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -431,4 +431,10 @@ public class PaperConfig {
@@ -430,4 +430,10 @@ public class PaperConfig {
private static void midTickChunkTasks() {
midTickChunkTasks = getInt("settings.chunk-tasks-per-tick", midTickChunkTasks);
}

View file

@ -5,10 +5,10 @@ Subject: [PATCH] Add option for console having all permissions
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index cf9b9de8688e3f655631451409096d7ec0471910..f0284e81db3ab7c45018de2b446f2d8296df15c3 100644
index 26f12b3033971f796aaf734d3b4a8709a2b726af..a253aa55447ba447591cbfb4958de261aa114eaa 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -437,4 +437,9 @@ public class PaperConfig {
@@ -436,4 +436,9 @@ public class PaperConfig {
allowBlockPermanentBreakingExploits = getBoolean("allow-perm-block-break-exploits", allowBlockPermanentBreakingExploits);
}

View file

@ -631,7 +631,7 @@ index ce0bf608b71cf492fc31e89a360ecd83fa5c23a6..87d58002116f361d8255d79fc0dbd120
chunkData.addProperty("queued-for-unload", chunkMap.unloadQueue.contains(playerChunk.location.pair()));
chunkData.addProperty("status", status == null ? "unloaded" : status.toString());
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..52da9c78c0cc2b21533a1477a25a3dda492700e4 100644
index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..72afc736c0973a9c2160b571aa740ba5fe374796 100644
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
@@ -26,8 +26,8 @@ public class PlayerChunk {
@ -682,7 +682,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..52da9c78c0cc2b21533a1477a25a3dda
+ }
+
+ private int getNeighborsPriority() {
+ return neighborPriorities.isEmpty() ? getMyPriority() : getDemandedPriority();
+ return (neighborPriorities.isEmpty() ? getMyPriority() : getDemandedPriority()) + 1;
+ }
+
+ public void onNeighborRequest(PlayerChunk neighbor, ChunkStatus status) {
@ -885,7 +885,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..52da9c78c0cc2b21533a1477a25a3dda
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..3139d55bb801b6c433de7274be4a1d0c0fd1eef7 100644
index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4bfef7520af497a29008919d5ff65d6db16e22a8 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -50,6 +50,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
@ -988,13 +988,13 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..3139d55bb801b6c433de7274be4a1d0c
+
+ double dist = MCUtil.distance(playerChunkX, 0, playerChunkZ, coord.x, 0, coord.z);
+ // Prioritize immediate
+ if (dist <= 4 * 4) {
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (27 - Math.sqrt(dist)));
+ if (dist <= 4) {
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (27 - dist));
+ return;
+ }
+
+ // Prioritize nearby chunks
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (20 - Math.sqrt(dist) * twoThirdModifier));
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (20 - dist * twoThirdModifier));
+ });
+
+ // Prioritize Frustum near 3
@ -1004,7 +1004,7 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..3139d55bb801b6c433de7274be4a1d0c
+ if (shouldSkipPrioritization(coord)) return;
+
+ double dist = MCUtil.distance(playerChunkX, 0, playerChunkZ, coord.x, 0, coord.z);
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (25 - Math.sqrt(dist) * twoThirdModifier));
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (25 - dist * twoThirdModifier));
+ });
+
+ // Prioritize Frustum near 5
@ -1015,7 +1015,7 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..3139d55bb801b6c433de7274be4a1d0c
+ if (shouldSkipPrioritization(coord)) return;
+
+ double dist = MCUtil.distance(playerChunkX, 0, playerChunkZ, coord.x, 0, coord.z);
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (25 - Math.sqrt(dist) * twoThirdModifier));
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (25 - dist * twoThirdModifier));
+ });
+ }
+
@ -1028,7 +1028,7 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..3139d55bb801b6c433de7274be4a1d0c
+ return;
+ }
+ double dist = MCUtil.distance(playerChunkX, 0, playerChunkZ, coord.x, 0, coord.z);
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (25 - Math.sqrt(dist) * twoThirdModifier));
+ updateChunkPriorityMap(priorities, coord.pair(), (int) (25 - dist * twoThirdModifier));
+ });
+ }
+
@ -1123,7 +1123,7 @@ index d52fbda79fe1c52d3ddb53c0f1c1f521d7620702..f9cb87a3be35575ecf3362b10dc7fe5e
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 6daca5c0ffd1d84f9a25cd106e8992a055dfb912..f133e7baf958b031819c2c72ccd21c52ba9a683d 100644
index 74571c1befa60e71e93de8052740a56f7b80e920..f0fe864026dc10cd809f06dc9d4e823c21494a8d 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -174,8 +174,8 @@ public abstract class PlayerList {

View file

@ -1095,30 +1095,33 @@ index 097f58e9ac3f4096d3b9dad75b6ebe76021fa92c..f744f62c93370d096c113f92ee81a823
lightenginelayer.a(Long.MAX_VALUE, l3, 15, false);
}
diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/main/java/net/minecraft/server/LightEngineThreaded.java
index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d7de86509 100644
index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..2985be96e7f72bf02169f9cd901ef217d848c3fb 100644
--- a/src/main/java/net/minecraft/server/LightEngineThreaded.java
+++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java
@@ -14,8 +14,98 @@ import org.apache.logging.log4j.Logger;
public class LightEngineThreaded extends LightEngine implements AutoCloseable {
@@ -1,6 +1,7 @@
package net.minecraft.server;
import com.mojang.datafixers.util.Pair;
+import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectList;
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
@@ -15,15 +16,149 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
private static final Logger LOGGER = LogManager.getLogger();
- private final ThreadedMailbox<Runnable> b;
private final ThreadedMailbox<Runnable> b;
- private final ObjectList<Pair<LightEngineThreaded.Update, Runnable>> c = new ObjectArrayList();
+ private final ThreadedMailbox<Runnable> b; ThreadedMailbox<Runnable> mailbox; // Paper
- private final PlayerChunkMap d;
+ // Paper start
+ private static final int MAX_PRIORITIES = PlayerChunkMap.GOLDEN_TICKET + 2;
+
+ public void changePriority(long pair, int currentPriority, int priority) {
+ this.mailbox.queue(() -> {
+ ChunkLightQueue remove = this.queue.buckets[currentPriority].remove(pair);
+ if (remove != null) {
+ ChunkLightQueue existing = this.queue.buckets[priority].put(pair, remove);
+ if (existing != null) {
+ remove.pre.addAll(existing.pre);
+ remove.post.addAll(existing.post);
+ }
+ }
+ });
+ private boolean isChunkLightStatus(long pair) {
+ PlayerChunk playerChunk = playerChunkMap.getUpdatingChunk(pair);
+ if (playerChunk == null) {
+ return false;
+ }
+ ChunkStatus status = PlayerChunk.getChunkStatus(playerChunk.getTicketLevel());
+ return status != null && status.isAtLeastStatus(ChunkStatus.LIGHT);
+ }
+
+ static class ChunkLightQueue {
@ -1129,41 +1132,76 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
+ ChunkLightQueue(long chunk) {}
+ }
+
+ static class PendingLightTask {
+ long chunkId;
+ IntSupplier priority;
+ Runnable pre;
+ Runnable post;
+ boolean fastUpdate;
+
+ public PendingLightTask(long chunkId, IntSupplier priority, Runnable pre, Runnable post, boolean fastUpdate) {
+ this.chunkId = chunkId;
+ this.priority = priority;
+ this.pre = pre;
+ this.post = post;
+ this.fastUpdate = fastUpdate;
+ }
+ }
+
+
+ // Retain the chunks priority level for queued light tasks
+ private static class LightQueue {
+ class LightQueue {
+ private int size = 0;
+ private int lowestPriority = MAX_PRIORITIES;
+ private final it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = new it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap[MAX_PRIORITIES];
+ private final Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = new Long2ObjectLinkedOpenHashMap[MAX_PRIORITIES];
+ private final java.util.concurrent.ConcurrentLinkedQueue<PendingLightTask> pendingTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
+ private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> priorityChanges = new java.util.concurrent.ConcurrentLinkedQueue<>();
+
+ private LightQueue() {
+ for (int i = 0; i < buckets.length; i++) {
+ buckets[i] = new it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<>();
+ buckets[i] = new Long2ObjectLinkedOpenHashMap<>();
+ }
+ }
+
+ public final void add(long chunkId, int priority, LightEngineThreaded.Update type, Runnable run) {
+ add(chunkId, priority, type, run, false);
+ public void changePriority(long pair, int currentPriority, int priority) {
+ this.priorityChanges.add(() -> {
+ ChunkLightQueue remove = this.buckets[currentPriority].remove(pair);
+ if (remove != null) {
+ ChunkLightQueue existing = this.buckets[Math.max(1, priority)].put(pair, remove);
+ if (existing != null) {
+ remove.pre.addAll(existing.pre);
+ remove.post.addAll(existing.post);
+ }
+ }
+ });
+ }
+ public final void add(long chunkId, int priority, LightEngineThreaded.Update type, Runnable run, boolean shouldFastUpdate) {
+ ChunkLightQueue lightQueue = this.buckets[priority].computeIfAbsent(chunkId, ChunkLightQueue::new);
+ this.size++;
+ if (type == Update.PRE_UPDATE) {
+ lightQueue.pre.add(run);
+ } else {
+ lightQueue.post.add(run);
+
+ public final void addChunk(long chunkId, IntSupplier priority, Runnable pre, Runnable post) {
+ pendingTasks.add(new PendingLightTask(chunkId, priority, pre, post, true));
+ queueUpdate();
+ }
+
+ public final void add(long chunkId, IntSupplier priority, LightEngineThreaded.Update type, Runnable run) {
+ pendingTasks.add(new PendingLightTask(chunkId, priority, type == Update.PRE_UPDATE ? run : null, type == Update.POST_UPDATE ? run : null, false));
+ }
+ public final void add(PendingLightTask update) {
+ int priority = update.priority.getAsInt();
+ ChunkLightQueue lightQueue = this.buckets[priority].computeIfAbsent(update.chunkId, ChunkLightQueue::new);
+
+ if (update.pre != null) {
+ this.size++;
+ lightQueue.pre.add(update.pre);
+ }
+ if (shouldFastUpdate) {
+ if (update.post != null) {
+ this.size++;
+ lightQueue.post.add(update.post);
+ }
+ if (update.fastUpdate) {
+ lightQueue.shouldFastUpdate = true;
+ }
+
+ if (this.lowestPriority > priority) {
+ this.lowestPriority = priority;
+ }
+ }
+
+ public final boolean isEmpty() {
+ return this.size == 0;
+ return this.size == 0 && this.pendingTasks.isEmpty();
+ }
+
+ public final int size() {
@ -1171,13 +1209,26 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
+ }
+
+ public boolean poll(java.util.List<Runnable> pre, java.util.List<Runnable> post) {
+ PendingLightTask pending;
+ while ((pending = pendingTasks.poll()) != null) {
+ add(pending);
+ }
+ Runnable run;
+ while ((run = priorityChanges.poll()) != null) {
+ run.run();
+ }
+ boolean hasWork = false;
+ it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = this.buckets;
+ while (lowestPriority < MAX_PRIORITIES && !isEmpty()) {
+ it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue> bucket = buckets[lowestPriority];
+ Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = this.buckets;
+ int priority = 0;
+ while (priority < MAX_PRIORITIES && !isEmpty()) {
+ Long2ObjectLinkedOpenHashMap<ChunkLightQueue> bucket = buckets[priority];
+ if (bucket.isEmpty()) {
+ lowestPriority++;
+ continue;
+ priority++;
+ if (hasWork) {
+ return true;
+ } else {
+ continue;
+ }
+ }
+ ChunkLightQueue queue = bucket.removeFirst();
+ this.size -= queue.pre.size() + queue.post.size();
@ -1194,59 +1245,73 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
+ }
+ }
+
+ private final LightQueue queue = new LightQueue();
+ final LightQueue queue = new LightQueue();
+ // Paper end
private final PlayerChunkMap d;
+ private final PlayerChunkMap d; private final PlayerChunkMap playerChunkMap; // Paper
private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> e;
private volatile int f = 5;
@@ -25,7 +115,7 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
private final AtomicBoolean g = new AtomicBoolean();
public LightEngineThreaded(ILightAccess ilightaccess, PlayerChunkMap playerchunkmap, boolean flag, ThreadedMailbox<Runnable> threadedmailbox, Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailbox) {
super(ilightaccess, true, flag);
this.d = playerchunkmap;
- this.d = playerchunkmap;
+ this.d = playerchunkmap; this.playerChunkMap = d; // Paper
this.e = mailbox;
- this.b = threadedmailbox;
+ this.mailbox = this.b = threadedmailbox; // Paper
this.b = threadedmailbox;
}
@@ -110,13 +245,9 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
}
public void close() {}
@@ -111,8 +201,11 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) {
this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error
- this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error
- this.c.add(Pair.of(lightenginethreaded_update, runnable));
- if (this.c.size() >= this.f) {
+ // Paper start
+ int priority = intsupplier.getAsInt();
+ this.queue.add(ChunkCoordIntPair.pair(i, j), priority, lightenginethreaded_update, runnable); // Paper
+ if (priority <= 25) { // don't auto kick off unless priority
+ // Paper end
this.b();
}
- this.b();
- }
-
- }, ChunkCoordIntPair.pair(i, j), intsupplier));
+ // Paper start - replace method
+ this.queue.add(ChunkCoordIntPair.pair(i, j), intsupplier, lightenginethreaded_update, runnable);
+ // Paper end
}
@@ -134,7 +227,14 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
@Override
@@ -133,8 +264,19 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
public CompletableFuture<IChunkAccess> a(IChunkAccess ichunkaccess, boolean flag) {
ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
ichunkaccess.b(false);
- ichunkaccess.b(false);
- this.a(chunkcoordintpair.x, chunkcoordintpair.z, LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> {
+ // Paper start
+ //ichunkaccess.b(false); // Don't need to disable this
+ long pair = chunkcoordintpair.pair();
+ CompletableFuture<IChunkAccess> future = new CompletableFuture<>();
+ IntSupplier prioritySupplier1 = d.getPrioritySupplier(pair);
+ IntSupplier prioritySupplier = flag ? () -> Math.max(1, prioritySupplier1.getAsInt() - 10) : prioritySupplier1;
+ this.e.a(ChunkTaskQueueSorter.a(() -> {
+ this.queue.add(pair, prioritySupplier.getAsInt(), LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> {
+ // Paper end
+ IntSupplier prioritySupplier = playerChunkMap.getPrioritySupplier(pair);
+ boolean[] skippedPre = {false};
+ this.queue.addChunk(pair, prioritySupplier, SystemUtils.a(() -> {
+ if (!isChunkLightStatus(pair)) {
+ future.complete(ichunkaccess);
+ skippedPre[0] = true;
+ return;
+ }
+ // Paper end
ChunkSection[] achunksection = ichunkaccess.getSections();
for (int i = 0; i < 16; ++i) {
@@ -155,52 +255,51 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
this.d.c(chunkcoordintpair);
@@ -152,55 +294,48 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
});
}
- this.d.c(chunkcoordintpair);
+ // this.d.c(chunkcoordintpair); // Paper - move into post task below
}, () -> {
return "lightChunk " + chunkcoordintpair + " " + flag;
+ // Paper start - merge the 2 together
}));
- }));
- return CompletableFuture.supplyAsync(() -> {
+
+ this.queue.add(pair, prioritySupplier.getAsInt(), LightEngineThreaded.Update.POST_UPDATE, () -> {
+ // Paper start - merge the 2 together
+ }), () -> {
+ this.d.c(chunkcoordintpair); // Paper - release light tickets as post task to ensure they stay loaded until fully done
+ if (skippedPre[0]) return; // Paper - future's already complete
ichunkaccess.b(true);
super.b(chunkcoordintpair, false);
- return ichunkaccess;
@ -1255,8 +1320,6 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
+ // Paper start
+ future.complete(ichunkaccess);
});
+ queueUpdate(); // run queue now
+ }, pair, prioritySupplier));
+ return future;
+ // Paper end
}
@ -1288,15 +1351,15 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
- if (pair.getFirst() == LightEngineThreaded.Update.PRE_UPDATE) {
- ((Runnable) pair.getSecond()).run();
- }
+ int i = Math.min(queue.size(), 4);
+ boolean ran = false;
+ while (i-- > 0 && queue.poll(pre, post)) {
+ if (queue.poll(pre, post)) {
+ pre.forEach(Runnable::run);
+ pre.clear();
+ super.a(Integer.MAX_VALUE, true, true);
+ post.forEach(Runnable::run);
+ post.clear();
+ ran = true;
+ } else {
+ // might have level updates to go still
+ super.a(Integer.MAX_VALUE, true, true);
}
-
- objectlistiterator.back(j);
@ -1309,10 +1372,7 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
- }
-
- objectlistiterator.remove();
+ if (!ran) {
+ // might have level updates to go still
+ super.a(Integer.MAX_VALUE, true, true);
}
- }
-
+ // Paper end
}
@ -1337,22 +1397,48 @@ index 8cedfdd820cc02a76607b53e0b054fc74654f907..a9795394c9b17f9f0ce4c4f9c8f51a48
private static final int nibbleBucketSizeMultiplier = Integer.getInteger("Paper.nibbleBucketSize", 3072);
private static final int maxPoolSize = Integer.getInteger("Paper.maxNibblePoolSize", (int) Math.min(6, Math.max(1, Runtime.getRuntime().maxMemory() / 1024 / 1024 / 1024)) * (nibbleBucketSizeMultiplier * 8));
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
index 69899c100dd86c6c4795013364472336327ce036..2edb4904d3071aa9de6517c375410b814a45cfbe 100644
index edda76f5ef443186b1c7296352a4c0c1f0d9037a..6a7ba0af771c584edf8db55d5ef67552ce10e17e 100644
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
@@ -728,6 +728,7 @@ public class PlayerChunk {
ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY;
}
chunkMap.world.asyncChunkTaskManager.raisePriority(location.x, location.z, ioPriority);
+ chunkMap.world.getChunkProvider().getLightEngine().changePriority(location.pair(), getCurrentPriority(), priority);
+ chunkMap.world.getChunkProvider().getLightEngine().queue.changePriority(location.pair(), getCurrentPriority(), priority);
}
if (getCurrentPriority() != priority) {
this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 98adcb6390105a183d66975ed9659906b609ce08..201221df63d4ec8e704fee9126240891f2b1c37d 100644
index 3ecd4a8c2b02652359f70cf1d70a3f9bbbf1f30a..f76dd80fc533928d194cc2e2995417b51966f393 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -647,6 +647,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -270,7 +270,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
// Paper end
-
+ private final java.util.concurrent.ExecutorService lightThread; // Paper
public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler<Runnable> iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator<?> chunkgenerator, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier, int i) {
super(new File(worldserver.getWorldProvider().getDimensionManager().a(file), "region"), datafixer);
//this.visibleChunks = this.updatingChunks.clone(); // Paper - no more cloning
@@ -301,7 +301,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
Mailbox<Runnable> mailbox = Mailbox.a("main", iasynctaskhandler::a);
this.worldLoadListener = worldloadlistener;
- ThreadedMailbox<Runnable> lightthreaded; ThreadedMailbox<Runnable> threadedmailbox1 = lightthreaded = ThreadedMailbox.a(executor, "light"); // Paper
+ // Paper start - use light thread
+ ThreadedMailbox<Runnable> lightthreaded; ThreadedMailbox<Runnable> threadedmailbox1 = lightthreaded = ThreadedMailbox.a(lightThread = java.util.concurrent.Executors.newSingleThreadExecutor(r -> {
+ Thread thread = new Thread(r);
+ thread.setName((world.getWorldData()).getName() + " - Light");
+ thread.setDaemon(true);
+ thread.setPriority(Thread.NORM_PRIORITY+1);
+ return thread;
+ }), "light");
+ // Paper end
this.p = new ChunkTaskQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE);
this.mailboxWorldGen = this.p.a(threadedmailbox, false);
@@ -647,6 +655,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
// Paper end
}
@ -1360,6 +1446,14 @@ index 98adcb6390105a183d66975ed9659906b609ce08..201221df63d4ec8e704fee9126240891
protected IntSupplier c(long i) {
return () -> {
PlayerChunk playerchunk = this.getVisibleChunk(i);
@@ -774,6 +783,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Override
public void close() throws IOException {
try {
+ this.lightThread.shutdown(); // Paper
this.p.close();
this.world.asyncChunkTaskManager.close(true); // Paper - Required since we're closing regionfiles in the next line
this.m.close();
diff --git a/src/main/java/net/minecraft/server/ThreadedMailbox.java b/src/main/java/net/minecraft/server/ThreadedMailbox.java
index 8082569022384a3ba03fb4a6f1ae12b443598dcb..3db8073f5182fe4dd4c710b202afc323dfb9b2d2 100644
--- a/src/main/java/net/minecraft/server/ThreadedMailbox.java

View file

@ -32,10 +32,10 @@ This patch fixes https://bugs.mojang.com/browse/MC-188840
This patch also fixes rail duping and carpet duping.
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index f0284e81db3ab7c45018de2b446f2d8296df15c3..8444819f071b13e98ba07032520016a664b7b9bc 100644
index a253aa55447ba447591cbfb4958de261aa114eaa..5d4783e357218694ac52ec0ab5c030470cc6595f 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -442,4 +442,9 @@ public class PaperConfig {
@@ -441,4 +441,9 @@ public class PaperConfig {
consoleHasAllPermissions = getBoolean("settings.console-has-all-permissions", consoleHasAllPermissions);
}

View file

@ -0,0 +1,71 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Sun, 5 Jul 2020 22:59:38 -0400
Subject: [PATCH] Optimize NetworkManager Exception Handling
diff --git a/src/main/java/net/minecraft/server/EnumProtocol.java b/src/main/java/net/minecraft/server/EnumProtocol.java
index 7cba1edc3f2e8fb7cfa730efa0fb3cc5580f12e1..300286354f58d7761ede06ab2df8d42cfe3d936e 100644
--- a/src/main/java/net/minecraft/server/EnumProtocol.java
+++ b/src/main/java/net/minecraft/server/EnumProtocol.java
@@ -128,6 +128,7 @@ public enum EnumProtocol {
@Nullable
public Packet<?> a(int i) {
+ if (i < 0 || i >= this.b.size()) return null; // Paper
Supplier<? extends Packet<T>> supplier = (Supplier) this.b.get(i);
return supplier != null ? (Packet) supplier.get() : null;
diff --git a/src/main/java/net/minecraft/server/PacketSplitter.java b/src/main/java/net/minecraft/server/PacketSplitter.java
index cdaa8be90d16b0e9e2f92a3e2ed120b856feab54..2aaa8770edfd8acc6861c23176e405863858b275 100644
--- a/src/main/java/net/minecraft/server/PacketSplitter.java
+++ b/src/main/java/net/minecraft/server/PacketSplitter.java
@@ -9,11 +9,21 @@ import java.util.List;
public class PacketSplitter extends ByteToMessageDecoder {
+ private final byte[] lenBuf = new byte[3]; // Paper
public PacketSplitter() {}
protected void decode(ChannelHandlerContext channelhandlercontext, ByteBuf bytebuf, List<Object> list) throws Exception {
+ // Paper start - if channel is not active just discard the packet
+ if (!channelhandlercontext.channel().isActive()) {
+ bytebuf.skipBytes(bytebuf.readableBytes());
+ return;
+ }
+ // Paper end
bytebuf.markReaderIndex();
- byte[] abyte = new byte[3];
+ // Paper start - reuse temporary length buffer
+ byte[] abyte = lenBuf;
+ java.util.Arrays.fill(abyte, (byte) 0);
+ // Paper end
for (int i = 0; i < abyte.length; ++i) {
if (!bytebuf.isReadable()) {
diff --git a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
index eb3269e0ea3ce33d08e9eee3bca7cf434921e991..7ea293f38dedd6066601d94adbe175a31c502e1f 100644
--- a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
+++ b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
@@ -22,6 +22,21 @@ public class PlayerConnectionUtils {
try (Timing ignored = timing.startTiming()) { // Paper - timings
packet.a(t0);
} // Paper - timings
+ // Paper start
+ catch (Exception e) {
+ NetworkManager networkmanager = t0.a();
+ if (networkmanager.getPlayer() != null) {
+ LOGGER.error("Error whilst processing packet {} for {}[{}]", packet, networkmanager.getPlayer().getName(), networkmanager.getSocketAddress(), e);
+ } else {
+ LOGGER.error("Error whilst processing packet {} for connection from {}", packet, networkmanager.getSocketAddress(), e);
+ }
+ ChatComponentText error = new ChatComponentText("Packet processing error");
+ networkmanager.sendPacket(new PacketPlayOutKickDisconnect(error), (future) -> {
+ networkmanager.close(error);
+ });
+ networkmanager.stopReading();
+ }
+ // Paper end
} else {
PlayerConnectionUtils.LOGGER.debug("Ignoring packet due to disconnection: " + packet);
}

View file

@ -0,0 +1,95 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Fri, 24 Jul 2020 15:56:05 -0700
Subject: [PATCH] Fix some rails connecting improperly
diff --git a/src/main/java/net/minecraft/server/BlockMinecartDetector.java b/src/main/java/net/minecraft/server/BlockMinecartDetector.java
index cbc19202465c128f22933df25661811cc9f99a8f..84e2d402cc749063cd83afb5ed2513d2168944bb 100644
--- a/src/main/java/net/minecraft/server/BlockMinecartDetector.java
+++ b/src/main/java/net/minecraft/server/BlockMinecartDetector.java
@@ -55,6 +55,7 @@ public class BlockMinecartDetector extends BlockMinecartTrackAbstract {
}
private void a(World world, BlockPosition blockposition, IBlockData iblockdata) {
+ if (iblockdata.getBlock() != this) { return; } // Paper - not our block, don't do anything
boolean flag = (Boolean) iblockdata.get(BlockMinecartDetector.POWERED);
boolean flag1 = false;
List<EntityMinecartAbstract> list = this.a(world, blockposition, EntityMinecartAbstract.class, (Predicate) null);
diff --git a/src/main/java/net/minecraft/server/BlockMinecartTrackAbstract.java b/src/main/java/net/minecraft/server/BlockMinecartTrackAbstract.java
index 18d60b85aa05bf5575ff65b202786f56deff5b51..4ad2e4932dcf60a90027e08ef037e9cca579dfc4 100644
--- a/src/main/java/net/minecraft/server/BlockMinecartTrackAbstract.java
+++ b/src/main/java/net/minecraft/server/BlockMinecartTrackAbstract.java
@@ -41,6 +41,7 @@ public abstract class BlockMinecartTrackAbstract extends Block {
iblockdata = this.a(world, blockposition, iblockdata, true);
if (this.c) {
iblockdata.doPhysics(world, blockposition, this, blockposition, flag);
+ iblockdata = world.getType(blockposition); // Paper - don't desync, update again
}
}
diff --git a/src/main/java/net/minecraft/server/MinecartTrackLogic.java b/src/main/java/net/minecraft/server/MinecartTrackLogic.java
index 8f9eef8237932d78487e2a6c3c7302e1e233f3fd..f78321d4ff2f633d7291bc44c478068f384612ca 100644
--- a/src/main/java/net/minecraft/server/MinecartTrackLogic.java
+++ b/src/main/java/net/minecraft/server/MinecartTrackLogic.java
@@ -7,13 +7,19 @@ import javax.annotation.Nullable;
public class MinecartTrackLogic {
- private final World a;
- private final BlockPosition b;
+ private final World a; public final World getWorld() { return this.a; } // Paper - OBFHELPER
+ private final BlockPosition b; public final BlockPosition getPos() { return this.b; } // Paper - OBFHELPER
private final BlockMinecartTrackAbstract c;
- private IBlockData d;
+ private IBlockData d; public final IBlockData getRailState() { return this.d; } // Paper - OBFHELPER
private final boolean e;
private final List<BlockPosition> f = Lists.newArrayList();
+ // Paper start - prevent desync
+ public boolean isValid() {
+ return this.getWorld().getType(this.getPos()).getBlock() == this.getRailState().getBlock();
+ }
+ // Paper end - prevent desync
+
public MinecartTrackLogic(World world, BlockPosition blockposition, IBlockData iblockdata) {
this.a = world;
this.b = blockposition;
@@ -148,6 +154,11 @@ public class MinecartTrackLogic {
}
private void c(MinecartTrackLogic minecarttracklogic) {
+ // Paper start - prevent desync
+ if (!this.isValid() || !minecarttracklogic.isValid()) {
+ return;
+ }
+ // Paper end - prevent desync
this.f.add(minecarttracklogic.b);
BlockPosition blockposition = this.b.north();
BlockPosition blockposition1 = this.b.south();
@@ -342,11 +353,16 @@ public class MinecartTrackLogic {
this.d = (IBlockData) this.d.set(this.c.d(), blockpropertytrackposition1);
if (flag1 || this.a.getType(this.b) != this.d) {
this.a.setTypeAndData(this.b, this.d, 3);
+ // Paper start - prevent desync
+ if (!this.isValid()) {
+ return this;
+ }
+ // Paper end - prevent desync
for (int i = 0; i < this.f.size(); ++i) {
MinecartTrackLogic minecarttracklogic = this.b((BlockPosition) this.f.get(i));
- if (minecarttracklogic != null) {
+ if (minecarttracklogic != null && minecarttracklogic.isValid()) { // Paper - prevent desync
minecarttracklogic.d();
if (minecarttracklogic.b(this)) {
minecarttracklogic.c(this);
@@ -359,6 +375,6 @@ public class MinecartTrackLogic {
}
public IBlockData c() {
- return this.d;
+ return this.getWorld().getType(this.getPos()); // Paper - prevent desync
}
}

View file

@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wyatt Childers <wchilders@nearce.com>
Date: Sat, 4 Jul 2020 23:07:43 -0400
Subject: [PATCH] Optimize the advancement data player iteration to be O(N)
rather than O(N^2)
diff --git a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
index c41e1384724ab150f43dc43fe2a453c9b1262e48..ac7b6734728f912ab9f02dc417f5924b3725adde 100644
--- a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
+++ b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
@@ -436,6 +436,16 @@ public class AdvancementDataPlayer {
}
private void e(Advancement advancement) {
+ // Paper start
+ e(advancement, IterationEntryPoint.ROOT);
+ }
+ private enum IterationEntryPoint {
+ ROOT,
+ ITERATOR,
+ PARENT_OF_ITERATOR
+ }
+ private void e(Advancement advancement, IterationEntryPoint entryPoint) {
+ // Paper end
boolean flag = this.f(advancement);
boolean flag1 = this.g.contains(advancement);
@@ -451,15 +461,23 @@ public class AdvancementDataPlayer {
}
if (flag != flag1 && advancement.b() != null) {
- this.e(advancement.b());
+ // Paper start - If we're not coming from an iterator consider this to be a root entry, otherwise
+ // market that we're entering from the parent of an iterator.
+ this.e(advancement.b(), entryPoint == IterationEntryPoint.ITERATOR ? IterationEntryPoint.PARENT_OF_ITERATOR : IterationEntryPoint.ROOT);
}
+ // If this is true, we've went through a child iteration, entered the parent, processed the parent
+ // and are about to reprocess the children. Stop processing here to prevent O(N^2) processing.
+ if (entryPoint == IterationEntryPoint.PARENT_OF_ITERATOR) {
+ return;
+ } // Paper end
+
Iterator iterator = advancement.e().iterator();
while (iterator.hasNext()) {
Advancement advancement1 = (Advancement) iterator.next();
- this.e(advancement1);
+ this.e(advancement1, IterationEntryPoint.ITERATOR); // Paper - Mark this call as being from iteration
}
}

View file

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Wed, 15 Jul 2020 19:23:32 -0700
Subject: [PATCH] Move range check for block placing up
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 10e3bf60f13fbc8e26071bcfe8d19cbb635662a9..03cbe720c430f549eb6c2f594d5a599cf1e73226 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -1400,6 +1400,13 @@ public class PlayerConnection implements PacketListenerPlayIn {
MovingObjectPositionBlock movingobjectpositionblock = packetplayinuseitem.c();
BlockPosition blockposition = movingobjectpositionblock.getBlockPosition();
EnumDirection enumdirection = movingobjectpositionblock.getDirection();
+ // Paper start - move check up
+ Location eyeLoc = this.getPlayer().getEyeLocation();
+ double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ());
+ if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) {
+ return;
+ }
+ // Paper end - move check up
IBlockData clickedBlock = worldserver.getType(blockposition); // Spigot
this.player.resetIdleTimer();
@@ -1409,11 +1416,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
this.player.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent, ChatMessageType.GAME_INFO));
} else if (this.teleportPos == null && this.player.g((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && worldserver.a((EntityHuman) this.player, blockposition)) {
// CraftBukkit start - Check if we can actually do something over this large a distance
- Location eyeLoc = this.getPlayer().getEyeLocation();
- double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ());
- if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) {
- return;
- }
+ // Paper - move up
this.player.clearActiveItem(); // SPIGOT-4706
// CraftBukkit end
EnumInteractionResult enuminteractionresult = this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock);

View file

@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Mon, 13 Jul 2020 06:22:54 -0700
Subject: [PATCH] Fix AdvancementDataPlayer leak due from quitting early in
login
Move the criterion storage to the AdvancementDataPlayer object
itself, so the criterion object stores no references - and thus
needs no cleanup.
diff --git a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
index ac7b6734728f912ab9f02dc417f5924b3725adde..4d12edf4f3eca1e7d7ba22760baea6f7458c8e98 100644
--- a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
+++ b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
@@ -49,6 +49,10 @@ public class AdvancementDataPlayer {
private Advancement k;
private boolean l = true;
+ // Paper start - fix advancement data player leakage
+ final Map<CriterionTriggerAbstract, Set<CriterionTrigger.a>> criterionData = Maps.newIdentityHashMap();
+ // Paper end - fix advancement data player leakage
+
public AdvancementDataPlayer(MinecraftServer minecraftserver, File file, EntityPlayer entityplayer) {
this.d = minecraftserver;
this.e = file;
diff --git a/src/main/java/net/minecraft/server/CriterionTriggerAbstract.java b/src/main/java/net/minecraft/server/CriterionTriggerAbstract.java
index b6370436f87f187f36da56dcfc1c847a656c1b1f..514fe53e50104509b3be9c47fd181305c57bf03d 100644
--- a/src/main/java/net/minecraft/server/CriterionTriggerAbstract.java
+++ b/src/main/java/net/minecraft/server/CriterionTriggerAbstract.java
@@ -14,25 +14,25 @@ import java.util.function.Predicate;
public abstract class CriterionTriggerAbstract<T extends CriterionInstance> implements CriterionTrigger<T> {
- private final Map<AdvancementDataPlayer, Set<CriterionTrigger.a<T>>> a = Maps.newIdentityHashMap();
+ //private final Map<AdvancementDataPlayer, Set<CriterionTrigger.a<T>>> a = Maps.newIdentityHashMap(); // Paper - moved into AdvancementDataPlayer to fix memory leak
public CriterionTriggerAbstract() {}
@Override
public final void a(AdvancementDataPlayer advancementdataplayer, CriterionTrigger.a<T> criteriontrigger_a) {
- ((Set) this.a.computeIfAbsent(advancementdataplayer, (advancementdataplayer1) -> {
+ (advancementdataplayer.criterionData.computeIfAbsent(this, (advancementdataplayer1) -> { // Paper - fix AdvancementDataPlayer leak
return Sets.newHashSet();
})).add(criteriontrigger_a);
}
@Override
public final void b(AdvancementDataPlayer advancementdataplayer, CriterionTrigger.a<T> criteriontrigger_a) {
- Set<CriterionTrigger.a<T>> set = (Set) this.a.get(advancementdataplayer);
+ Set<CriterionTrigger.a<T>> set = (Set) advancementdataplayer.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
if (set != null) {
set.remove(criteriontrigger_a);
if (set.isEmpty()) {
- this.a.remove(advancementdataplayer);
+ advancementdataplayer.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
}
}
@@ -40,11 +40,11 @@ public abstract class CriterionTriggerAbstract<T extends CriterionInstance> impl
@Override
public final void a(AdvancementDataPlayer advancementdataplayer) {
- this.a.remove(advancementdataplayer);
+ advancementdataplayer.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
}
protected void a(AdvancementDataPlayer advancementdataplayer, Predicate<T> predicate) {
- Set<CriterionTrigger.a<T>> set = (Set) this.a.get(advancementdataplayer);
+ Set<CriterionTrigger.a<T>> set = (Set) advancementdataplayer.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
if (set != null) {
List<CriterionTrigger.a<T>> list = null;
@@ -54,7 +54,7 @@ public abstract class CriterionTriggerAbstract<T extends CriterionInstance> impl
while (iterator.hasNext()) {
criteriontrigger_a = (CriterionTrigger.a) iterator.next();
- if (predicate.test(criteriontrigger_a.a())) {
+ if (predicate.test((T) criteriontrigger_a.a())) { // Paper - decompile fix
if (list == null) {
list = Lists.newArrayList();
}
@@ -76,7 +76,7 @@ public abstract class CriterionTriggerAbstract<T extends CriterionInstance> impl
}
protected void b(AdvancementDataPlayer advancementdataplayer) {
- Set<CriterionTrigger.a<T>> set = (Set) this.a.get(advancementdataplayer);
+ Set<CriterionTrigger.a<T>> set = (Set) advancementdataplayer.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
if (set != null && !set.isEmpty()) {
UnmodifiableIterator unmodifiableiterator = ImmutableSet.copyOf(set).iterator();

View file

@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach@zachbr.io>
Date: Tue, 23 Jul 2019 20:44:47 -0500
Subject: [PATCH] Do not let the server load chunks from newer versions
If the server attempts to load a chunk generated by a newer version of
the game, immediately stop the server to prevent data corruption.
You can override this functionality at your own peril.
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index 1685237dfd7d6f352c5bab5f65817462de5e6d12..55a9b9cac2f882c5fe14eb7da2cbbfd532461bfb 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -50,9 +50,23 @@ public class ChunkRegionLoader {
return holder.protoChunk;
}
+ // Paper start
+ private static final int CURRENT_DATA_VERSION = SharedConstants.getGameVersion().getWorldVersion();
+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion");
+ // Paper end
+
public static InProgressChunkHolder loadChunk(WorldServer worldserver, DefinedStructureManager definedstructuremanager, VillagePlace villageplace, ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound, boolean distinguish) {
ArrayDeque<Runnable> tasksToExecuteOnMain = new ArrayDeque<>();
// Paper end
+ // Paper start - Do NOT attempt to load chunks saved with newer versions
+ if (nbttagcompound.hasKeyOfType("DataVersion", 99)) {
+ int dataVersion = nbttagcompound.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);
+ }
+ }
+ // Paper end
ChunkGenerator<?> chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level"); // Paper - diff on change, see ChunkRegionLoader#getChunkCoordinate

View file

@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Wed, 19 Aug 2020 05:05:54 +0100
Subject: [PATCH] Buffer joins to world
This patch buffers the number of logins which will attempt to join
the world per tick, this attempts to reduce the impact that join floods
has on the server
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 5d4783e357218694ac52ec0ab5c030470cc6595f..431aecdbc93d93b38813536ca5297acfc6c2a3b1 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -446,4 +446,9 @@ public class PaperConfig {
allowPistonDuplication = getBoolean("settings.unsupported-settings.allow-piston-duplication", config.getBoolean("settings.unsupported-settings.allow-tnt-duplication", false));
set("settings.unsupported-settings.allow-tnt-duplication", null);
}
+
+ public static int maxJoinsPerTick;
+ private static void maxJoinsPerTick() {
+ maxJoinsPerTick = getInt("settings.max-joins-per-tick", 3);
+ }
}
diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java
index ed63bf3648153ce9ecab75e960c612337cbcbfe8..c06b70fa490a3bf91ea20c8405178420d62e7df2 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -363,10 +363,22 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
}
// Paper end
+ private static final int MAX_PER_TICK = com.destroystokyo.paper.PaperConfig.maxJoinsPerTick; // Paper
+ private static int joinAttemptsThisTick; // Paper
+ private static int currTick; // Paper
public void a() {
this.o();
+ // Paper start
+ if (currTick != MinecraftServer.currentTick) {
+ currTick = MinecraftServer.currentTick;
+ joinAttemptsThisTick = 0;
+ }
+ // Paper end
if (this.packetListener instanceof LoginListener) {
+ if ( ((LoginListener) this.packetListener).getLoginState() != LoginListener.EnumProtocolState.READY_TO_ACCEPT // Paper
+ || (joinAttemptsThisTick++ < MAX_PER_TICK)) { // Paper - limit the number of joins which can be processed each tick
((LoginListener) this.packetListener).tick();
+ } // Paper
}
if (this.packetListener instanceof PlayerConnection) {

View file

@ -0,0 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: chickeneer <emcchickeneer@gmail.com>
Date: Wed, 18 Mar 2020 00:07:46 -0500
Subject: [PATCH] MC-147729: Drop items that are extra from a crafting recipe
diff --git a/src/main/java/net/minecraft/server/AutoRecipe.java b/src/main/java/net/minecraft/server/AutoRecipe.java
index dbc03cfc12ee8f8ff57668dc72be734056e5a996..a47a48cd067be4487c2e0683b6dfd2097498d9cc 100644
--- a/src/main/java/net/minecraft/server/AutoRecipe.java
+++ b/src/main/java/net/minecraft/server/AutoRecipe.java
@@ -60,7 +60,12 @@ public class AutoRecipe<C extends IInventory> implements AutoRecipeAbstract<Inte
if (j == -1) {
j = this.c.getFirstEmptySlotIndex();
}
-
+ // Paper start
+ if (j == -1) {
+ this.c.player.drop(itemstack.cloneItemStack(), false);
+ break;
+ }
+ // Paper end
ItemStack itemstack1 = itemstack.cloneItemStack();
itemstack1.setCount(1);

View file

@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: sulu5890 <sulu@sulu.me>
Date: Sat, 11 Dec 2021 12:42:57 -0600
Subject: [PATCH] Update Log4j
diff --git a/pom.xml b/pom.xml
index e4c63bb76cb598545f9d215a8859724d6e7f8b81..4d4e37c1ad973e5419924f61972b37980d2233ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,25 +63,25 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
- <version>2.8.1</version>
+ <version>2.17.0</version> <!-- Paper - Update Log4j -->
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
- <version>2.8.1</version>
+ <version>2.17.0</version> <!-- Paper - Update Log4j -->
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-iostreams</artifactId>
- <version>2.8.1</version>
+ <version>2.17.0</version> <!-- Paper - Update Log4j -->
</dependency>
<!-- Paper - Async loggers -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
- <version>3.4.2</version>
+ <version>3.4.4</version> <!-- Paper - Update Log4j -->
<scope>runtime</scope>
</dependency>
<dependency>
@@ -203,6 +203,7 @@
<Specification-Title>Bukkit</Specification-Title>
<Specification-Version>${api.version}</Specification-Version>
<Specification-Vendor>Bukkit Team</Specification-Vendor>
+ <Multi-Release>true</Multi-Release> <!-- Paper - update log4j -->
</manifestEntries>
<manifestSections>
<manifestSection>
@@ -230,7 +231,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
- <version>3.2.3</version>
+ <version>3.2.4</version> <!-- Paper - Update Log4j -->
<executions>
<execution>
<phase>package</phase>
@@ -242,7 +243,7 @@
<createSourcesJar>${shadeSourcesJar}</createSourcesJar>
<filters>
<filter>
- <artifact>org.spigotmc:minecraft-server</artifact>
+ <artifact>org.spigotmc:minecraft-server:**</artifact> <!-- Paper - update log4j -->
<excludes>
<exclude>com/google/common/**</exclude>
<exclude>com/google/gson/**</exclude>
@@ -254,7 +255,7 @@
<exclude>META-INF/MANIFEST.MF</exclude>
<exclude>com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository</exclude>
<exclude>com.mojang.datafixers.util.Either</exclude>
- <exclude>org.apache.logging.log4j/**</exclude>
+ <exclude>org/apache/logging/log4j/**</exclude> <!-- Paper - update log4j -->
</excludes>
</filter>
</filters>
@@ -307,16 +308,18 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/java.sql.Driver</resource>
</transformer>
- <transformer implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer" />
+ <transformer implementation="io.github.edwgiz.log4j.maven.plugins.shade.transformer.Log4j2PluginCacheFileTransformer" /> <!-- Paper - update log4j -->
</transformers>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
- <groupId>com.github.edwgiz</groupId>
- <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
- <version>2.13.1</version>
+ <!-- Paper start - update log4j -->
+ <groupId>io.github.edwgiz</groupId>
+ <artifactId>log4j-maven-shade-plugin-extensions</artifactId>
+ <version>2.17.0</version>
+ <!-- Paper end - update log4j -->
</dependency>
</dependencies>
</plugin>
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index 2ea6f5b7da35cbb342e72a00ea70fef667f05d49..da02663cb468449aed25b2d6ff2a416179c3088b 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -178,7 +178,7 @@ public class Main {
tryPreloadClass("org.apache.logging.log4j.core.async.DisruptorUtil");
tryPreloadClass("org.apache.logging.log4j.core.async.RingBufferLogEventHandler");
tryPreloadClass("org.apache.logging.log4j.core.impl.ThrowableProxy");
- tryPreloadClass("org.apache.logging.log4j.core.impl.ThrowableProxy$CacheEntry");
+ tryPreloadClass("org.apache.logging.log4j.core.impl.ThrowableProxyHelper$CacheEntry"); // Paper - Update Log4j -- https://github.com/apache/logging-log4j2/commit/de6593f5f3b5acbb2cdb4ee91e4e1f472db5dcbb
tryPreloadClass("org.apache.logging.log4j.core.impl.ExtendedClassInfo");
tryPreloadClass("org.apache.logging.log4j.core.impl.ExtendedStackTraceElement");
// Paper end

@ -1 +1 @@
Subproject commit ad5fe61d352beab2fb598070d9e25afb6b60397e
Subproject commit 2d4c7b3bbd322d8b7f3bbe2fe33ecf627251c828