geforkt von Mirrors/Paper
Merge pull request 'Fix tick freeze issues' (#7) from tick-freeze into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #7
Dieser Commit ist enthalten in:
Commit
5b55c23dbd
70
patches/server/0963-Tick-freeze.patch
Normale Datei
70
patches/server/0963-Tick-freeze.patch
Normale Datei
@ -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) {
|
@ -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();
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren