mirror of
https://github.com/SparklyPower/SparklyPaper.git
synced 2025-12-19 15:09:27 +00:00
Let's start from scratch, shall we?
This commit is contained in:
@@ -12,7 +12,5 @@ While our fork is mostly cherry-picked patches from other forks, we do have some
|
||||
|
||||
* Configurable Farm Land moisture tick rate when the block is already moisturised
|
||||
* The isNearWater check is costly, especially if you have a lot of farm lands. If the block is already moistured, we can change the tick rate of it to avoid these expensive isNearWater checks.
|
||||
* Only check thundering once per world instead for every chunk
|
||||
* For some reason the isThundering check is consuming ~3% of CPU time when profiled so, instead of checking the thunder every chunk, we can cache the result and reuse on the same chunk tick.
|
||||
|
||||
We don't cherry-pick *everything* from other forks, only patches that I can see and think "yeah, I can see how this would improve performance" or patches that target specific performance/feature pain points in our server are cherry-picked! In fact, some patches that are used in other forks [may be actually borked](BORKED_PATCHES.md)...
|
||||
@@ -2,7 +2,7 @@ group=net.sparklypower.sparklypaper
|
||||
version=1.20.2-R0.1-SNAPSHOT
|
||||
|
||||
mcVersion=1.20.2
|
||||
paperRef=5bb30ce95b14293f5bfebf10be2fdf929eabcc01
|
||||
paperRef=1865625d958b94d82e0bd601d6d860318980c4c4
|
||||
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Sat, 13 Mar 2021 12:24:41 -0600
|
||||
Subject: [PATCH] Remove iterators from inventory contains
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
index 96d664c28738d6090f7067761c2978dd1aa0fd0e..b1c24a02b87aca7b180a6efbce177f2300db49c1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
@@ -687,6 +687,8 @@ public class Inventory implements Container, Nameable {
|
||||
}
|
||||
|
||||
public boolean contains(ItemStack stack) {
|
||||
+ // Pufferfish start - don't allocate iterators
|
||||
+ /*
|
||||
Iterator iterator = this.compartments.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -701,6 +703,18 @@ public class Inventory implements Container, Nameable {
|
||||
}
|
||||
}
|
||||
}
|
||||
+ */
|
||||
+ for (int i = 0; i < this.compartments.size(); i++) {
|
||||
+ List<ItemStack> list = this.compartments.get(i);
|
||||
+ for (int j = 0; j < list.size(); j++) {
|
||||
+ ItemStack itemstack1 = list.get(j);
|
||||
+
|
||||
+ if (!itemstack1.isEmpty() && ItemStack.isSameItemSameTags(itemstack1, stack)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Pufferfish end
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Tue, 22 Jun 2021 15:08:21 -0500
|
||||
Subject: [PATCH] Remove streams and iterators from range check
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 28c6ec04750daca3d77a0cee2b9f17f2508662cc..219393390fcef956b0694ff597436249901b3e17 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1330,8 +1330,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
return ChunkMap.this.level.getServer().getScaledTrackingDistance(initialDistance);
|
||||
}
|
||||
|
||||
+ private static int getHighestRange(Entity parent, int highest) {
|
||||
+ List<Entity> passengers = parent.getPassengers();
|
||||
+
|
||||
+ for (int i = 0, size = passengers.size(); i < size; i++) {
|
||||
+ Entity entity = passengers.get(i);
|
||||
+ int range = entity.getType().clientTrackingRange() * 16;
|
||||
+ range = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, range); // Paper
|
||||
+
|
||||
+ if (range > highest) { // Paper - we need the lowest range thanks to the fact that our tracker doesn't account for passenger logic // Tuinity - not anymore!
|
||||
+ highest = range;
|
||||
+ }
|
||||
+
|
||||
+ highest = getHighestRange(entity, highest);
|
||||
+ }
|
||||
+
|
||||
+ return highest;
|
||||
+ }
|
||||
+
|
||||
private int getEffectiveRange() {
|
||||
int i = this.range;
|
||||
+ // Pufferfish start - remove iterators and streams
|
||||
+ /*
|
||||
Iterator iterator = this.entity.getIndirectPassengers().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -1343,6 +1363,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
+ */
|
||||
+ i = getHighestRange(this.entity, i);
|
||||
+ // Pufferfish end
|
||||
|
||||
return this.scaledRange(i);
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Sat, 31 Oct 2020 18:51:38 -0500
|
||||
Subject: [PATCH] Simpler ShapelessRecipes comparison for Vanilla
|
||||
|
||||
Paper added a fancy sorting comparison due to Bukkit recipes breaking
|
||||
the vanilla one, however this is far more advanced than what you need
|
||||
for all the vanilla recipes.
|
||||
|
||||
Airplane
|
||||
Copyright (C) 2020 Technove LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
index 38f7d1ece27ec1a3deda21fb6a6f0e788c8ed718..252fc22844682c0f67dc02a87478e01e49b6430d 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
@@ -26,8 +26,13 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo
|
||||
final CraftingBookCategory category;
|
||||
final ItemStack result;
|
||||
final NonNullList<Ingredient> ingredients;
|
||||
+ private final boolean isBukkit; // Pufferfish
|
||||
|
||||
+ // Pufferfish start
|
||||
public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, NonNullList<Ingredient> ingredients) {
|
||||
+ this(group, category, result, ingredients, false);
|
||||
+ }
|
||||
+ public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, NonNullList<Ingredient> ingredients, boolean isBukkit) { this.isBukkit = isBukkit; // Pufferfish end
|
||||
this.group = group;
|
||||
this.category = category;
|
||||
this.result = result;
|
||||
@@ -77,6 +82,28 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo
|
||||
}
|
||||
|
||||
public boolean matches(CraftingContainer inventory, Level world) {
|
||||
+ // Pufferfish start
|
||||
+ if (!this.isBukkit) {
|
||||
+ java.util.List<Ingredient> ingredients = com.google.common.collect.Lists.newArrayList(this.ingredients.toArray(new Ingredient[0]));
|
||||
+
|
||||
+ inventory: for (int index = 0; index < inventory.getContainerSize(); index++) {
|
||||
+ ItemStack itemStack = inventory.getItem(index);
|
||||
+
|
||||
+ if (!itemStack.isEmpty()) {
|
||||
+ for (int i = 0; i < ingredients.size(); i++) {
|
||||
+ if (ingredients.get(i).test(itemStack)) {
|
||||
+ ingredients.remove(i);
|
||||
+ continue inventory;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ingredients.isEmpty();
|
||||
+ }
|
||||
+ // Pufferfish end
|
||||
+
|
||||
StackedContents autorecipestackmanager = new StackedContents();
|
||||
autorecipestackmanager.initialize(this); // Paper - better exact choice recipes
|
||||
int i = 0;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java
|
||||
index 96d772eb02f79f8c478f5e6f065e387aa7665b18..c5ce412f321b8b4f31cc042893659e213b081f29 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java
|
||||
@@ -45,6 +45,6 @@ public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe
|
||||
data.set(i, this.toNMS(ingred.get(i), true));
|
||||
}
|
||||
|
||||
- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.ShapelessRecipe(this.getGroup(), CraftRecipe.getCategory(this.getCategory()), CraftItemStack.asNMSCopy(this.getResult()), data)));
|
||||
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.ShapelessRecipe(this.getGroup(), CraftRecipe.getCategory(this.getCategory()), CraftItemStack.asNMSCopy(this.getResult()), data, true))); // Pufferfish
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Sun, 13 Dec 2020 17:53:08 -0600
|
||||
Subject: [PATCH] Only check for spooky season once an hour
|
||||
|
||||
Airplane
|
||||
Copyright (C) 2020 Technove LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
|
||||
index 5beaa849a250ea005733250ad3edfa8382224667..2c91fe46355c9a201507de5577f693ed4f5fb974 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
|
||||
@@ -237,13 +237,22 @@ public class Bat extends AmbientCreature {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Pufferfish start - only check for spooky season once an hour
|
||||
+ private static boolean isSpookySeason = false;
|
||||
+ private static final int ONE_HOUR = 20 * 60 * 60;
|
||||
+ private static int lastSpookyCheck = -ONE_HOUR;
|
||||
private static boolean isHalloween() {
|
||||
+ if (net.minecraft.server.MinecraftServer.currentTick - lastSpookyCheck > ONE_HOUR) {
|
||||
LocalDate localdate = LocalDate.now();
|
||||
int i = localdate.get(ChronoField.DAY_OF_MONTH);
|
||||
int j = localdate.get(ChronoField.MONTH_OF_YEAR);
|
||||
|
||||
- return j == 10 && i >= 20 || j == 11 && i <= 3;
|
||||
+ isSpookySeason = j == 10 && i >= 20 || j == 11 && i <= 3;
|
||||
+ lastSpookyCheck = net.minecraft.server.MinecraftServer.currentTick;
|
||||
+ }
|
||||
+ return isSpookySeason;
|
||||
}
|
||||
+ // Pufferfish end
|
||||
|
||||
@Override
|
||||
protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) {
|
||||
@@ -1,35 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Raneri <kevin.raneri@gmail.com>
|
||||
Date: Sun, 12 Jun 2022 22:19:37 -0500
|
||||
Subject: [PATCH] Move ThreadUnsafeRandom Initialization
|
||||
|
||||
ThreadUnsafeRandom is initialized too late and some of our patches
|
||||
require it to be initialized earlier. By moving it to the superclass, we
|
||||
initialize it earlier, ensuring that it is available sooner.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 17610196db7a1c6feb2cf74a02479a8691aa323f..715a622a11b295badb0821376fec721f9c6ecaed 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -962,7 +962,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
}
|
||||
// Paper start - optimise random block ticking
|
||||
private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos();
|
||||
- private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong());
|
||||
+ // private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(); // Pufferfish - moved to super
|
||||
// Paper end
|
||||
|
||||
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index aa9c56fb95d5e438e85aced984631493b84c8556..33b81d637bb5fe2a864f4313ad8796e42a5d2ad8 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -211,6 +211,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
|
||||
public abstract ResourceKey<LevelStem> getTypeKey();
|
||||
|
||||
+ protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); // Pufferfish - move thread unsafe random initialization
|
||||
+
|
||||
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
|
||||
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper
|
||||
@@ -1,40 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Tue, 22 Jun 2021 15:04:37 -0500
|
||||
Subject: [PATCH] Use thread unsafe random for mob spawning
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 33b81d637bb5fe2a864f4313ad8796e42a5d2ad8..e357223bcaa27a668e7e95cf54e183fed13920aa 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -211,7 +211,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
|
||||
public abstract ResourceKey<LevelStem> getTypeKey();
|
||||
|
||||
- protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); // Pufferfish - move thread unsafe random initialization
|
||||
+ protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); public net.minecraft.util.RandomSource getThreadUnsafeRandom() { return this.randomTickRandom; } // Pufferfish - move thread unsafe random initialization // Pufferfish - getter
|
||||
|
||||
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
|
||||
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
index 3cdddda9c0618e95288b81b975d499c8dd30c05f..9c2d62feff1816f5729060c6192269a5b2d34153 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -429,12 +429,12 @@ public final class NaturalSpawner {
|
||||
}
|
||||
}
|
||||
|
||||
- private static BlockPos getRandomPosWithin(Level world, LevelChunk chunk) {
|
||||
+ private static BlockPos getRandomPosWithin(ServerLevel world, LevelChunk chunk) { // Pufferfish - accept serverlevel
|
||||
ChunkPos chunkcoordintpair = chunk.getPos();
|
||||
- int i = chunkcoordintpair.getMinBlockX() + world.random.nextInt(16);
|
||||
- int j = chunkcoordintpair.getMinBlockZ() + world.random.nextInt(16);
|
||||
+ int i = chunkcoordintpair.getMinBlockX() + world.getThreadUnsafeRandom().nextInt(16); // Pufferfish - use thread unsafe random
|
||||
+ int j = chunkcoordintpair.getMinBlockZ() + world.getThreadUnsafeRandom().nextInt(16); // Pufferfish
|
||||
int k = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, i, j) + 1;
|
||||
- int l = Mth.randomBetweenInclusive(world.random, world.getMinBuildHeight(), k);
|
||||
+ int l = Mth.randomBetweenInclusive(world.getThreadUnsafeRandom(), world.getMinBuildHeight(), k); // Pufferfish
|
||||
|
||||
return new BlockPos(i, l, j);
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Thu, 7 Jan 2021 11:49:36 -0600
|
||||
Subject: [PATCH] Optimize random calls in chunk ticking
|
||||
|
||||
Especially at over 30,000 chunks these random calls are fairly heavy. We
|
||||
use a different method here for checking lightning, and for checking
|
||||
ice.
|
||||
|
||||
Lightning: Each chunk now keeps an int of how many ticks until the
|
||||
lightning should strike. This int is a random number from 0 to 100000 * 2,
|
||||
the multiplication is required to keep the probability the same.
|
||||
|
||||
Ice and snow: We just generate a single random number 0-16 and increment
|
||||
it, while checking if it's 0 for the current chunk.
|
||||
|
||||
Depending on configuration for things that tick in a chunk, this is a
|
||||
5-10% improvement.
|
||||
|
||||
Airplane
|
||||
Copyright (C) 2020 Technove LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..b384a9ed3f072d2fbf08d2fd8d8ef9a18fdf1e3e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -521,6 +521,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
|
||||
|
||||
gameprofilerfiller.push("pollingChunks");
|
||||
+ this.level.resetIceAndSnowTick(); // Pufferfish - reset ice & snow tick random
|
||||
int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING);
|
||||
boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 1c73235e071cfd713972a2485c8dbaf995f0512f..93b6e92e490025f8ef3c154e7534bf6c278eae2a 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -965,6 +965,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(); // Pufferfish - moved to super
|
||||
// Paper end
|
||||
|
||||
+ private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.randomTickRandom.nextInt(16); } // Pufferfish
|
||||
+
|
||||
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
|
||||
ChunkPos chunkcoordintpair = chunk.getPos();
|
||||
boolean flag = this.isRaining();
|
||||
@@ -975,7 +977,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
gameprofilerfiller.push("thunder");
|
||||
final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change
|
||||
|
||||
- if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder
|
||||
+ if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && /*this.random.nextInt(this.spigotConfig.thunderChance) == 0 &&*/ chunk.shouldDoLightning(this.random)) { // Spigot // Paper - disable thunder // Pufferfish - replace random with shouldDoLightning
|
||||
blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
|
||||
|
||||
if (this.isRainingAt(blockposition)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index fa170cc1ce7011d201295b89718292d696c7fc24..7fd68d4aba72b15b2e21e5c88b44e677b794fe57 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -86,6 +86,18 @@ public class LevelChunk extends ChunkAccess {
|
||||
private final LevelChunkTicks<Fluid> fluidTicks;
|
||||
public volatile FullChunkStatus chunkStatus = FullChunkStatus.INACCESSIBLE; // Paper - rewrite chunk system
|
||||
|
||||
+ // Pufferfish start - instead of using a random every time the chunk is ticked, define when lightning strikes preemptively
|
||||
+ private int lightningTick;
|
||||
+ // shouldDoLightning compiles down to 29 bytes, which with the default of 35 byte inlining should guarantee an inline
|
||||
+ public final boolean shouldDoLightning(net.minecraft.util.RandomSource random) {
|
||||
+ if (this.lightningTick-- <= 0) {
|
||||
+ this.lightningTick = random.nextInt(this.level.spigotConfig.thunderChance) << 1;
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Pufferfish end
|
||||
+
|
||||
public LevelChunk(Level world, ChunkPos pos) {
|
||||
this(world, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, (LevelChunkSection[]) null, (LevelChunk.PostLoadProcessor) null, (BlendingData) null);
|
||||
}
|
||||
@@ -109,6 +121,8 @@ public class LevelChunk extends ChunkAccess {
|
||||
this.postLoad = entityLoader;
|
||||
this.blockTicks = blockTickScheduler;
|
||||
this.fluidTicks = fluidTickScheduler;
|
||||
+
|
||||
+ this.lightningTick = this.level.getThreadUnsafeRandom().nextInt(100000) << 1; // Pufferfish - initialize lightning tick
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
@@ -1,45 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Thu, 4 Feb 2021 23:33:52 -0600
|
||||
Subject: [PATCH] Reduce chunk loading & lookups
|
||||
|
||||
Airplane
|
||||
Copyright (C) 2020 Technove LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index b0a97679157a18a3c623ce3b2ae315789772c254..9fc3db543a0c9df502df5fb85012c6aa590e887d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -333,11 +333,17 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
private boolean teleport(double x, double y, double z) {
|
||||
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(x, y, z);
|
||||
|
||||
- while (blockposition_mutableblockposition.getY() > this.level().getMinBuildHeight() && !this.level().getBlockState(blockposition_mutableblockposition).blocksMotion()) {
|
||||
+ // Pufferfish start - single chunk lookup
|
||||
+ net.minecraft.world.level.chunk.LevelChunk chunk = this.level().getChunkIfLoaded(blockposition_mutableblockposition);
|
||||
+ if (chunk == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Pufferfish end
|
||||
+ while (blockposition_mutableblockposition.getY() > this.level().getMinBuildHeight() && !chunk.getBlockState(blockposition_mutableblockposition).blocksMotion()) { // Pufferfish
|
||||
blockposition_mutableblockposition.move(Direction.DOWN);
|
||||
}
|
||||
|
||||
- BlockState iblockdata = this.level().getBlockState(blockposition_mutableblockposition);
|
||||
+ BlockState iblockdata = chunk.getBlockState(blockposition_mutableblockposition); // Pufferfish
|
||||
boolean flag = iblockdata.blocksMotion();
|
||||
boolean flag1 = iblockdata.getFluidState().is(FluidTags.WATER);
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Sat, 13 Mar 2021 15:05:28 -0600
|
||||
Subject: [PATCH] Early return optimization for target finding
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
|
||||
index c157309ac78e7af084d3acb6e8b2bcd469a39d5e..ac5e5676b194a2a99e5cf53eb89c1152cac963b8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
|
||||
@@ -75,9 +75,18 @@ public class TargetingConditions {
|
||||
}
|
||||
|
||||
if (this.range > 0.0D) {
|
||||
- double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D;
|
||||
- double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0D); // Paper
|
||||
+ // Pufferfish start - check range before getting visibility
|
||||
+ // d = invisibility percent, e = follow range adjusted for invisibility, f = distance
|
||||
double f = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ());
|
||||
+ double followRangeRaw = this.useFollowRange ? this.getFollowRange(baseEntity) : this.range;
|
||||
+
|
||||
+ if (f > followRangeRaw * followRangeRaw) { // the actual follow range will always be this value or smaller, so if the distance is larger then it never will return true after getting invis
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D;
|
||||
+ double e = Math.max((followRangeRaw) * d, 2.0D); // Paper
|
||||
+ // Pufferfish end
|
||||
if (f > e * e) {
|
||||
return false;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Raneri <kevin.raneri@gmail.com>
|
||||
Date: Tue, 9 Nov 2021 14:33:16 -0500
|
||||
Subject: [PATCH] Optimize entity coordinate key
|
||||
|
||||
When executing getCoordinateKey for entities (a hotpath), the JVM is
|
||||
required to repeatedly cast doubles to longs. The performance impact of
|
||||
this depends on the CPU architecture, but generally switching between
|
||||
FPU and ALU incurs a significant performance hit. The casted/rounded
|
||||
data is already available in the blockPosition struct, so we use that
|
||||
instead of re-doing the casting.
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
index d02546b18cb689724887b4e85e8d32a18828a4ad..91eaff58bb422ba188e6cfaa9c20b45bec211edd 100644
|
||||
--- a/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
@@ -213,7 +213,7 @@ public final class MCUtil {
|
||||
}
|
||||
|
||||
public static long getCoordinateKey(final Entity entity) {
|
||||
- return ((long)(MCUtil.fastFloor(entity.getZ()) >> 4) << 32) | ((MCUtil.fastFloor(entity.getX()) >> 4) & 0xFFFFFFFFL);
|
||||
+ return ((long)(entity.blockPosition.getZ() >> 4) << 32) | ((entity.blockPosition.getX() >> 4) & 0xFFFFFFFFL); // Pufferfish - eliminate double->long cast in hotpath
|
||||
}
|
||||
|
||||
public static long getCoordinateKey(final ChunkPos pair) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index f20ae9153b7098980ce6c0e75fcbbb4da652661b..4b551df667bb1aeca7ba78a063f7f0e0f1e11c5e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -305,7 +305,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
public double yo;
|
||||
public double zo;
|
||||
private Vec3 position;
|
||||
- private BlockPos blockPosition;
|
||||
+ public BlockPos blockPosition; // Pufferfish - private->public
|
||||
private ChunkPos chunkPosition;
|
||||
private Vec3 deltaMovement;
|
||||
private float yRot;
|
||||
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul <paul@technove.co>
|
||||
Date: Fri, 2 Jul 2021 18:27:12 -0500
|
||||
Subject: [PATCH] Remove lambda from ticking guard
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 2192db61ced4434c2c643599b5d2dcc11fcfb45c..008a4cd92932024af8ced4e33100570d2ded3552 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -897,7 +897,20 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
}
|
||||
|
||||
gameprofilerfiller.push("tick");
|
||||
- this.guardEntityTick(this::tickNonPassenger, entity);
|
||||
+ // Pufferfish start - copied from this.guardEntityTick
|
||||
+ try {
|
||||
+ this.tickNonPassenger(entity); // Pufferfish - changed
|
||||
+ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick
|
||||
+ } catch (Throwable throwable) {
|
||||
+ if (throwable instanceof ThreadDeath) throw throwable; // Paper
|
||||
+ // Paper start - Prevent tile entity and entity crashes
|
||||
+ final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
|
||||
+ MinecraftServer.LOGGER.error(msg, throwable);
|
||||
+ getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable)));
|
||||
+ entity.discard();
|
||||
+ // Paper end
|
||||
+ }
|
||||
+ // Pufferfish end
|
||||
gameprofilerfiller.pop();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index e357223bcaa27a668e7e95cf54e183fed13920aa..9388dd9b34bb8148ce8b5f7e24122fa4bd1bafa8 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -1312,13 +1312,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
try {
|
||||
tickConsumer.accept(entity);
|
||||
MinecraftServer.getServer().executeMidTickTasks(); // Paper - execute chunk tasks mid tick
|
||||
- } catch (Throwable throwable) {
|
||||
+ } catch (Throwable throwable) { // Pufferfish - diff on change ServerLevel.tick
|
||||
if (throwable instanceof ThreadDeath) throw throwable; // Paper
|
||||
// Paper start - Prevent tile entity and entity crashes
|
||||
final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
|
||||
MinecraftServer.LOGGER.error(msg, throwable);
|
||||
getCraftServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable)));
|
||||
- entity.discard();
|
||||
+ entity.discard(); // Pufferfish - diff on change ServerLevel.tick
|
||||
// Paper end
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul <paul@technove.co>
|
||||
Date: Fri, 2 Jul 2021 18:25:18 -0500
|
||||
Subject: [PATCH] Reduce entity allocations
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
index 7204b973c3ad9239e82355513f6d538107102e48..3087f8359b098682a345399c85395de8a15b6eed 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
@@ -23,9 +23,11 @@ public class AttributeMap {
|
||||
private final Map<Attribute, AttributeInstance> attributes = Maps.newHashMap();
|
||||
private final Set<AttributeInstance> dirtyAttributes = Sets.newHashSet();
|
||||
private final AttributeSupplier supplier;
|
||||
+ private final java.util.function.Function<Attribute, AttributeInstance> createInstance; // Pufferfish
|
||||
|
||||
public AttributeMap(AttributeSupplier defaultAttributes) {
|
||||
this.supplier = defaultAttributes;
|
||||
+ this.createInstance = attribute -> this.supplier.createInstance(this::onAttributeModified, attribute); // Pufferfish
|
||||
}
|
||||
|
||||
private void onAttributeModified(AttributeInstance instance) {
|
||||
@@ -45,11 +47,10 @@ public class AttributeMap {
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
+
|
||||
@Nullable
|
||||
public AttributeInstance getInstance(Attribute attribute) {
|
||||
- return this.attributes.computeIfAbsent(attribute, (attributex) -> {
|
||||
- return this.supplier.createInstance(this::onAttributeModified, attributex);
|
||||
- });
|
||||
+ return this.attributes.computeIfAbsent(attribute, this.createInstance); // Pufferfish - cache lambda, as for some reason java allocates it anyways
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Reference in New Issue
Block a user