mirror of
https://github.com/SparklyPower/SparklyPaper.git
synced 2025-12-21 07:59:31 +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
|
* 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.
|
* 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)...
|
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
|
version=1.20.2-R0.1-SNAPSHOT
|
||||||
|
|
||||||
mcVersion=1.20.2
|
mcVersion=1.20.2
|
||||||
paperRef=5bb30ce95b14293f5bfebf10be2fdf929eabcc01
|
paperRef=1865625d958b94d82e0bd601d6d860318980c4c4
|
||||||
|
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.parallel=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