910 lines
52 KiB
Diff
910 lines
52 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: AlphaKR93 <dev@alpha93.kr>
|
|
Date: Thu, 25 Jan 2024 17:13:09 +0900
|
|
Subject: [PATCH] Port SparklyPaper patches
|
|
|
|
SparklyPower
|
|
Copyright (C) 2024 SparklyPower
|
|
|
|
Based on commit: 29212936a832106c4d68e2a2017acbea2fdd3cc4
|
|
|
|
diff --git a/src/main/java/io/papermc/paper/command/MSPTCommand.java b/src/main/java/io/papermc/paper/command/MSPTCommand.java
|
|
index 8b5293b0c696ef21d0101493ffa41b60bf0bc86b..03be23690a94a14d7343526acad67ccf53b85c70 100644
|
|
--- a/src/main/java/io/papermc/paper/command/MSPTCommand.java
|
|
+++ b/src/main/java/io/papermc/paper/command/MSPTCommand.java
|
|
@@ -78,6 +78,47 @@ public final class MSPTCommand extends Command {
|
|
)
|
|
)
|
|
);
|
|
+
|
|
+ // Plazma start - Port SparklyPaper patches; Track World specific MSPT
|
|
+ sender.sendMessage(text());
|
|
+ sender.sendMessage(text().content("World tick times ").color(GOLD)
|
|
+ .append(text().color(YELLOW)
|
|
+ .append(
|
|
+ text("("),
|
|
+ text("avg", GRAY),
|
|
+ text("/"),
|
|
+ text("min", GRAY),
|
|
+ text("/"),
|
|
+ text("max", GRAY),
|
|
+ text(")")
|
|
+ )
|
|
+ ).append(
|
|
+ text(" from last 5s"),
|
|
+ text(",", GRAY),
|
|
+ text(" 10s"),
|
|
+ text(",", GRAY),
|
|
+ text(" 1m"),
|
|
+ text(":", YELLOW)
|
|
+ )
|
|
+ );
|
|
+ for (net.minecraft.server.level.ServerLevel level: server.getAllLevels()) {
|
|
+ List<Component> worldTimes = new ArrayList<>();
|
|
+ worldTimes.addAll(eval(level.tickTimes5s.getTimes()));
|
|
+ worldTimes.addAll(eval(level.tickTimes10s.getTimes()));
|
|
+ worldTimes.addAll(eval(level.tickTimes60s.getTimes()));
|
|
+
|
|
+ sender.sendMessage(text().content("◴ " + level.getWorld().getName() + ": ").color(GOLD)
|
|
+ .append(text().color(GRAY)
|
|
+ .append(
|
|
+ worldTimes.get(0), SLASH, worldTimes.get(1), SLASH, worldTimes.get(2), text(", ", YELLOW),
|
|
+ worldTimes.get(3), SLASH, worldTimes.get(4), SLASH, worldTimes.get(5), text(", ", YELLOW),
|
|
+ worldTimes.get(6), SLASH, worldTimes.get(7), SLASH, worldTimes.get(8)
|
|
+ )
|
|
+ )
|
|
+ );
|
|
+ }
|
|
+ // Plazma end - Port SparklyPaper patches; Track World specific MSPT
|
|
+
|
|
return true;
|
|
}
|
|
|
|
diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
|
|
index c03608fec96b51e1867f43d8f42e5aefb1520e46..93180066224345c0332fb33744f84204f15bba29 100644
|
|
--- a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
|
|
+++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
|
|
@@ -41,6 +41,7 @@ public final class EntityScheduler {
|
|
|
|
private long tickCount = 0L;
|
|
private static final long RETIRED_TICK_COUNT = -1L;
|
|
+ private static final net.minecraft.server.MinecraftServer SERVER = net.minecraft.server.MinecraftServer.getServer(); // Plazma - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
private final Object stateLock = new Object();
|
|
private final Long2ObjectOpenHashMap<List<ScheduledTask>> oneTimeDelayed = new Long2ObjectOpenHashMap<>();
|
|
|
|
@@ -61,15 +62,15 @@ public final class EntityScheduler {
|
|
* @throws IllegalStateException If the scheduler is already retired.
|
|
*/
|
|
public void retire() {
|
|
+ final Entity thisEntity = this.entity.getHandleRaw(); // Plazma - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
synchronized (this.stateLock) {
|
|
if (this.tickCount == RETIRED_TICK_COUNT) {
|
|
throw new IllegalStateException("Already retired");
|
|
}
|
|
this.tickCount = RETIRED_TICK_COUNT;
|
|
+ SERVER.entitiesWithScheduledTasks.remove(thisEntity); // Plazma - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
}
|
|
|
|
- final Entity thisEntity = this.entity.getHandleRaw();
|
|
-
|
|
// correctly handle and order retiring while running executeTick
|
|
for (int i = 0, len = this.currentlyExecuting.size(); i < len; ++i) {
|
|
final ScheduledTask task = this.currentlyExecuting.pollFirst();
|
|
@@ -124,6 +125,7 @@ public final class EntityScheduler {
|
|
if (this.tickCount == RETIRED_TICK_COUNT) {
|
|
return false;
|
|
}
|
|
+ SERVER.entitiesWithScheduledTasks.add(this.entity.getHandleRaw()); // Plazma - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
this.oneTimeDelayed.computeIfAbsent(this.tickCount + Math.max(1L, delay), (final long keyInMap) -> {
|
|
return new ArrayList<>();
|
|
}).add(task);
|
|
@@ -143,6 +145,12 @@ public final class EntityScheduler {
|
|
TickThread.ensureTickThread(thisEntity, "May not tick entity scheduler asynchronously");
|
|
final List<ScheduledTask> toRun;
|
|
synchronized (this.stateLock) {
|
|
+ // Plazma start - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
+ if (this.currentlyExecuting.isEmpty() && this.oneTimeDelayed.isEmpty()) {
|
|
+ SERVER.entitiesWithScheduledTasks.remove(thisEntity);
|
|
+ return;
|
|
+ }
|
|
+ // Plazma end - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
if (this.tickCount == RETIRED_TICK_COUNT) {
|
|
throw new IllegalStateException("Ticking retired scheduler");
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 94eb4e0686d8235f06ea7950c178cdec8bd6e037..118832d94f96d7624f9faee35b9da0aeb9d9ded8 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -327,6 +327,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
public volatile boolean abnormalExit = false; // Paper
|
|
public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
|
|
public gg.pufferfish.pufferfish.util.AsyncExecutor mobSpawnExecutor = new gg.pufferfish.pufferfish.util.AsyncExecutor("MobSpawning"); // Pufferfish - optimize mob spawning
|
|
+ public final Set<Entity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // Plazma - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
|
|
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
|
|
AtomicReference<S> atomicreference = new AtomicReference();
|
|
@@ -1776,17 +1777,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
//MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper // Purpur
|
|
// Paper start - Folia scheduler API
|
|
((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).tick();
|
|
- getAllLevels().forEach(level -> {
|
|
- for (final Entity entity : level.moonrise$getEntityLookup().getAllCopy()) { // Paper - rewrite chunk system
|
|
- if (entity.isRemoved()) {
|
|
- continue;
|
|
- }
|
|
- final org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw();
|
|
- if (bukkit != null) {
|
|
- bukkit.taskScheduler.executeTick();
|
|
- }
|
|
- }
|
|
- });
|
|
+ // Plazma start - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
+ for (final Entity entity : entitiesWithScheduledTasks) {
|
|
+ if (entity.isRemoved() || entity.getBukkitEntityRaw() == null) continue;
|
|
+ entity.getBukkitEntityRaw().taskScheduler.executeTick();
|
|
+ }
|
|
+ // Plazma end - Port SparklyPaper patches; Skip EntityScheduler's executeTick checks if there isn't any tasks to be run
|
|
// Paper end - Folia scheduler API
|
|
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper
|
|
//this.profiler.push("commandFunctions"); // Purpur
|
|
@@ -1852,8 +1848,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
//this.profiler.push("tick"); // Purpur
|
|
|
|
try {
|
|
- //worldserver.timings.doTick.startTiming(); // Spigot // Purpur
|
|
- worldserver.tick(shouldKeepTicking);
|
|
+ //worldserver.timings.doTick.startTiming(); // Spigot // Purpur// Plazma start - Port SparklyPaper patches; Track World specific MSPT
|
|
+ long before = Util.getNanos();
|
|
+ worldserver.tick(shouldKeepTicking); // diff on changes
|
|
+ long after = Util.getNanos() - before;
|
|
+
|
|
+ worldserver.tickTimes5s.add(this.tickCount, after);
|
|
+ worldserver.tickTimes10s.add(this.tickCount, after);
|
|
+ worldserver.tickTimes60s.add(this.tickCount, after);
|
|
+ // Plazma end - Port SparklyPaper patches; Track World specific MSPT
|
|
//worldserver.timings.doTick.stopTiming(); // Spigot // Purpur
|
|
} catch (Throwable throwable) {
|
|
CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
|
|
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
index 97df4706150dd198dc9bbdd3bdcecea9094d3b62..d31fabbca11b1f619bfa62487eed2cd5f19844ce 100644
|
|
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
@@ -227,6 +227,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
|
this.plazmaConfigurations.initializeGlobalConfiguration(this.registryAccess()); // Plazma - Configurable Plazma
|
|
this.plazmaConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); // Plazma - Configurable Plazma
|
|
+ net.sparklypower.sparklypaper.HalloweenManager.startSyncEpochTask(); // Plazma - Port SparklyPaper patches; Optimize Spooky Season
|
|
// Paper end - initialize global and world-defaults configuration
|
|
// Paper start - detect running as root // Plazma - Tweak console logging (moved down)
|
|
if (io.papermc.paper.util.ServerEnvironment.userIsRootOrAdmin()) {
|
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
index 1883abec14e05f8eb2e865446b4d81091b1aa5e0..adfc891ae8868bb562910ad169c116e5d30348c7 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
@@ -1262,7 +1262,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
// Paper end - Configurable entity tracking range by Y
|
|
|
|
// CraftBukkit start - respect vanish API
|
|
- if (flag && !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - only consider hits
|
|
+ if (flag && !player.getBukkitEntity().chunkMapCanSee(this.entity.getBukkitEntity())) { // Paper - only consider hits // Plazma - Port SparklyPaper patches; Optimize canSee check
|
|
flag = false;
|
|
}
|
|
// CraftBukkit end
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
index dfd09004063a8d8d93357633c8d23b6acff67b73..7458cd657e809bba7483da31ddeb8f77aab1203d 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
@@ -78,6 +78,7 @@ public class ServerEntity {
|
|
private List<SynchedEntityData.DataValue<?>> trackedDataValues;
|
|
// CraftBukkit start
|
|
public final Set<ServerPlayerConnection> trackedPlayers; // Purpur - private -> public
|
|
+ public static boolean skipSqrWhenNoDeltaChanges = false; // Plazma - SparklyPaper port; Skip distanceToSqr if the delta movement hasn't changed
|
|
|
|
public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer<Packet<?>> consumer, Set<ServerPlayerConnection> trackedPlayers) {
|
|
this.trackedPlayers = trackedPlayers;
|
|
@@ -218,20 +219,21 @@ public class ServerEntity {
|
|
|
|
if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) {
|
|
Vec3 vec3d1 = this.entity.getDeltaMovement();
|
|
- double d0 = vec3d1.distanceToSqr(this.lastSentMovement);
|
|
-
|
|
- if (d0 > 1.0E-7D || d0 > 0.0D && vec3d1.lengthSqr() == 0.0D) {
|
|
- this.lastSentMovement = vec3d1;
|
|
- Entity entity1 = this.entity;
|
|
-
|
|
- if (entity1 instanceof AbstractHurtingProjectile) {
|
|
- AbstractHurtingProjectile entityfireball = (AbstractHurtingProjectile) entity1;
|
|
-
|
|
- this.broadcast.accept(new ClientboundBundlePacket(List.of(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement), new ClientboundProjectilePowerPacket(entityfireball.getId(), entityfireball.accelerationPower))));
|
|
- } else {
|
|
- this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement));
|
|
- }
|
|
- }
|
|
+ // Plazma start - SparklyPaper port; Skip distanceToSqr if the delta movement hasn't changed
|
|
+ if (!skipSqrWhenNoDeltaChanges && vec3d1 != this.lastSentMovement) {
|
|
+ double d0 = vec3d1.distanceToSqr(this.lastSentMovement);
|
|
+ if (d0 > 1.0E-7D || d0 > 0.0D && vec3d1.lengthSqr() == 0.0D) {
|
|
+ this.lastSentMovement = vec3d1;
|
|
+ Entity entity1 = this.entity;
|
|
+ if (entity1 instanceof AbstractHurtingProjectile) {
|
|
+ AbstractHurtingProjectile entityfireball = (AbstractHurtingProjectile) entity1;
|
|
+ this.broadcast.accept(new ClientboundBundlePacket(List.of(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement), new ClientboundProjectilePowerPacket(entityfireball.getId(), entityfireball.accelerationPower))));
|
|
+ } else {
|
|
+ this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement));
|
|
+ }
|
|
+ } // diff on changes
|
|
+ } // diff on changes
|
|
+ // Plazma end - SparklyPaper port; Skip distanceToSqr if the delta movement hasn't changed
|
|
}
|
|
|
|
if (packet1 != null) {
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
index dfcd3989ffbd4aa5dc9368a34b95c1c2748c23a2..f5f944899d860d8363db43d430f3daab96e0d774 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
@@ -233,6 +233,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
|
|
private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current)
|
|
public boolean hasRidableMoveEvent = false; // Purpur
|
|
|
|
+ // Plazma start - Port SparklyPaper patches; Track World specific MSPT
|
|
+ public final MinecraftServer.TickTimes tickTimes5s = new MinecraftServer.TickTimes(100);
|
|
+ public final MinecraftServer.TickTimes tickTimes10s = new MinecraftServer.TickTimes(200);
|
|
+ public final MinecraftServer.TickTimes tickTimes60s = new MinecraftServer.TickTimes(1200);
|
|
+ // Plazma end - Port SparklyPaper patches; Track World specific MSPT
|
|
+
|
|
public LevelChunk getChunkIfLoaded(int x, int z) {
|
|
return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/stats/ServerStatsCounter.java b/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
|
index fb7342f7a5008a283c3400c6313c637de8210dfa..8b068f6b4c52cdba60a7fbe21bc1f7a86891800a 100644
|
|
--- a/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
|
+++ b/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
|
@@ -90,12 +90,14 @@ public class ServerStatsCounter extends StatsCounter {
|
|
this.dirty.add(stat);
|
|
}
|
|
|
|
+ /* // Plazma - Port SparklyPaper patches; Skip dirty stats copy when requesting player stats
|
|
private Set<Stat<?>> getDirty() {
|
|
Set<Stat<?>> set = Sets.newHashSet(this.dirty);
|
|
|
|
this.dirty.clear();
|
|
return set;
|
|
}
|
|
+ */ // Plazma - Port SparklyPaper patches; Skip dirty stats copy when requesting player stats
|
|
|
|
public void parseLocal(DataFixer dataFixer, String json) {
|
|
try {
|
|
@@ -243,7 +245,7 @@ public class ServerStatsCounter extends StatsCounter {
|
|
|
|
public void sendStats(ServerPlayer player) {
|
|
Object2IntMap<Stat<?>> object2intmap = new Object2IntOpenHashMap();
|
|
- Iterator iterator = this.getDirty().iterator();
|
|
+ Iterator<Stat<?>> iterator = this.dirty.iterator(); // Plazma - SparklyPaper port; Skip dirty stats copy when requesting player stats
|
|
|
|
while (iterator.hasNext()) {
|
|
Stat<?> statistic = (Stat) iterator.next();
|
|
@@ -251,6 +253,7 @@ public class ServerStatsCounter extends StatsCounter {
|
|
object2intmap.put(statistic, this.getValue(statistic));
|
|
}
|
|
|
|
+ this.dirty.clear(); // Plazma - SparklyPaper port; Skip dirty stats copy when requesting player stats
|
|
player.connection.send(new ClientboundAwardStatsPacket(object2intmap));
|
|
}
|
|
}
|
|
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 36e5a6462675ceb3cef236c451321b1656d9fcc0..bdc2391aed4fedc2e15a0b51a6930a2d85905c90 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
|
|
@@ -307,7 +307,7 @@ public class Bat extends AmbientCreature {
|
|
int i = world.getMaxLocalRawBrightness(pos);
|
|
byte b0 = 4;
|
|
|
|
- if (Bat.isHalloweenSeason(world.getMinecraftWorld())) { // Purpur
|
|
+ if (isSpookySeason(world.getMinecraftWorld())) { // Purpur // Plazma - Port SparklyPaper patches; Optimize Spooky Season
|
|
b0 = 7;
|
|
} else if (random.nextBoolean()) {
|
|
return false;
|
|
@@ -321,7 +321,24 @@ public class Bat extends AmbientCreature {
|
|
private static boolean isSpookySeason = false;
|
|
private static final int ONE_HOUR = 20 * 60 * 60;
|
|
private static int lastSpookyCheck = -ONE_HOUR;
|
|
- public static boolean isHalloweenSeason(Level level) { return level.purpurConfig.forceHalloweenSeason || isHalloween(); } // Purpur
|
|
+ // Plazma start - Port SparklyPaper patches; Optimize Spooky Season
|
|
+ private static boolean isSpookySeason(Level level) {
|
|
+ if (level.purpurConfig.forceHalloweenSeason) return true;
|
|
+ if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().entity.spookyOptimize)
|
|
+ return net.sparklypower.sparklypaper.HalloweenManager.isSpookySeason()
|
|
+ || net.sparklypower.sparklypaper.HalloweenManager.isHalloween();
|
|
+ return isHalloween();
|
|
+ }
|
|
+
|
|
+ public static boolean isHalloweenSeason(Level level) {
|
|
+ if (level.purpurConfig.forceHalloweenSeason) return true;
|
|
+ if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().entity.spookyOptimize)
|
|
+ return net.sparklypower.sparklypaper.HalloweenManager.isHalloween();
|
|
+ return isHalloween();
|
|
+ }
|
|
+
|
|
+ @SuppressWarnings("RedundantExplicitChronoField")
|
|
+ // Plazma end - Port SparklyPaper patches; Optimize Spooky Season
|
|
private static boolean isHalloween() {
|
|
if (net.minecraft.server.MinecraftServer.currentTick - lastSpookyCheck > ONE_HOUR) {
|
|
LocalDate localdate = LocalDate.now();
|
|
diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java
|
|
index 608390ed36710a419de1542b80340dd3fcc7299c..043f068345ca3c50209c1c3cc1feb6277a3da61a 100644
|
|
--- a/src/main/java/net/minecraft/world/item/MapItem.java
|
|
+++ b/src/main/java/net/minecraft/world/item/MapItem.java
|
|
@@ -268,11 +268,13 @@ public class MapItem extends ComplexItem {
|
|
}
|
|
}
|
|
|
|
+ public static boolean skipTickWhenCraftNotPresent = false; // Plazma - SparklyPaper port; Skip map item ticking if the craft map renderer is not present
|
|
@Override
|
|
public void inventoryTick(ItemStack stack, Level world, Entity entity, int slot, boolean selected) {
|
|
if (!world.isClientSide) {
|
|
MapItemSavedData mapItemSavedData = getSavedData(stack, world);
|
|
if (mapItemSavedData != null) {
|
|
+ if (skipTickWhenCraftNotPresent && mapItemSavedData.mapView.getRenderers().stream().noneMatch(mapRenderer -> mapRenderer.getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class)) return; // Plazma - SparklyPaper port; Skip map item ticking if the craft map renderer is not present
|
|
if (entity instanceof Player player) {
|
|
mapItemSavedData.tickCarriedBy(player, stack);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index 253d47418b4e9cbce74584c2461d12e17effd7bb..f3c44a2ddc52661984cc07b2ee23b3a3431a4b0a 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -1456,6 +1456,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
|
int tickedEntities = 0; // Paper - rewrite chunk system
|
|
|
|
int tilesThisCycle = 0;
|
|
+ int shouldTickBlocksAtLastResult = -1; // Plazma - Port SparklyPaper patches; Optimize tickingBlockEntities
|
|
+ long shouldTickBlocksAtChunkPos = 0; // Plazma - Port SparklyPaper patches; Optimize tickingBlockEntities
|
|
var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<TickingBlockEntity>(); // Paper - Fix MC-117075; use removeAll
|
|
toRemove.add(null); // Paper - Fix MC-117075
|
|
for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters
|
|
@@ -1468,14 +1470,28 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
|
tilesThisCycle--;
|
|
toRemove.add(tickingblockentity); // Paper - Fix MC-117075; use removeAll
|
|
// Spigot end
|
|
- } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) {
|
|
- tickingblockentity.tick();
|
|
- // Paper start - rewrite chunk system
|
|
- if ((++tickedEntities & 7) == 0) {
|
|
- ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
|
|
- }
|
|
- // Paper end - rewrite chunk system
|
|
- }
|
|
+ // Plazma start - Port SparklyPaper patches; Optimize tickingBlockEntities
|
|
+ } else if (flag) {
|
|
+ long chunkPos = tickingblockentity.getChunkCoordinateKey();
|
|
+ boolean shouldTick;
|
|
+ if (shouldTickBlocksAtChunkPos == chunkPos && shouldTickBlocksAtLastResult != -1)
|
|
+ shouldTick = shouldTickBlocksAtLastResult == 1;
|
|
+ else {
|
|
+ shouldTick = this.shouldTickBlocksAt(chunkPos);
|
|
+ shouldTickBlocksAtLastResult = shouldTick ? 1 : 0;
|
|
+ shouldTickBlocksAtChunkPos = chunkPos;
|
|
+ } // diff on changes
|
|
+
|
|
+ if (shouldTick) {
|
|
+ tickingblockentity.tick();
|
|
+ // Paper start - execute chunk tasks during tick
|
|
+ if ((++tickedEntities & 7) == 0) {
|
|
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
|
|
+ }
|
|
+ // Paper end - execute chunk tasks during tick
|
|
+ } // diff on changes
|
|
+ } // diff on changes
|
|
+ // Plazma end - Port SparklyPaper patches; Optimize tickingBlockEntities
|
|
}
|
|
this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java
|
|
index 5a190834baef60c7b61074393f8856a933902d81..366ae05a060b5b12b85521a4b8aed1907f3f044a 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/CropBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java
|
|
@@ -77,35 +77,57 @@ public class CropBlock extends BushBlock implements BonemealableBlock {
|
|
|
|
@Override
|
|
protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
|
- if (world.getRawBrightness(pos, 0) >= 9) {
|
|
- int i = this.getAge(state);
|
|
-
|
|
- if (i < this.getMaxAge()) {
|
|
- float f = CropBlock.getGrowthSpeed(this, world, pos);
|
|
-
|
|
- // Spigot start
|
|
- int modifier;
|
|
- if (this == Blocks.BEETROOTS) {
|
|
- modifier = world.spigotConfig.beetrootModifier;
|
|
- } else if (this == Blocks.CARROTS) {
|
|
- modifier = world.spigotConfig.carrotModifier;
|
|
- } else if (this == Blocks.POTATOES) {
|
|
- modifier = world.spigotConfig.potatoModifier;
|
|
- // Paper start - Fix Spigot growth modifiers
|
|
- } else if (this == Blocks.TORCHFLOWER_CROP) {
|
|
- modifier = world.spigotConfig.torchFlowerModifier;
|
|
- // Paper end - Fix Spigot growth modifiers
|
|
- } else {
|
|
- modifier = world.spigotConfig.wheatModifier;
|
|
- }
|
|
+ // Plazma start - Port SparklyPaper patches; Optimize Farm checks
|
|
+ if (world.getRawBrightness(pos, 0) < 9) return;
|
|
+
|
|
+ int age = this.getAge(state);
|
|
+ if (age >= this.getMaxAge()) return;
|
|
+
|
|
+ final int modifier;
|
|
+ if (this == Blocks.BEETROOTS) {
|
|
+ modifier = world.spigotConfig.beetrootModifier;
|
|
+ } else if (this == Blocks.CARROTS) {
|
|
+ modifier = world.spigotConfig.carrotModifier;
|
|
+ } else if (this == Blocks.POTATOES) {
|
|
+ modifier = world.spigotConfig.potatoModifier;
|
|
+ } else if (this == Blocks.TORCHFLOWER_CROP) {
|
|
+ modifier = world.spigotConfig.torchFlowerModifier;
|
|
+ } else {
|
|
+ modifier = world.spigotConfig.wheatModifier;
|
|
+ }
|
|
|
|
- if (random.nextFloat() < (modifier / (100.0f * (Math.floor((25.0F / f) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution
|
|
- // Spigot end
|
|
- CraftEventFactory.handleBlockGrowEvent(world, pos, this.getStateForAge(i + 1), 2); // CraftBukkit
|
|
- }
|
|
+ if (world.plazmaConfig().block.optimizeFarmCheck.enabled) {
|
|
+ BlockPos current = pos.below();
|
|
+ BlockState currentState = world.getBlockState(current);
|
|
+
|
|
+ boolean moist;
|
|
+ float growthSpeed;
|
|
+ if (currentState.is(Blocks.FARMLAND) && currentState.getValue(FarmBlock.MOISTURE) > 0) {
|
|
+ moist = true;
|
|
+ growthSpeed = world.plazmaConfig().block.optimizeFarmCheck.growthSpeed.moist;
|
|
+ } else {
|
|
+ moist = false;
|
|
+ growthSpeed = world.plazmaConfig().block.optimizeFarmCheck.growthSpeed.normal;
|
|
}
|
|
+
|
|
+ if (world.plazmaConfig().block.optimizeFarmCheck.skipMiddleAgingStageForCrops) {
|
|
+ growthSpeed = growthSpeed / getMaxAge();
|
|
+ age = getMaxAge() - 1;
|
|
+ }
|
|
+
|
|
+ if (random.nextFloat() >= (modifier / (100.0f * Math.floor((25.0F / growthSpeed) + 1)))) return;
|
|
+ if (!CraftEventFactory.handleBlockGrowEvent(world, pos, this.getStateForAge(age + 1), 2)) return;
|
|
+ if (!moist || age + 1 != this.getMaxAge() || FarmBlock.isNearWater(world, current)) return;
|
|
+
|
|
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, current, currentState.setValue(FarmBlock.MOISTURE, 0), 2);
|
|
+ return;
|
|
}
|
|
|
|
+ float growthSpeed = CropBlock.getGrowthSpeed(this, world, pos);
|
|
+
|
|
+ if (random.nextFloat() < (modifier / (100.0f * Math.floor((25.0F / growthSpeed) + 1))))
|
|
+ CraftEventFactory.handleBlockGrowEvent(world, pos, this.getStateForAge(age + 1), 2);
|
|
+ // Plazma end - Port SparklyPaper patches; Optimize Farm checks
|
|
}
|
|
|
|
public void growCrops(Level world, BlockPos pos, BlockState state) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
|
|
index d0ec0722496ed931b48c4e7076fddbb1ed36e111..b91afbc90c138ebb7f8722934f59f953642196c9 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
|
|
@@ -92,7 +92,19 @@ public class FarmBlock extends Block {
|
|
|
|
@Override
|
|
protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
|
- int i = (Integer) state.getValue(FarmBlock.MOISTURE);
|
|
+ // Plazma start - Port SparklyPaper patches; Optimize Farm checks
|
|
+ int i = state.getValue(FarmBlock.MOISTURE);
|
|
+ if (world.plazmaConfig().block.optimizeFarmCheck.enabled) {
|
|
+ if (i != 0) return;
|
|
+
|
|
+ if (isNearWater(world, pos))
|
|
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, pos, state.setValue(MOISTURE, 7), 2);
|
|
+ else
|
|
+ turnToDirt(null, state, world, pos);
|
|
+
|
|
+ return;
|
|
+ }
|
|
+ // Plazma end - Port SparklyPaper patches; Optimize Farm checks
|
|
if (i > 0 && world.paperConfig().tickRates.wetFarmland != 1 && (world.paperConfig().tickRates.wetFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.wetFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks
|
|
if (i == 0 && world.paperConfig().tickRates.dryFarmland != 1 && (world.paperConfig().tickRates.dryFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.dryFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks
|
|
|
|
@@ -167,7 +179,7 @@ public class FarmBlock extends Block {
|
|
return world.getBlockState(pos.above()).is(BlockTags.MAINTAINS_FARMLAND);
|
|
}
|
|
|
|
- private static boolean isNearWater(LevelReader world, BlockPos pos) {
|
|
+ static boolean isNearWater(LevelReader world, BlockPos pos) { // Plazma - AT (private -> package)
|
|
// Paper start - Perf: remove abstract block iteration
|
|
int xOff = pos.getX();
|
|
int yOff = pos.getY();
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/StemBlock.java b/src/main/java/net/minecraft/world/level/block/StemBlock.java
|
|
index 924d80eb41d9a71d1e521c40742557251cf51832..4a30e1e6eac4b0e3dc2147a74e73e05fa76f5db2 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/StemBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/StemBlock.java
|
|
@@ -72,38 +72,82 @@ public class StemBlock extends BushBlock implements BonemealableBlock {
|
|
|
|
@Override
|
|
protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
|
- if (world.getRawBrightness(pos, 0) >= 9) {
|
|
- float f = CropBlock.getGrowthSpeed(this, world, pos);
|
|
-
|
|
- if (random.nextFloat() < ((this == Blocks.PUMPKIN_STEM ? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier) / (100.0f * (Math.floor((25.0F / f) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution
|
|
- int i = (Integer) state.getValue(StemBlock.AGE);
|
|
-
|
|
- if (i < 7) {
|
|
- state = (BlockState) state.setValue(StemBlock.AGE, i + 1);
|
|
- CraftEventFactory.handleBlockGrowEvent(world, pos, state, 2); // CraftBukkit
|
|
- } else {
|
|
- Direction enumdirection = Direction.Plane.HORIZONTAL.getRandomDirection(random);
|
|
- BlockPos blockposition1 = pos.relative(enumdirection);
|
|
- BlockState iblockdata1 = world.getBlockState(blockposition1.below());
|
|
-
|
|
- if (world.getBlockState(blockposition1).isAir() && (iblockdata1.is(Blocks.FARMLAND) || iblockdata1.is(BlockTags.DIRT))) {
|
|
- Registry<Block> iregistry = world.registryAccess().registryOrThrow(Registries.BLOCK);
|
|
- Optional<Block> optional = iregistry.getOptional(this.fruit);
|
|
- Optional<Block> optional1 = iregistry.getOptional(this.attachedStem);
|
|
-
|
|
- if (optional.isPresent() && optional1.isPresent()) {
|
|
- // CraftBukkit start
|
|
- if (!CraftEventFactory.handleBlockGrowEvent(world, blockposition1, ((Block) optional.get()).defaultBlockState())) {
|
|
- return;
|
|
- }
|
|
- // CraftBukkit end
|
|
- world.setBlockAndUpdate(pos, (BlockState) ((Block) optional1.get()).defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, enumdirection));
|
|
- }
|
|
- }
|
|
- }
|
|
+ // Plazma start - Port SparklyPaper patches; Optimize Farm checks
|
|
+ if (world.getRawBrightness(pos, 0) < 9) return;
|
|
+
|
|
+ int modifier = this == Blocks.PUMPKIN_STEM ? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier;
|
|
+
|
|
+ if (world.plazmaConfig().block.optimizeFarmCheck.enabled) {
|
|
+ final BlockPos current = pos.below();
|
|
+ final BlockState currentState = world.getBlockState(current);
|
|
+
|
|
+ final boolean moist;
|
|
+ final float growthSpeed;
|
|
+ if (currentState.is(Blocks.FARMLAND) && currentState.getValue(FarmBlock.MOISTURE) > 0) {
|
|
+ moist = true;
|
|
+ growthSpeed = world.plazmaConfig().block.optimizeFarmCheck.growthSpeed.moist;
|
|
+ } else {
|
|
+ moist = false;
|
|
+ growthSpeed = world.plazmaConfig().block.optimizeFarmCheck.growthSpeed.normal;
|
|
}
|
|
|
|
+ if (random.nextFloat() >= (modifier / (100.0f * Math.floor((25.0F / growthSpeed) + 1)))) return;
|
|
+
|
|
+ int age = state.getValue(AGE);
|
|
+
|
|
+ if (age < 7) {
|
|
+ CraftEventFactory.handleMoistureChangeEvent(world, pos, state.setValue(AGE, age + 1), 2);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Direction direction = Direction.Plane.HORIZONTAL.getRandomDirection(random);
|
|
+ BlockPos pos1 = pos.relative(direction);
|
|
+ BlockState state1 = world.getBlockState(pos1.below());
|
|
+
|
|
+ if (!world.getBlockState(pos1).isAir() || (!state1.is(Blocks.FARMLAND) && !state1.is(BlockTags.DIRT)))
|
|
+ return;
|
|
+
|
|
+ Registry<Block> registry = world.registryAccess().registryOrThrow(Registries.BLOCK);
|
|
+ Optional<Block> fruit = registry.getOptional(this.fruit);
|
|
+ Optional<Block> stem = registry.getOptional(this.attachedStem);
|
|
+
|
|
+ if (fruit.isEmpty() || stem.isEmpty()) return;
|
|
+ if (!CraftEventFactory.handleBlockGrowEvent(world, pos1, fruit.get().defaultBlockState())) return;
|
|
+ if (moist && !FarmBlock.isNearWater(world, current))
|
|
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, current, currentState.setValue(FarmBlock.MOISTURE, 0), 2);
|
|
+
|
|
+ world.setBlockAndUpdate(pos, stem.get().defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, direction));
|
|
+ return;
|
|
}
|
|
+
|
|
+ float f = CropBlock.getGrowthSpeed(this, world, pos);
|
|
+
|
|
+ if (random.nextFloat() >= (modifier / (100.0f * Math.floor((25.0F / f) + 1)))) return;
|
|
+
|
|
+ int age = state.getValue(StemBlock.AGE);
|
|
+
|
|
+ if (age < 7) {
|
|
+ CraftEventFactory.handleBlockGrowEvent(world, pos, state.setValue(StemBlock.AGE, age + 1), 2);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Direction direction = Direction.Plane.HORIZONTAL.getRandomDirection(random);
|
|
+ BlockPos pos1 = pos.relative(direction);
|
|
+ BlockState state1 = world.getBlockState(pos1.below());
|
|
+
|
|
+ if (!world.getBlockState(pos1).isAir() || (!state1.is(Blocks.FARMLAND) && !state1.is(BlockTags.DIRT))) return;
|
|
+
|
|
+ Registry<Block> registry = world.registryAccess().registryOrThrow(Registries.BLOCK);
|
|
+ Optional<Block> fruit = registry.getOptional(this.fruit);
|
|
+ Optional<Block> stem = registry.getOptional(this.attachedStem);
|
|
+
|
|
+ if (fruit.isEmpty() || stem.isEmpty()) return;
|
|
+
|
|
+ if (!CraftEventFactory.handleBlockGrowEvent(world, pos1, fruit.get().defaultBlockState()))
|
|
+ return;
|
|
+
|
|
+ world.setBlockAndUpdate(pos, stem.get().defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, direction));
|
|
+ // Plazma end - Port SparklyPaper patches; Optimize Farm checks
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TickingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TickingBlockEntity.java
|
|
index 28e3b73507b988f7234cbf29c4024c88180d0aef..6239c171ca996f3f5c23060f728a62236bc8b6d5 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TickingBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TickingBlockEntity.java
|
|
@@ -10,4 +10,6 @@ public interface TickingBlockEntity {
|
|
BlockPos getPos();
|
|
|
|
String getType();
|
|
+
|
|
+ long getChunkCoordinateKey(); // Plazma - Port SparklyPaper patches; Optimize tickingBlockEntities
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
|
index 75c8125e20b70433fe9d143a3193d821043327c3..80511433c184c6918c8d2e7cff6ca257e8fbf676 100644
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
|
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
|
@@ -66,6 +66,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
|
|
protected volatile boolean unsaved;
|
|
private volatile boolean isLightCorrect;
|
|
protected final ChunkPos chunkPos; public final long coordinateKey; public final int locX; public final int locZ; // Paper - cache coordinate key
|
|
+ public final long nearbyPlayersCoordinateKey; // Plazma - Port SparklyPaper patches; Cache coordinate key used for nearby players when ticking chunks
|
|
private long inhabitedTime;
|
|
/** @deprecated */
|
|
@Nullable
|
|
@@ -144,6 +145,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
|
|
public ChunkAccess(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry<Biome> biomeRegistry, long inhabitedTime, @Nullable LevelChunkSection[] sectionArray, @Nullable BlendingData blendingData) {
|
|
this.locX = pos.x; this.locZ = pos.z; // Paper - reduce need for field lookups
|
|
this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); // Paper - cache long key
|
|
+ this.nearbyPlayersCoordinateKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(locX, locZ); // Plazma - Port SparklyPaper patches; Cache coordinate key used for nearby players when ticking chunks
|
|
this.upgradeData = upgradeData;
|
|
this.levelHeightAccessor = heightLimitView;
|
|
this.sections = new LevelChunkSection[heightLimitView.getSectionsCount()];
|
|
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 a4578ae22409edb686d0bcbac8cbc1a2e1d7b988..9cc1a79dd25c63af6986e721ceff5560cf56b7d1 100644
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
|
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
|
@@ -74,6 +74,8 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
|
public String getType() {
|
|
return "<null>";
|
|
}
|
|
+
|
|
+ @Override public long getChunkCoordinateKey() { return 0; } // Plazma - Port SparklyPaper patches; Optimize tickingBlockEntities
|
|
};
|
|
private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel;
|
|
public boolean loaded;
|
|
@@ -966,7 +968,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
|
}
|
|
|
|
private <T extends BlockEntity> TickingBlockEntity createTicker(T blockEntity, BlockEntityTicker<T> blockEntityTicker) {
|
|
- return new LevelChunk.BoundTickingBlockEntity<>(blockEntity, blockEntityTicker);
|
|
+ return new LevelChunk.BoundTickingBlockEntity<>(blockEntity, blockEntityTicker, this.coordinateKey); // Plazma - Port SparklyPaper patches; Optimize TickingBlockEntity
|
|
}
|
|
|
|
@FunctionalInterface
|
|
@@ -1017,6 +1019,8 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
|
public String toString() {
|
|
return String.valueOf(this.ticker) + " <wrapped>";
|
|
}
|
|
+
|
|
+ @Override public long getChunkCoordinateKey() { return this.ticker.getChunkCoordinateKey(); } // Plazma - Port SparklyPaper patches; Optimize TickingBlockEntity
|
|
}
|
|
|
|
private class BoundTickingBlockEntity<T extends BlockEntity> implements TickingBlockEntity {
|
|
@@ -1024,10 +1028,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
|
private final T blockEntity;
|
|
private final BlockEntityTicker<T> ticker;
|
|
private boolean loggedInvalidBlockState;
|
|
+ private final long chunkCoordinateKey; // Plazma - Port SparklyPaper patches; Optimize TickingBlockEntity
|
|
|
|
- BoundTickingBlockEntity(final BlockEntity tileentity, final BlockEntityTicker blockentityticker) {
|
|
+ BoundTickingBlockEntity(final BlockEntity tileentity, final BlockEntityTicker blockentityticker, long chunkCoordinateKey) { // Plazma - Port SparklyPaper patches; Optimize TickingBlockEntity
|
|
this.blockEntity = (T) tileentity; // CraftBukkit - decompile error
|
|
this.ticker = blockentityticker;
|
|
+ this.chunkCoordinateKey = chunkCoordinateKey; // Plazma - Port SparklyPaper patches; Optimize TickingBlockEntity
|
|
}
|
|
|
|
@Override
|
|
@@ -1095,5 +1101,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
|
|
|
return "Level ticker for " + s + "@" + String.valueOf(this.getPos());
|
|
}
|
|
+
|
|
+ @Override public long getChunkCoordinateKey() { return this.chunkCoordinateKey; } // Plazma - Port SparklyPaper patches; Optimize TickingBlockEntity
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/sparklypower/sparklypaper/HalloweenManager.java b/src/main/java/net/sparklypower/sparklypaper/HalloweenManager.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..f8c26e26025d7a7b5489ed5b3274ba734db27a1d
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/sparklypower/sparklypaper/HalloweenManager.java
|
|
@@ -0,0 +1,78 @@
|
|
+package net.sparklypower.sparklypaper;
|
|
+
|
|
+import com.mojang.logging.LogUtils;
|
|
+import it.unimi.dsi.fastutil.Pair;
|
|
+import net.minecraft.world.level.Level;
|
|
+import org.slf4j.Logger;
|
|
+import java.time.LocalDateTime;
|
|
+import java.time.Month;
|
|
+import java.time.ZoneOffset;
|
|
+import java.util.concurrent.CountDownLatch;
|
|
+import java.util.concurrent.Executors;
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
+import java.util.concurrent.ScheduledFuture;
|
|
+import java.util.concurrent.TimeUnit;
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
+
|
|
+import static org.plazmamc.plazma.configurations.GlobalConfiguration.get;
|
|
+
|
|
+public class HalloweenManager {
|
|
+
|
|
+ private static final Logger LOGGER = LogUtils.getClassLogger();
|
|
+ private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor(factory -> {
|
|
+ Thread thread = new Thread(factory);
|
|
+ thread.setName("halloween-timer-updater");
|
|
+ thread.setPriority(1);
|
|
+ return thread;
|
|
+ });
|
|
+
|
|
+ private static ScheduledFuture<?> future;
|
|
+ private static Pair<Long, Long> spookyEpoch;
|
|
+ private static Pair<Long, Long> halloweenEpoch;
|
|
+
|
|
+ private static long getEpochMillisAtDate(Month month, int day, boolean start) {
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
+ LocalDateTime target = LocalDateTime.of(
|
|
+ now.getYear(), month, day, start ? 0 : 23, start ? 0 : 59, start ? 0 : 59, start ? 0 : 999_999_999
|
|
+ );
|
|
+
|
|
+ if (now.isAfter(target)) target = target.plusYears(1);
|
|
+ return target.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli();
|
|
+ }
|
|
+
|
|
+ private static void syncEpoch() {
|
|
+ LOGGER.info("Updating Spooky Season and Halloween epoch...");
|
|
+ spookyEpoch = Pair.of(
|
|
+ getEpochMillisAtDate(Month.OCTOBER, 20, true),
|
|
+ getEpochMillisAtDate(Month.NOVEMBER, 3, false)
|
|
+ );
|
|
+ halloweenEpoch = Pair.of(
|
|
+ getEpochMillisAtDate(Month.OCTOBER, 31, true),
|
|
+ getEpochMillisAtDate(Month.OCTOBER, 31, false)
|
|
+ );
|
|
+ LOGGER.info("Successfully updated Spooky Season and Halloween epoch");
|
|
+ }
|
|
+
|
|
+ public static void syncConfiguration() {
|
|
+ if (get().entity.spookyOptimize && future == null) {
|
|
+ startSyncEpochTask();
|
|
+ } else if (!get().entity.spookyOptimize && future != null) {
|
|
+ future.cancel(true);
|
|
+ future = null;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static void startSyncEpochTask() {
|
|
+ if (!get().entity.spookyOptimize) return;
|
|
+ future = EXECUTOR.scheduleAtFixedRate(HalloweenManager::syncEpoch, 0, 90, TimeUnit.DAYS);
|
|
+ }
|
|
+
|
|
+ public static boolean isSpookySeason() {
|
|
+ return spookyEpoch.first() <= System.currentTimeMillis() && System.currentTimeMillis() <= spookyEpoch.second();
|
|
+ }
|
|
+
|
|
+ public static boolean isHalloween() {
|
|
+ return halloweenEpoch.first() <= System.currentTimeMillis() && System.currentTimeMillis() <= halloweenEpoch.second();
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
index 173e4a075078af67f030750c9a6294ab3f796677..92ad49e0ff5dc17bc8e181578ff93bc96e3503ef 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -978,7 +978,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
public void sendMultiBlockChange(final Map<? extends io.papermc.paper.math.Position, BlockData> blockChanges) {
|
|
if (this.getHandle().connection == null) return;
|
|
|
|
- Map<SectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState>> sectionMap = new HashMap<>();
|
|
+ Map<SectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState>> sectionMap = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // Plazma - Port SparklyPaper patches; Optimize canSee checks
|
|
|
|
for (Map.Entry<? extends io.papermc.paper.math.Position, BlockData> entry : blockChanges.entrySet()) {
|
|
BlockData blockData = entry.getValue();
|
|
@@ -2259,9 +2259,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
|
|
@Override
|
|
public boolean canSee(org.bukkit.entity.Entity entity) {
|
|
- return this.equals(entity) || entity.isVisibleByDefault() ^ this.invertedVisibilityEntities.containsKey(entity.getUniqueId()); // SPIGOT-7312: Can always see self
|
|
+ return this.equals(entity) || this.chunkMapCanSee(entity); // SPIGOT-7312: Can always see self // Plazma - Port SparklyPaper patches; Optimize canSee check
|
|
}
|
|
|
|
+ // Plazma start - Port SparklyPaper patches; Optimize canSee check (The check in ChunkMap#updatePlayer already rejects if it is the same entity, so we don't need to check it twice, especially because CraftPlayer's equals check is a bit expensive)
|
|
+ public boolean chunkMapCanSee(org.bukkit.entity.Entity entity) {
|
|
+ return entity.isVisibleByDefault() ^ (!invertedVisibilityEntities.isEmpty() && this.invertedVisibilityEntities.containsKey(entity.getUniqueId()));
|
|
+ }
|
|
+ // Plazma end - Port SparklyPaper patches; Optimize canSee check
|
|
+
|
|
public boolean canSeePlayer(UUID uuid) {
|
|
org.bukkit.entity.Entity entity = this.getServer().getPlayer(uuid);
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapColorCache.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapColorCache.java
|
|
index 8149b9c51b78eb5c689b7218a2ca3aab60e73bcf..b9a303f6280a2f6ad3616da152922a4f4a504281 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapColorCache.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapColorCache.java
|
|
@@ -145,7 +145,7 @@ public class CraftMapColorCache implements MapPalette.MapColorCache {
|
|
}
|
|
|
|
@Override
|
|
- public boolean isCached() {
|
|
+ public synchronized boolean isCached() { // Plazma - Fix concurrency issues when using "imageToBytes" in multiple threads
|
|
return this.cached || (!this.running.get() && this.initCache().isDone());
|
|
}
|
|
|
|
diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java
|
|
index 451723377d505f1fe15ddd4ac535ca61fa253f17..7ccf554610bd00b602eb7be11df7028d2f6a7008 100644
|
|
--- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java
|
|
+++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java
|
|
@@ -68,6 +68,8 @@ public class GlobalConfiguration extends ConfigurationPart {
|
|
public Entity entity;
|
|
public class Entity extends ConfigurationPart {
|
|
|
|
+ boolean skipSqrWhenNoDeltaChanges = OPTIMIZE;
|
|
+ public boolean spookyOptimize = OPTIMIZE;
|
|
|
|
public AsyncPathProcess asyncPathProcess;
|
|
public class AsyncPathProcess extends ConfigurationPart {
|
|
@@ -91,6 +93,7 @@ public class GlobalConfiguration extends ConfigurationPart {
|
|
|
|
@PostProcess
|
|
public void post() {
|
|
+ net.minecraft.server.level.ServerEntity.skipSqrWhenNoDeltaChanges = this.skipSqrWhenNoDeltaChanges;
|
|
}
|
|
|
|
}
|
|
@@ -98,9 +101,11 @@ public class GlobalConfiguration extends ConfigurationPart {
|
|
public World world;
|
|
public class World extends ConfigurationPart {
|
|
|
|
+ boolean skipTickWhenCraftNotPresent = OPTIMIZE;
|
|
|
|
@PostProcess
|
|
public void post() {
|
|
+ net.minecraft.world.item.MapItem.skipTickWhenCraftNotPresent = this.skipTickWhenCraftNotPresent;
|
|
}
|
|
|
|
}
|
|
diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java
|
|
index e5989010aa752c23eda58a6df87aa6925f45671a..00ab417a8b7da0457b6f8e18e4f877373774672e 100644
|
|
--- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java
|
|
+++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java
|
|
@@ -89,7 +89,22 @@ public class WorldConfigurations extends ConfigurationPart {
|
|
|
|
public Block block;
|
|
public class Block extends ConfigurationPart {
|
|
-
|
|
+
|
|
+ public OptimizeFarmCheck optimizeFarmCheck;
|
|
+ public class OptimizeFarmCheck extends ConfigurationPart {
|
|
+
|
|
+ public boolean enabled = OPTIMIZE;
|
|
+ public boolean skipMiddleAgingStageForCrops = true;
|
|
+
|
|
+ public GrowthSpeed growthSpeed;
|
|
+ public class GrowthSpeed extends ConfigurationPart {
|
|
+
|
|
+ public int normal = 1;
|
|
+ public int moist = 4;
|
|
+
|
|
+ }
|
|
+
|
|
+ }
|
|
|
|
}
|
|
|