Merge pull request 'Fix tick freeze issues' (#7) from tick-freeze into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Reviewed-on: #7
Dieser Commit ist enthalten in:
YoyoNow 2023-04-13 11:25:21 +02:00
Commit 5b55c23dbd
2 geänderte Dateien mit 70 neuen und 431 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lixfel <agga-games@gmx.de>
Date: Thu, 13 Apr 2023 10:28:53 +0200
Subject: [PATCH] Tick freeze
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 54c2b7fba83d6f06dba95b1bb5b487a02048d6e6..cc51b2b9188d798eb51fdc3bfb87f02bb9095204 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -625,6 +625,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
public void tick(BooleanSupplier shouldKeepTicking) {
+ if(!freezed) {
// Paper start - optimise checkDespawn
this.playersAffectingSpawning.clear();
for (ServerPlayer player : this.players) {
@@ -633,9 +634,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
// Paper end - optimise checkDespawn
+ } // freezed
ProfilerFiller gameprofilerfiller = this.getProfiler();
this.handlingTick = true;
+ if(!freezed) {
gameprofilerfiller.push("world border");
this.getWorldBorder().tick();
gameprofilerfiller.popPush("weather");
@@ -681,14 +684,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.timings.raids.startTiming(); // Paper - timings
this.raids.tick();
this.timings.raids.stopTiming(); // Paper - timings
+ } // freezed
gameprofilerfiller.popPush("chunkSource");
this.timings.chunkProviderTick.startTiming(); // Paper - timings
this.getChunkSource().tick(shouldKeepTicking, true);
this.timings.chunkProviderTick.stopTiming(); // Paper - timings
+ if(!freezed) {
gameprofilerfiller.popPush("blockEvents");
timings.doSounds.startTiming(); // Spigot
this.runBlockEvents();
timings.doSounds.stopTiming(); // Spigot
+ } // freezed
this.handlingTick = false;
gameprofilerfiller.pop();
boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players
@@ -697,7 +703,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.resetEmptyTime();
}
- if (flag || this.emptyTime++ < 300) {
+ if (!freezed && (flag || this.emptyTime++ < 300)) {
gameprofilerfiller.push("entities");
timings.tickEntities.startTiming(); // Spigot
if (this.dragonFight != null) {
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 3cbf801b2e5420c0e870f73788deb550e49ad54d..f6d1030725e1ebeeb2d62df401faf781171d5bee 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -181,6 +181,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
+ public boolean freezed = false;
+
// Paper start - fix and optimise world upgrading
// copied from below
public static ResourceKey<DimensionType> getDimensionKey(DimensionType manager) {

Datei anzeigen

@ -1,431 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lixfel <agga-games@gmx.de>
Date: Wed, 1 Feb 2023 21:49:21 +0100
Subject: [PATCH] TickFreeze
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 54c2b7fba83d6f06dba95b1bb5b487a02048d6e6..9d2a39fb012cfc8a5b186b389c6089a4d206301b 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1,21 +1,18 @@
package net.minecraft.server.level;
+import co.aikar.timings.TimingHistory;
import com.google.common.annotations.VisibleForTesting;
-import co.aikar.timings.TimingHistory; // Paper
import com.google.common.collect.Lists;
import com.mojang.datafixers.DataFixer;
import com.mojang.datafixers.util.Pair;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.longs.LongSets;
+import it.unimi.dsi.fastutil.objects.*;
import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry;
-import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
-import it.unimi.dsi.fastutil.objects.ObjectArrayList;
-import it.unimi.dsi.fastutil.objects.ObjectIterator;
-import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
-import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
@@ -40,28 +37,15 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.CrashReport;
import net.minecraft.Util;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderSet;
-import net.minecraft.core.RegistryAccess;
-import net.minecraft.core.SectionPos;
+import net.minecraft.core.*;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.protocol.Packet;
-import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket;
-import net.minecraft.network.protocol.game.ClientboundBlockEventPacket;
-import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
-import net.minecraft.network.protocol.game.ClientboundExplodePacket;
-import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
-import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket;
-import net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket;
-import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket;
-import net.minecraft.network.protocol.game.ClientboundSoundPacket;
-import net.minecraft.network.protocol.game.DebugPackets;
+import net.minecraft.network.protocol.game.*;
+import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceKey;
import io.papermc.paper.util.MCUtil;
import net.minecraft.server.MinecraftServer;
@@ -79,13 +63,7 @@ import net.minecraft.util.Unit;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.damagesource.DamageSource;
-import net.minecraft.world.entity.Entity;
-import net.minecraft.world.entity.EntityType;
-import net.minecraft.world.entity.LightningBolt;
-import net.minecraft.world.entity.LivingEntity;
-import net.minecraft.world.entity.Mob;
-import net.minecraft.world.entity.MobCategory;
-import net.minecraft.world.entity.ReputationEventHandler;
+import net.minecraft.world.entity.*;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.ai.village.ReputationEventType;
import net.minecraft.world.entity.ai.village.poi.PoiManager;
@@ -96,23 +74,15 @@ import net.minecraft.world.entity.animal.WaterAnimal;
import net.minecraft.world.entity.animal.horse.SkeletonHorse;
import net.minecraft.world.entity.boss.EnderDragonPart;
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
+import net.minecraft.world.entity.item.ItemEntity;
+import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.entity.npc.Npc;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.raid.Raid;
import net.minecraft.world.entity.raid.Raids;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.item.crafting.RecipeManager;
-import net.minecraft.world.level.BlockEventData;
-import net.minecraft.world.level.ChunkPos;
-import net.minecraft.world.level.CustomSpawner;
-import net.minecraft.world.level.Explosion;
-import net.minecraft.world.level.ExplosionDamageCalculator;
-import net.minecraft.world.level.ForcedChunksSavedData;
-import net.minecraft.world.level.GameRules;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.NaturalSpawner;
-import net.minecraft.world.level.StructureManager;
-import net.minecraft.world.level.WorldGenLevel;
+import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.block.Block;
@@ -128,12 +98,7 @@ import net.minecraft.world.level.chunk.storage.EntityStorage;
import net.minecraft.world.level.dimension.BuiltinDimensionTypes;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.dimension.end.EndDragonFight;
-import net.minecraft.world.level.entity.EntityPersistentStorage;
-import net.minecraft.world.level.entity.EntityTickList;
-import net.minecraft.world.level.entity.EntityTypeTest;
-import net.minecraft.world.level.entity.LevelCallback;
-import net.minecraft.world.level.entity.LevelEntityGetter;
-import net.minecraft.world.level.entity.PersistentEntitySectionManager;
+import net.minecraft.world.level.entity.*;
import net.minecraft.world.level.gameevent.DynamicGameEventListener;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.GameEventDispatcher;
@@ -174,6 +139,21 @@ import org.bukkit.event.world.TimeSkipEvent;
// CraftBukkit end
import it.unimi.dsi.fastutil.ints.IntArrayList; // Paper
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.concurrent.Executor;
+import java.util.function.BooleanSupplier;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
public class ServerLevel extends Level implements WorldGenLevel {
public static final BlockPos END_SPAWN_POINT = new BlockPos(100, 50, 0);
@@ -625,6 +605,9 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
public void tick(BooleanSupplier shouldKeepTicking) {
+ // SteamWar start
+ currentlyFrozen = freezed;
+ // SteamWar end
// Paper start - optimise checkDespawn
this.playersAffectingSpawning.clear();
for (ServerPlayer player : this.players) {
@@ -664,10 +647,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
this.updateSkyBrightness();
- this.tickTime();
+ // SteamWar start
+ if (!currentlyFrozen) {
+ this.tickTime();
+ }
+ // SteamWar end
gameprofilerfiller.popPush("tickPending");
timings.scheduledBlocks.startTiming(); // Paper
- if (!this.isDebug()) {
+ if (!currentlyFrozen && !this.isDebug()) { // SteamWar
j = this.getGameTime();
gameprofilerfiller.push("blockTicks");
this.blockTicks.tick(j, 65536, this::tickBlock);
@@ -687,7 +674,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.timings.chunkProviderTick.stopTiming(); // Paper - timings
gameprofilerfiller.popPush("blockEvents");
timings.doSounds.startTiming(); // Spigot
- this.runBlockEvents();
+ // SteamWar start
+ if (!currentlyFrozen) {
+ this.runBlockEvents();
+ }
+ // SteamWar end
timings.doSounds.stopTiming(); // Spigot
this.handlingTick = false;
gameprofilerfiller.pop();
@@ -697,6 +688,15 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.resetEmptyTime();
}
+ // SteamWar start
+ lastFreezed = false;
+ if (!currentlyFrozen && !physicsTick.isEmpty()) {
+ physicsTick.forEach((blockPos, runnables) -> runnables.forEach(Runnable::run));
+ physicsTick.clear();
+ lastFreezed = true;
+ }
+ // SteamWar end
+
if (flag || this.emptyTime++ < 300) {
gameprofilerfiller.push("entities");
timings.tickEntities.startTiming(); // Spigot
@@ -728,16 +728,30 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
gameprofilerfiller.push("tick");
- this.guardEntityTick(this::tickNonPassenger, entity);
+ // SteamWar start
+ if (!currentlyFrozen || entity instanceof Player) {
+ this.guardEntityTick(this::tickNonPassenger, entity);
+ }
+ // SteamWar end
gameprofilerfiller.pop();
}
}
}
});
+ // SteamWar start
+ getEntities().getAll().forEach(entity -> {
+ if (entity instanceof Player || entity instanceof ItemEntity) return;
+ sendEntityPackets(entity);
+ });
+ // SteamWar end
timings.entityTick.stopTiming(); // Spigot
timings.tickEntities.stopTiming(); // Spigot
gameprofilerfiller.pop();
- this.tickBlockEntities();
+ // SteamWar start
+ if (!currentlyFrozen) {
+ this.tickBlockEntities();
+ }
+ // SteamWar end
}
gameprofilerfiller.push("entityManagement");
@@ -797,6 +811,9 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper end
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
+ // SteamWar start
+ if (currentlyFrozen) return;
+ // SteamWar end
ChunkPos chunkcoordintpair = chunk.getPos();
boolean flag = this.isRaining();
int j = chunkcoordintpair.getMinBlockX();
@@ -1475,8 +1492,55 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.entityLookup.addNewEntity(player); // Paper - rewite chunk system
}
+ // SteamWar start
+ private boolean sendEntityPackets(Entity entity) {
+ if (currentlyFrozen && !(entity instanceof ItemEntity)) {
+ ClientboundSetEntityMotionPacket packetPlayOutEntityVelocity = new ClientboundSetEntityMotionPacket(entity.getId(), new Vec3(0, 0, 0));
+ ClientboundTeleportEntityPacket packetPlayOutEntityTeleport = new ClientboundTeleportEntityPacket(entity);
+ if (entity instanceof PrimedTnt) {
+ PrimedTnt entityTNTPrimed = new PrimedTnt(EntityType.TNT, this);
+ entityTNTPrimed.setNoGravity(true);
+ entityTNTPrimed.setPos(entity.getX(), entity.getY(), entity.getZ());
+ entityTNTPrimed.setFuse(((PrimedTnt) entity).getFuse());
+ entityTNTPrimed.setFuse(entityTNTPrimed.getFuse() - (entityTNTPrimed.getFuse() % 5 == 1 ? 1 : 0));
+ }
+ players.forEach(player -> {
+ player.connection.send(packetPlayOutEntityVelocity);
+ player.connection.send(packetPlayOutEntityTeleport);
+ });
+
+ List<SynchedEntityData.DataValue<?>> nonDefaultValues = entity.getEntityData().getNonDefaultValues();
+ if(nonDefaultValues != null) {
+ ClientboundSetEntityDataPacket packetPlayOutEntityMetadata = new ClientboundSetEntityDataPacket(entity.getId(), nonDefaultValues);
+ players.forEach(player -> player.connection.send(packetPlayOutEntityMetadata));
+ }
+ return true;
+ }
+ if (lastFreezed && !(entity instanceof ItemEntity)) {
+ ClientboundSetEntityMotionPacket packetPlayOutEntityVelocity = new ClientboundSetEntityMotionPacket(entity);
+ ClientboundTeleportEntityPacket packetPlayOutEntityTeleport = new ClientboundTeleportEntityPacket(entity);
+
+ players.forEach(player -> {
+ player.connection.send(packetPlayOutEntityVelocity);
+ player.connection.send(packetPlayOutEntityTeleport);
+ });
+
+ List<SynchedEntityData.DataValue<?>> nonDefaultValues = entity.getEntityData().getNonDefaultValues();
+ if(nonDefaultValues != null) {
+ ClientboundSetEntityDataPacket packetPlayOutEntityMetadata = new ClientboundSetEntityDataPacket(entity.getId(), nonDefaultValues);
+ players.forEach(player -> player.connection.send(packetPlayOutEntityMetadata));
+ }
+ }
+ return false;
+ }
+ // SteamWar end
+
// CraftBukkit start
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
+ // SteamWar start
+ if (sendEntityPackets(entity)) return true;
+ // SteamWar end
+
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
// Paper start
if (entity.valid) {
@@ -1700,12 +1764,24 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override
public void updateNeighborsAt(BlockPos pos, Block sourceBlock) {
+ if (currentlyFrozen) {
+ physicsTick.computeIfAbsent(pos, p -> new ArrayList<>()).add(() -> {
+ updateNeighborsAt(pos, sourceBlock);
+ });
+ return;
+ }
if (captureBlockStates) { return; } // Paper - Cancel all physics during placement
this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null);
}
@Override
public void updateNeighborsAtExceptFromFacing(BlockPos pos, Block sourceBlock, Direction direction) {
+ if (currentlyFrozen) {
+ physicsTick.computeIfAbsent(pos, p -> new ArrayList<>()).add(() -> {
+ updateNeighborsAtExceptFromFacing(pos, sourceBlock, direction);
+ });
+ return;
+ }
this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, direction);
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 3cbf801b2e5420c0e870f73788deb550e49ad54d..5e173f3b96fc03baf53b9a7b8dcc37828fe8f7c7 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -8,9 +8,7 @@ import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;
import com.mojang.serialization.Codec;
import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
@@ -47,6 +45,7 @@ import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
@@ -181,6 +180,21 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
+ // SteamWar start
+ public boolean freezed = false;
+ protected boolean currentlyFrozen = false;
+ protected boolean lastFreezed = false;
+ protected Map<BlockPos, List<Runnable>> physicsTick = new LinkedHashMap<>();
+
+ public boolean getCurrentlyFrozen() {
+ return currentlyFrozen;
+ }
+
+ public void addPhysicsTick(BlockPos pos, Runnable runnable) {
+ physicsTick.computeIfAbsent(pos, k -> new ArrayList<>()).add(runnable);
+ }
+ // SteamWar end
+
// Paper start - fix and optimise world upgrading
// copied from below
public static ResourceKey<DimensionType> getDimensionKey(DimensionType manager) {
@@ -536,6 +550,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
} else {
LevelChunk chunk = this.getChunkAt(pos);
Block block = state.getBlock();
+ // SteamWar start
+ if (currentlyFrozen && block.asItem().equals(Items.AIR)) {
+ physicsTick.remove(pos);
+ }
+ // SteamWar end
// CraftBukkit start - capture blockstates
boolean captured = false;
@@ -552,6 +571,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
if (iblockdata1 == null) {
// CraftBukkit start - remove blockstate if failed (or the same)
+ // SteamWar start
+ if (currentlyFrozen) {
+ physicsTick.remove(pos);
+ }
+ // SteamWar end
if (this.captureBlockStates && captured) {
this.capturedBlockStates.remove(pos);
}
@@ -654,8 +678,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}
}
// CraftBukkit end
- iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1);
- iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1);
+ // SteamWar start
+ if (!currentlyFrozen) {
+ iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1);
+ iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1);
+ } else {
+ physicsTick.computeIfAbsent(blockposition, __ -> new ArrayList<>()).add(() -> {
+ iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1);
+ iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1);
+ });
+ }
+ // SteamWar end
}
// CraftBukkit start - SPIGOT-5710
diff --git a/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java
index 19faa8f5f891c1ffbed0af8391dee8202433c447..84373b6f1558174ebe66cd7ee1d8307f141be7ae 100644
--- a/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java
+++ b/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java
@@ -51,6 +51,12 @@ public interface NeighborUpdater {
}
static void executeUpdate(Level world, BlockState state, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
+ if (world.getCurrentlyFrozen()) {
+ world.addPhysicsTick(sourcePos, () -> {
+ executeUpdate(world, state, pos, sourceBlock, sourcePos, notify);
+ });
+ return;
+ }
try {
// CraftBukkit start
CraftWorld cworld = ((ServerLevel) world).getWorld();