minecraft-source/src/net/minecraft/server/level/ServerLevel.java

1297 lines
55 KiB
Java

package net.minecraft.server.level;
import org.apache.logging.log4j.LogManager;
import net.minecraft.world.level.dimension.Dimension;
import net.minecraft.world.level.TickList;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.scores.Scoreboard;
import com.google.common.annotations.VisibleForTesting;
import net.minecraft.core.Vec3i;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.util.CsvOutput;
import java.io.IOException;
import java.io.Writer;
import net.minecraft.CrashReport;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import net.minecraft.world.entity.ReputationEventHandler;
import net.minecraft.world.entity.ai.village.ReputationEventType;
import net.minecraft.world.entity.raid.Raid;
import net.minecraft.core.SectionPos;
import net.minecraft.world.entity.ai.village.poi.PoiManager;
import java.util.Optional;
import net.minecraft.network.protocol.game.DebugPackets;
import java.util.Objects;
import net.minecraft.world.entity.ai.village.poi.PoiType;
import it.unimi.dsi.fastutil.longs.LongSets;
import net.minecraft.world.level.ForcedChunksSavedData;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.util.Unit;
import net.minecraft.world.level.saveddata.maps.MapIndex;
import net.minecraft.world.level.saveddata.SavedData;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import net.minecraft.world.level.storage.DimensionDataStorage;
import net.minecraft.tags.TagManager;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.core.Position;
import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import javax.annotation.Nonnull;
import net.minecraft.network.protocol.game.ClientboundBlockEventPacket;
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket;
import net.minecraft.network.protocol.game.ClientboundSoundPacket;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket;
import net.minecraft.network.protocol.game.ClientboundAddGlobalEntityPacket;
import net.minecraft.util.ClassInstanceMultiMap;
import net.minecraft.Util;
import net.minecraft.world.level.block.entity.BlockEntity;
import java.util.Collection;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import java.util.function.BiFunction;
import net.minecraft.world.entity.Mob;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.minecraft.world.entity.MobCategory;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
import java.util.function.Predicate;
import net.minecraft.world.level.LevelConflictException;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.util.ProgressListener;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.ChunkGeneratorSettings;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.tags.BlockTags;
import java.util.Random;
import net.minecraft.world.level.LevelSettings;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.TickNextTickData;
import net.minecraft.server.ServerScoreboard;
import java.util.Iterator;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.entity.global.LightningBolt;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.horse.SkeletonHorse;
import net.minecraft.world.level.chunk.LevelChunk;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import net.minecraft.world.entity.LivingEntity;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import net.minecraft.world.entity.boss.EnderDragonPart;
import net.minecraft.world.entity.npc.Npc;
import net.minecraft.world.entity.animal.WaterAnimal;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.level.LevelType;
import net.minecraft.world.Difficulty;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.util.Mth;
import net.minecraft.world.level.GameRules;
import java.util.function.BooleanSupplier;
import net.minecraft.world.level.biome.Biome;
import com.google.common.collect.Sets;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.core.Registry;
import com.google.common.collect.Queues;
import com.google.common.collect.Maps;
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
import com.google.common.collect.Lists;
import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.storage.LevelData;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;
import net.minecraft.world.entity.npc.WanderingTraderSpawner;
import net.minecraft.world.level.BlockEventData;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import net.minecraft.world.entity.raid.Raids;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import java.util.Set;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.ServerTickList;
import net.minecraft.world.level.PortalForcer;
import net.minecraft.world.level.storage.LevelStorage;
import net.minecraft.server.MinecraftServer;
import java.util.Queue;
import java.util.UUID;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.world.entity.Entity;
import java.util.List;
import org.apache.logging.log4j.Logger;
import net.minecraft.world.level.Level;
public class ServerLevel extends Level {
private static final Logger LOGGER;
private final List<Entity> globalEntities;
private final Int2ObjectMap<Entity> entitiesById;
private final Map<UUID, Entity> entitiesByUuid;
private final Queue<Entity> toAddAfterTick;
private final List<ServerPlayer> players;
boolean tickingEntities;
private final MinecraftServer server;
private final LevelStorage levelStorage;
public boolean noSave;
private boolean allPlayersSleeping;
private int emptyTime;
private final PortalForcer portalForcer;
private final ServerTickList<Block> blockTicks;
private final ServerTickList<Fluid> liquidTicks;
private final Set<PathNavigation> navigations;
protected final Raids raids;
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents;
private boolean handlingTick;
@Nullable
private final WanderingTraderSpawner wanderingTraderSpawner;
public ServerLevel(final MinecraftServer minecraftServer, final Executor executor, final LevelStorage crk, final LevelData crj, final DimensionType cbf, final ProfilerFiller aim, final ChunkProgressListener xm) {
super(crj, cbf, (bjt, cbe) -> new ServerChunkCache(bjt, crk.getFolder(), crk.getFixerUpper(), crk.getStructureManager(), executor, cbe.createRandomLevelGenerator(), minecraftServer.getPlayerList().getViewDistance(), xm, () -> minecraftServer.getLevel(DimensionType.OVERWORLD).getDataStorage()), aim, false);
this.globalEntities = Lists.newArrayList();
this.entitiesById = (Int2ObjectMap<Entity>)new Int2ObjectLinkedOpenHashMap();
this.entitiesByUuid = Maps.newHashMap();
this.toAddAfterTick = Queues.newArrayDeque();
this.players = Lists.newArrayList();
this.blockTicks = new ServerTickList<Block>(this, bpe -> bpe == null || bpe.defaultBlockState().isAir(), Registry.BLOCK::getKey, Registry.BLOCK::get, this::tickBlock);
this.liquidTicks = new ServerTickList<Fluid>(this, cof -> cof == null || cof == Fluids.EMPTY, Registry.FLUID::getKey, Registry.FLUID::get, this::tickLiquid);
this.navigations = Sets.newHashSet();
this.blockEvents = (ObjectLinkedOpenHashSet<BlockEventData>)new ObjectLinkedOpenHashSet();
this.levelStorage = crk;
this.server = minecraftServer;
this.portalForcer = new PortalForcer(this);
this.updateSkyBrightness();
this.prepareWeather();
this.getWorldBorder().setAbsoluteMaxSize(minecraftServer.getAbsoluteMaxWorldSize());
this.raids = this.getDataStorage().<Raids>computeIfAbsent(() -> new Raids(this), Raids.getFileId(this.dimension));
if (!minecraftServer.isSingleplayer()) {
this.getLevelData().setGameType(minecraftServer.getDefaultGameType());
}
this.wanderingTraderSpawner = ((this.dimension.getType() == DimensionType.OVERWORLD) ? new WanderingTraderSpawner(this) : null);
}
@Override
public Biome getUncachedNoiseBiome(final int integer1, final int integer2, final int integer3) {
return this.getChunkSource().getGenerator().getBiomeSource().getNoiseBiome(integer1, integer2, integer3);
}
public void tick(final BooleanSupplier booleanSupplier) {
final ProfilerFiller aim3 = this.getProfiler();
this.handlingTick = true;
aim3.push("world border");
this.getWorldBorder().tick();
aim3.popPush("weather");
final boolean boolean4 = this.isRaining();
if (this.dimension.isHasSkyLight()) {
if (this.getGameRules().getBoolean(GameRules.RULE_WEATHER_CYCLE)) {
int integer5 = this.levelData.getClearWeatherTime();
int integer6 = this.levelData.getThunderTime();
int integer7 = this.levelData.getRainTime();
boolean boolean5 = this.levelData.isThundering();
boolean boolean6 = this.levelData.isRaining();
if (integer5 > 0) {
--integer5;
integer6 = (boolean5 ? 0 : 1);
integer7 = (boolean6 ? 0 : 1);
boolean5 = false;
boolean6 = false;
}
else {
if (integer6 > 0) {
if (--integer6 == 0) {
boolean5 = !boolean5;
}
}
else if (boolean5) {
integer6 = this.random.nextInt(12000) + 3600;
}
else {
integer6 = this.random.nextInt(168000) + 12000;
}
if (integer7 > 0) {
if (--integer7 == 0) {
boolean6 = !boolean6;
}
}
else if (boolean6) {
integer7 = this.random.nextInt(12000) + 12000;
}
else {
integer7 = this.random.nextInt(168000) + 12000;
}
}
this.levelData.setThunderTime(integer6);
this.levelData.setRainTime(integer7);
this.levelData.setClearWeatherTime(integer5);
this.levelData.setThundering(boolean5);
this.levelData.setRaining(boolean6);
}
this.oThunderLevel = this.thunderLevel;
if (this.levelData.isThundering()) {
this.thunderLevel += (float)0.01;
}
else {
this.thunderLevel -= (float)0.01;
}
this.thunderLevel = Mth.clamp(this.thunderLevel, 0.0f, 1.0f);
this.oRainLevel = this.rainLevel;
if (this.levelData.isRaining()) {
this.rainLevel += (float)0.01;
}
else {
this.rainLevel -= (float)0.01;
}
this.rainLevel = Mth.clamp(this.rainLevel, 0.0f, 1.0f);
}
if (this.oRainLevel != this.rainLevel) {
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(7, this.rainLevel), this.dimension.getType());
}
if (this.oThunderLevel != this.thunderLevel) {
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(8, this.thunderLevel), this.dimension.getType());
}
if (boolean4 != this.isRaining()) {
if (boolean4) {
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(2, 0.0f));
}
else {
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(1, 0.0f));
}
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(7, this.rainLevel));
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(8, this.thunderLevel));
}
if (this.getLevelData().isHardcore() && this.getDifficulty() != Difficulty.HARD) {
this.getLevelData().setDifficulty(Difficulty.HARD);
}
if (this.allPlayersSleeping && this.players.stream().noneMatch(xe -> !xe.isSpectator() && !xe.isSleepingLongEnough())) {
this.allPlayersSleeping = false;
if (this.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) {
final long long5 = this.levelData.getDayTime() + 24000L;
this.setDayTime(long5 - long5 % 24000L);
}
this.wakeUpAllPlayers();
if (this.getGameRules().getBoolean(GameRules.RULE_WEATHER_CYCLE)) {
this.stopWeather();
}
}
this.updateSkyBrightness();
this.tickTime();
aim3.popPush("chunkSource");
this.getChunkSource().tick(booleanSupplier);
aim3.popPush("tickPending");
if (this.levelData.getGeneratorType() != LevelType.DEBUG_ALL_BLOCK_STATES) {
this.blockTicks.tick();
this.liquidTicks.tick();
}
aim3.popPush("raid");
this.raids.tick();
if (this.wanderingTraderSpawner != null) {
this.wanderingTraderSpawner.tick();
}
aim3.popPush("blockEvents");
this.runBlockEvents();
this.handlingTick = false;
aim3.popPush("entities");
final boolean boolean7 = !this.players.isEmpty() || !this.getForcedChunks().isEmpty();
if (boolean7) {
this.resetEmptyTime();
}
if (boolean7 || this.emptyTime++ < 300) {
this.dimension.tick();
aim3.push("global");
for (int integer6 = 0; integer6 < this.globalEntities.size(); ++integer6) {
final Entity akn2 = this.globalEntities.get(integer6);
this.guardEntityTick(akn -> {
++akn.tickCount;
akn.tick();
return;
}, akn2);
if (akn2.removed) {
this.globalEntities.remove(integer6--);
}
}
aim3.popPush("regular");
this.tickingEntities = true;
final ObjectIterator<Int2ObjectMap.Entry<Entity>> objectIterator6 = (ObjectIterator<Int2ObjectMap.Entry<Entity>>)this.entitiesById.int2ObjectEntrySet().iterator();
while (objectIterator6.hasNext()) {
final Int2ObjectMap.Entry<Entity> entry7 = (Int2ObjectMap.Entry<Entity>)objectIterator6.next();
final Entity akn3 = (Entity)entry7.getValue();
final Entity akn4 = akn3.getVehicle();
if (!this.server.isAnimals() && (akn3 instanceof Animal || akn3 instanceof WaterAnimal)) {
akn3.remove();
}
if (!this.server.isNpcsEnabled() && akn3 instanceof Npc) {
akn3.remove();
}
aim3.push("checkDespawn");
if (!akn3.removed) {
akn3.checkDespawn();
}
aim3.pop();
if (akn4 != null) {
if (!akn4.removed && akn4.hasPassenger(akn3)) {
continue;
}
akn3.stopRiding();
}
aim3.push("tick");
if (!akn3.removed && !(akn3 instanceof EnderDragonPart)) {
this.guardEntityTick(this::tickNonPassenger, akn3);
}
aim3.pop();
aim3.push("remove");
if (akn3.removed) {
this.removeFromChunk(akn3);
objectIterator6.remove();
this.onEntityRemoved(akn3);
}
aim3.pop();
}
this.tickingEntities = false;
Entity akn2;
while ((akn2 = this.toAddAfterTick.poll()) != null) {
this.add(akn2);
}
aim3.pop();
this.tickBlockEntities();
}
aim3.pop();
}
private void wakeUpAllPlayers() {
this.players.stream().filter(LivingEntity::isSleeping).collect(Collectors.toList()).forEach(xe -> xe.stopSleepInBed(false, false));
}
public void tickChunk(final LevelChunk cai, final int integer) {
final ChunkPos bje4 = cai.getPos();
final boolean boolean5 = this.isRaining();
final int integer2 = bje4.getMinBlockX();
final int integer3 = bje4.getMinBlockZ();
final ProfilerFiller aim8 = this.getProfiler();
aim8.push("thunder");
if (boolean5 && this.isThundering() && this.random.nextInt(100000) == 0) {
final BlockPos fk9 = this.findLightingTargetAround(this.getBlockRandomPos(integer2, 0, integer3, 15));
if (this.isRainingAt(fk9)) {
final DifficultyInstance ajg10 = this.getCurrentDifficultyAt(fk9);
final boolean boolean6 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < ajg10.getEffectiveDifficulty() * 0.01;
if (boolean6) {
final SkeletonHorse aug12 = EntityType.SKELETON_HORSE.create(this);
aug12.setTrap(true);
aug12.setAge(0);
aug12.setPos(fk9.getX(), fk9.getY(), fk9.getZ());
this.addFreshEntity(aug12);
}
this.addGlobalEntity(new LightningBolt(this, fk9.getX() + 0.5, fk9.getY(), fk9.getZ() + 0.5, boolean6));
}
}
aim8.popPush("iceandsnow");
if (this.random.nextInt(16) == 0) {
final BlockPos fk9 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.getBlockRandomPos(integer2, 0, integer3, 15));
final BlockPos fk10 = fk9.below();
final Biome bkq11 = this.getBiome(fk9);
if (bkq11.shouldFreeze(this, fk10)) {
this.setBlockAndUpdate(fk10, Blocks.ICE.defaultBlockState());
}
if (boolean5 && bkq11.shouldSnow(this, fk9)) {
this.setBlockAndUpdate(fk9, Blocks.SNOW.defaultBlockState());
}
if (boolean5 && this.getBiome(fk10).getPrecipitation() == Biome.Precipitation.RAIN) {
this.getBlockState(fk10).getBlock().handleRain(this, fk10);
}
}
aim8.popPush("tickBlocks");
if (integer > 0) {
for (final LevelChunkSection caj12 : cai.getSections()) {
if (caj12 != LevelChunk.EMPTY_SECTION && caj12.isRandomlyTicking()) {
final int integer4 = caj12.bottomBlockY();
for (int integer5 = 0; integer5 < integer; ++integer5) {
final BlockPos fk11 = this.getBlockRandomPos(integer2, integer4, integer3, 15);
aim8.push("randomTick");
final BlockState byg16 = caj12.getBlockState(fk11.getX() - integer2, fk11.getY() - integer4, fk11.getZ() - integer3);
if (byg16.isRandomlyTicking()) {
byg16.randomTick(this, fk11, this.random);
}
final FluidState cog17 = byg16.getFluidState();
if (cog17.isRandomlyTicking()) {
cog17.randomTick(this, fk11, this.random);
}
aim8.pop();
}
}
}
}
aim8.pop();
}
protected BlockPos findLightingTargetAround(final BlockPos fk) {
BlockPos fk2 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, fk);
final AABB cvc4 = new AABB(fk2, new BlockPos(fk2.getX(), this.getMaxBuildHeight(), fk2.getZ())).inflate(3.0);
final List<LivingEntity> list5 = this.<LivingEntity>getEntitiesOfClass(LivingEntity.class, cvc4, akw -> akw != null && akw.isAlive() && this.canSeeSky(akw.getCommandSenderBlockPosition()));
if (!list5.isEmpty()) {
return list5.get(this.random.nextInt(list5.size())).getCommandSenderBlockPosition();
}
if (fk2.getY() == -1) {
fk2 = fk2.above(2);
}
return fk2;
}
public boolean isHandlingTick() {
return this.handlingTick;
}
public void updateSleepingPlayerList() {
this.allPlayersSleeping = false;
if (!this.players.isEmpty()) {
int integer2 = 0;
int integer3 = 0;
for (final ServerPlayer xe5 : this.players) {
if (xe5.isSpectator()) {
++integer2;
}
else {
if (!xe5.isSleeping()) {
continue;
}
++integer3;
}
}
this.allPlayersSleeping = (integer3 > 0 && integer3 >= this.players.size() - integer2);
}
}
@Override
public ServerScoreboard getScoreboard() {
return this.server.getScoreboard();
}
private void stopWeather() {
this.levelData.setRainTime(0);
this.levelData.setRaining(false);
this.levelData.setThunderTime(0);
this.levelData.setThundering(false);
}
@Override
public void validateSpawn() {
if (this.levelData.getYSpawn() <= 0) {
this.levelData.setYSpawn(this.getSeaLevel() + 1);
}
int integer2 = this.levelData.getXSpawn();
int integer3 = this.levelData.getZSpawn();
int integer4 = 0;
while (this.getTopBlockState(new BlockPos(integer2, 0, integer3)).isAir()) {
integer2 += this.random.nextInt(8) - this.random.nextInt(8);
integer3 += this.random.nextInt(8) - this.random.nextInt(8);
if (++integer4 == 10000) {
break;
}
}
this.levelData.setXSpawn(integer2);
this.levelData.setZSpawn(integer3);
}
public void resetEmptyTime() {
this.emptyTime = 0;
}
private void tickLiquid(final TickNextTickData<Fluid> bkj) {
final FluidState cog3 = this.getFluidState(bkj.pos);
if (cog3.getType() == bkj.getType()) {
cog3.tick(this, bkj.pos);
}
}
private void tickBlock(final TickNextTickData<Block> bkj) {
final BlockState byg3 = this.getBlockState(bkj.pos);
if (byg3.getBlock() == bkj.getType()) {
byg3.tick(this, bkj.pos, this.random);
}
}
public void tickNonPassenger(final Entity akn) {
if (!(akn instanceof Player) && !this.getChunkSource().isEntityTickingChunk(akn)) {
return;
}
akn.setPosAndOldPos(akn.getX(), akn.getY(), akn.getZ());
akn.yRotO = akn.yRot;
akn.xRotO = akn.xRot;
if (akn.inChunk) {
++akn.tickCount;
this.getProfiler().push(() -> Registry.ENTITY_TYPE.getKey(akn.getType()).toString());
akn.tick();
this.getProfiler().pop();
}
this.updateChunkPos(akn);
if (akn.inChunk) {
for (final Entity akn2 : akn.getPassengers()) {
this.tickPassenger(akn, akn2);
}
}
}
public void tickPassenger(final Entity akn1, final Entity akn2) {
if (akn2.removed || akn2.getVehicle() != akn1) {
akn2.stopRiding();
return;
}
if (!(akn2 instanceof Player) && !this.getChunkSource().isEntityTickingChunk(akn2)) {
return;
}
akn2.setPosAndOldPos(akn2.getX(), akn2.getY(), akn2.getZ());
akn2.yRotO = akn2.yRot;
akn2.xRotO = akn2.xRot;
if (akn2.inChunk) {
++akn2.tickCount;
akn2.rideTick();
}
this.updateChunkPos(akn2);
if (akn2.inChunk) {
for (final Entity akn3 : akn2.getPassengers()) {
this.tickPassenger(akn2, akn3);
}
}
}
public void updateChunkPos(final Entity akn) {
this.getProfiler().push("chunkCheck");
final int integer3 = Mth.floor(akn.getX() / 16.0);
final int integer4 = Mth.floor(akn.getY() / 16.0);
final int integer5 = Mth.floor(akn.getZ() / 16.0);
if (!akn.inChunk || akn.xChunk != integer3 || akn.yChunk != integer4 || akn.zChunk != integer5) {
if (akn.inChunk && this.hasChunk(akn.xChunk, akn.zChunk)) {
this.getChunk(akn.xChunk, akn.zChunk).removeEntity(akn, akn.yChunk);
}
if (akn.checkAndResetTeleportedFlag() || this.hasChunk(integer3, integer5)) {
this.getChunk(integer3, integer5).addEntity(akn);
}
else {
akn.inChunk = false;
}
}
this.getProfiler().pop();
}
@Override
public boolean mayInteract(final Player ayg, final BlockPos fk) {
return !this.server.isUnderSpawnProtection(this, fk, ayg) && this.getWorldBorder().isWithinBounds(fk);
}
public void setInitialSpawn(final LevelSettings bjx) {
if (!this.dimension.mayRespawn()) {
this.levelData.setSpawn(BlockPos.ZERO.above(this.getChunkSource().getGenerator().getSpawnHeight()));
return;
}
if (this.levelData.getGeneratorType() == LevelType.DEBUG_ALL_BLOCK_STATES) {
this.levelData.setSpawn(BlockPos.ZERO.above());
return;
}
final BiomeSource bkt3 = this.getChunkSource().getGenerator().getBiomeSource();
final List<Biome> list4 = bkt3.getPlayerSpawnBiomes();
final Random random5 = new Random(this.getSeed());
final BlockPos fk6 = bkt3.findBiomeHorizontal(0, this.getSeaLevel(), 0, 256, list4, random5);
final ChunkPos bje7 = (fk6 == null) ? new ChunkPos(0, 0) : new ChunkPos(fk6);
if (fk6 == null) {
ServerLevel.LOGGER.warn("Unable to find spawn biome");
}
boolean boolean8 = false;
for (final Block bpe10 : BlockTags.VALID_SPAWN.getValues()) {
if (bkt3.getSurfaceBlocks().contains(bpe10.defaultBlockState())) {
boolean8 = true;
break;
}
}
this.levelData.setSpawn(bje7.getWorldPosition().offset(8, this.getChunkSource().getGenerator().getSpawnHeight(), 8));
int integer9 = 0;
int integer10 = 0;
int integer11 = 0;
int integer12 = -1;
final int integer13 = 32;
for (int integer14 = 0; integer14 < 1024; ++integer14) {
if (integer9 > -16 && integer9 <= 16 && integer10 > -16 && integer10 <= 16) {
final BlockPos fk7 = this.dimension.getSpawnPosInChunk(new ChunkPos(bje7.x + integer9, bje7.z + integer10), boolean8);
if (fk7 != null) {
this.levelData.setSpawn(fk7);
break;
}
}
if (integer9 == integer10 || (integer9 < 0 && integer9 == -integer10) || (integer9 > 0 && integer9 == 1 - integer10)) {
final int integer15 = integer11;
integer11 = -integer12;
integer12 = integer15;
}
integer9 += integer11;
integer10 += integer12;
}
if (bjx.hasStartingBonusItems()) {
this.generateBonusItemsNearSpawn();
}
}
protected void generateBonusItemsNearSpawn() {
final ConfiguredFeature<?, ?> ccz2 = Feature.BONUS_CHEST.configured(FeatureConfiguration.NONE);
ccz2.place(this, this.getChunkSource().getGenerator(), this.random, new BlockPos(this.levelData.getXSpawn(), this.levelData.getYSpawn(), this.levelData.getZSpawn()));
}
@Nullable
public BlockPos getDimensionSpecificSpawn() {
return this.dimension.getDimensionSpecificSpawn();
}
public void save(@Nullable final ProgressListener abs, final boolean boolean2, final boolean boolean3) throws LevelConflictException {
final ServerChunkCache xb5 = this.getChunkSource();
if (boolean3) {
return;
}
if (abs != null) {
abs.progressStartNoAbort(new TranslatableComponent("menu.savingLevel", new Object[0]));
}
this.saveLevelData();
if (abs != null) {
abs.progressStage(new TranslatableComponent("menu.savingChunks", new Object[0]));
}
xb5.save(boolean2);
}
protected void saveLevelData() throws LevelConflictException {
this.checkSession();
this.dimension.saveData();
this.getChunkSource().getDataStorage().save();
}
public List<Entity> getEntities(@Nullable final EntityType<?> akr, final Predicate<? super Entity> predicate) {
final List<Entity> list4 = Lists.newArrayList();
final ServerChunkCache xb5 = this.getChunkSource();
for (final Entity akn7 : this.entitiesById.values()) {
if ((akr == null || akn7.getType() == akr) && xb5.hasChunk(Mth.floor(akn7.getX()) >> 4, Mth.floor(akn7.getZ()) >> 4) && predicate.test(akn7)) {
list4.add(akn7);
}
}
return list4;
}
public List<EnderDragon> getDragons() {
final List<EnderDragon> list2 = Lists.newArrayList();
for (final Entity akn4 : this.entitiesById.values()) {
if (akn4 instanceof EnderDragon && akn4.isAlive()) {
list2.add((EnderDragon)akn4);
}
}
return list2;
}
public List<ServerPlayer> getPlayers(final Predicate<? super ServerPlayer> predicate) {
final List<ServerPlayer> list3 = Lists.newArrayList();
for (final ServerPlayer xe5 : this.players) {
if (predicate.test(xe5)) {
list3.add(xe5);
}
}
return list3;
}
@Nullable
public ServerPlayer getRandomPlayer() {
final List<ServerPlayer> list2 = this.getPlayers(LivingEntity::isAlive);
if (list2.isEmpty()) {
return null;
}
return list2.get(this.random.nextInt(list2.size()));
}
public Object2IntMap<MobCategory> getMobCategoryCounts() {
final Object2IntMap<MobCategory> object2IntMap2 = (Object2IntMap<MobCategory>)new Object2IntOpenHashMap();
for (final Entity akn4 : this.entitiesById.values()) {
if (akn4 instanceof Mob) {
final Mob akx5 = (Mob)akn4;
if (akx5.isPersistenceRequired()) {
continue;
}
if (akx5.requiresCustomPersistence()) {
continue;
}
}
final MobCategory aky5 = akn4.getType().getCategory();
if (aky5 == MobCategory.MISC) {
continue;
}
if (!this.getChunkSource().isInAccessibleChunk(akn4)) {
continue;
}
object2IntMap2.mergeInt(aky5, 1, (BiFunction)Integer::sum);
}
return object2IntMap2;
}
@Override
public boolean addFreshEntity(final Entity akn) {
return this.addEntity(akn);
}
public boolean addWithUUID(final Entity akn) {
return this.addEntity(akn);
}
public void addFromAnotherDimension(final Entity akn) {
final boolean boolean3 = akn.forcedLoading;
akn.forcedLoading = true;
this.addWithUUID(akn);
akn.forcedLoading = boolean3;
this.updateChunkPos(akn);
}
public void addDuringCommandTeleport(final ServerPlayer xe) {
this.addPlayer(xe);
this.updateChunkPos(xe);
}
public void addDuringPortalTeleport(final ServerPlayer xe) {
this.addPlayer(xe);
this.updateChunkPos(xe);
}
public void addNewPlayer(final ServerPlayer xe) {
this.addPlayer(xe);
}
public void addRespawnedPlayer(final ServerPlayer xe) {
this.addPlayer(xe);
}
private void addPlayer(final ServerPlayer xe) {
final Entity akn3 = this.entitiesByUuid.get(xe.getUUID());
if (akn3 != null) {
ServerLevel.LOGGER.warn("Force-added player with duplicate UUID {}", xe.getUUID().toString());
akn3.unRide();
this.removePlayerImmediately((ServerPlayer)akn3);
}
this.players.add(xe);
this.updateSleepingPlayerList();
final ChunkAccess bzv4 = this.getChunk(Mth.floor(xe.getX() / 16.0), Mth.floor(xe.getZ() / 16.0), ChunkStatus.FULL, true);
if (bzv4 instanceof LevelChunk) {
bzv4.addEntity(xe);
}
this.add(xe);
}
private boolean addEntity(final Entity akn) {
if (akn.removed) {
ServerLevel.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityType.getKey(akn.getType()));
return false;
}
if (this.isUUIDUsed(akn)) {
return false;
}
final ChunkAccess bzv3 = this.getChunk(Mth.floor(akn.getX() / 16.0), Mth.floor(akn.getZ() / 16.0), ChunkStatus.FULL, akn.forcedLoading);
if (!(bzv3 instanceof LevelChunk)) {
return false;
}
bzv3.addEntity(akn);
this.add(akn);
return true;
}
public boolean loadFromChunk(final Entity akn) {
if (this.isUUIDUsed(akn)) {
return false;
}
this.add(akn);
return true;
}
private boolean isUUIDUsed(final Entity akn) {
final Entity akn2 = this.entitiesByUuid.get(akn.getUUID());
if (akn2 == null) {
return false;
}
ServerLevel.LOGGER.warn("Keeping entity {} that already exists with UUID {}", EntityType.getKey(akn2.getType()), akn.getUUID().toString());
return true;
}
public void unload(final LevelChunk cai) {
this.blockEntitiesToUnload.addAll(cai.getBlockEntities().values());
for (final ClassInstanceMultiMap<Entity> abe6 : cai.getEntitySections()) {
for (final Entity akn8 : abe6) {
if (akn8 instanceof ServerPlayer) {
continue;
}
if (this.tickingEntities) {
throw Util.<IllegalStateException>pauseInIde(new IllegalStateException("Removing entity while ticking!"));
}
this.entitiesById.remove(akn8.getId());
this.onEntityRemoved(akn8);
}
}
}
public void onEntityRemoved(final Entity akn) {
if (akn instanceof EnderDragon) {
for (final EnderDragonPart aun6 : ((EnderDragon)akn).getSubEntities()) {
aun6.remove();
}
}
this.entitiesByUuid.remove(akn.getUUID());
this.getChunkSource().removeEntity(akn);
if (akn instanceof ServerPlayer) {
final ServerPlayer xe3 = (ServerPlayer)akn;
this.players.remove(xe3);
}
this.getScoreboard().entityRemoved(akn);
if (akn instanceof Mob) {
this.navigations.remove(((Mob)akn).getNavigation());
}
}
private void add(final Entity akn) {
if (this.tickingEntities) {
this.toAddAfterTick.add(akn);
}
else {
this.entitiesById.put(akn.getId(), akn);
if (akn instanceof EnderDragon) {
for (final EnderDragonPart aun6 : ((EnderDragon)akn).getSubEntities()) {
this.entitiesById.put(aun6.getId(), aun6);
}
}
this.entitiesByUuid.put(akn.getUUID(), akn);
this.getChunkSource().addEntity(akn);
if (akn instanceof Mob) {
this.navigations.add(((Mob)akn).getNavigation());
}
}
}
public void despawn(final Entity akn) {
if (this.tickingEntities) {
throw Util.<IllegalStateException>pauseInIde(new IllegalStateException("Removing entity while ticking!"));
}
this.removeFromChunk(akn);
this.entitiesById.remove(akn.getId());
this.onEntityRemoved(akn);
}
private void removeFromChunk(final Entity akn) {
final ChunkAccess bzv3 = this.getChunk(akn.xChunk, akn.zChunk, ChunkStatus.FULL, false);
if (bzv3 instanceof LevelChunk) {
((LevelChunk)bzv3).removeEntity(akn);
}
}
public void removePlayerImmediately(final ServerPlayer xe) {
xe.remove();
this.despawn(xe);
this.updateSleepingPlayerList();
}
public void addGlobalEntity(final LightningBolt avv) {
this.globalEntities.add(avv);
this.server.getPlayerList().broadcast(null, avv.getX(), avv.getY(), avv.getZ(), 512.0, this.dimension.getType(), new ClientboundAddGlobalEntityPacket(avv));
}
@Override
public void destroyBlockProgress(final int integer1, final BlockPos fk, final int integer3) {
for (final ServerPlayer xe6 : this.server.getPlayerList().getPlayers()) {
if (xe6 != null && xe6.level == this) {
if (xe6.getId() == integer1) {
continue;
}
final double double7 = fk.getX() - xe6.getX();
final double double8 = fk.getY() - xe6.getY();
final double double9 = fk.getZ() - xe6.getZ();
if (double7 * double7 + double8 * double8 + double9 * double9 >= 1024.0) {
continue;
}
xe6.connection.send(new ClientboundBlockDestructionPacket(integer1, fk, integer3));
}
}
}
@Override
public void playSound(@Nullable final Player ayg, final double double2, final double double3, final double double4, final SoundEvent aah, final SoundSource aaj, final float float7, final float float8) {
this.server.getPlayerList().broadcast(ayg, double2, double3, double4, (float7 > 1.0f) ? ((double)(16.0f * float7)) : 16.0, this.dimension.getType(), new ClientboundSoundPacket(aah, aaj, double2, double3, double4, float7, float8));
}
@Override
public void playSound(@Nullable final Player ayg, final Entity akn, final SoundEvent aah, final SoundSource aaj, final float float5, final float float6) {
this.server.getPlayerList().broadcast(ayg, akn.getX(), akn.getY(), akn.getZ(), (float5 > 1.0f) ? ((double)(16.0f * float5)) : 16.0, this.dimension.getType(), new ClientboundSoundEntityPacket(aah, aaj, akn, float5, float6));
}
@Override
public void globalLevelEvent(final int integer1, final BlockPos fk, final int integer3) {
this.server.getPlayerList().broadcastAll(new ClientboundLevelEventPacket(integer1, fk, integer3, true));
}
@Override
public void levelEvent(@Nullable final Player ayg, final int integer2, final BlockPos fk, final int integer4) {
this.server.getPlayerList().broadcast(ayg, fk.getX(), fk.getY(), fk.getZ(), 64.0, this.dimension.getType(), new ClientboundLevelEventPacket(integer2, fk, integer4, false));
}
@Override
public void sendBlockUpdated(final BlockPos fk, final BlockState byg2, final BlockState byg3, final int integer) {
this.getChunkSource().blockChanged(fk);
final VoxelShape cwc6 = byg2.getCollisionShape(this, fk);
final VoxelShape cwc7 = byg3.getCollisionShape(this, fk);
if (!Shapes.joinIsNotEmpty(cwc6, cwc7, BooleanOp.NOT_SAME)) {
return;
}
for (final PathNavigation aro9 : this.navigations) {
if (aro9.hasDelayedRecomputation()) {
continue;
}
aro9.recomputePath(fk);
}
}
@Override
public void broadcastEntityEvent(final Entity akn, final byte byte2) {
this.getChunkSource().broadcastAndSend(akn, new ClientboundEntityEventPacket(akn, byte2));
}
@Override
public ServerChunkCache getChunkSource() {
return (ServerChunkCache)super.getChunkSource();
}
@Override
public Explosion explode(@Nullable final Entity akn, @Nullable final DamageSource ajw, final double double3, final double double4, final double double5, final float float6, final boolean boolean7, final Explosion.BlockInteraction a) {
final Explosion bjm13 = new Explosion(this, akn, double3, double4, double5, float6, boolean7, a);
if (ajw != null) {
bjm13.setDamageSource(ajw);
}
bjm13.explode();
bjm13.finalizeExplosion(false);
if (a == Explosion.BlockInteraction.NONE) {
bjm13.clearToBlow();
}
for (final ServerPlayer xe15 : this.players) {
if (xe15.distanceToSqr(double3, double4, double5) < 4096.0) {
xe15.connection.send(new ClientboundExplodePacket(double3, double4, double5, float6, bjm13.getToBlow(), bjm13.getHitPlayers().get(xe15)));
}
}
return bjm13;
}
@Override
public void blockEvent(final BlockPos fk, final Block bpe, final int integer3, final int integer4) {
this.blockEvents.add(new BlockEventData(fk, bpe, integer3, integer4));
}
private void runBlockEvents() {
while (!this.blockEvents.isEmpty()) {
final BlockEventData bjc2 = (BlockEventData)this.blockEvents.removeFirst();
if (this.doBlockEvent(bjc2)) {
this.server.getPlayerList().broadcast(null, bjc2.getPos().getX(), bjc2.getPos().getY(), bjc2.getPos().getZ(), 64.0, this.dimension.getType(), new ClientboundBlockEventPacket(bjc2.getPos(), bjc2.getBlock(), bjc2.getParamA(), bjc2.getParamB()));
}
}
}
private boolean doBlockEvent(final BlockEventData bjc) {
final BlockState byg3 = this.getBlockState(bjc.getPos());
return byg3.getBlock() == bjc.getBlock() && byg3.triggerEvent(this, bjc.getPos(), bjc.getParamA(), bjc.getParamB());
}
@Override
public ServerTickList<Block> getBlockTicks() {
return this.blockTicks;
}
@Override
public ServerTickList<Fluid> getLiquidTicks() {
return this.liquidTicks;
}
@Nonnull
@Override
public MinecraftServer getServer() {
return this.server;
}
public PortalForcer getPortalForcer() {
return this.portalForcer;
}
public StructureManager getStructureManager() {
return this.levelStorage.getStructureManager();
}
public <T extends ParticleOptions> int sendParticles(final T gt, final double double2, final double double3, final double double4, final int integer, final double double6, final double double7, final double double8, final double double9) {
final ClientboundLevelParticlesPacket nh18 = new ClientboundLevelParticlesPacket((T)gt, false, double2, double3, double4, (float)double6, (float)double7, (float)double8, (float)double9, integer);
int integer2 = 0;
for (int integer3 = 0; integer3 < this.players.size(); ++integer3) {
final ServerPlayer xe21 = this.players.get(integer3);
if (this.sendParticles(xe21, false, double2, double3, double4, nh18)) {
++integer2;
}
}
return integer2;
}
public <T extends ParticleOptions> boolean sendParticles(final ServerPlayer xe, final T gt, final boolean boolean3, final double double4, final double double5, final double double6, final int integer, final double double8, final double double9, final double double10, final double double11) {
final Packet<?> lt20 = new ClientboundLevelParticlesPacket((T)gt, boolean3, double4, double5, double6, (float)double8, (float)double9, (float)double10, (float)double11, integer);
return this.sendParticles(xe, boolean3, double4, double5, double6, lt20);
}
private boolean sendParticles(final ServerPlayer xe, final boolean boolean2, final double double3, final double double4, final double double5, final Packet<?> lt) {
if (xe.getLevel() != this) {
return false;
}
final BlockPos fk11 = xe.getCommandSenderBlockPosition();
if (fk11.closerThan(new Vec3(double3, double4, double5), boolean2 ? 512.0 : 32.0)) {
xe.connection.send(lt);
return true;
}
return false;
}
@Nullable
@Override
public Entity getEntity(final int integer) {
return (Entity)this.entitiesById.get(integer);
}
@Nullable
public Entity getEntity(final UUID uUID) {
return this.entitiesByUuid.get(uUID);
}
@Nullable
public BlockPos findNearestMapFeature(final String string, final BlockPos fk, final int integer, final boolean boolean4) {
return this.getChunkSource().getGenerator().findNearestMapFeature(this, string, fk, integer, boolean4);
}
@Override
public RecipeManager getRecipeManager() {
return this.server.getRecipeManager();
}
@Override
public TagManager getTagManager() {
return this.server.getTags();
}
@Override
public void setGameTime(final long long1) {
super.setGameTime(long1);
this.levelData.getScheduledEvents().tick(this.server, long1);
}
@Override
public boolean noSave() {
return this.noSave;
}
public void checkSession() throws LevelConflictException {
this.levelStorage.checkSession();
}
public LevelStorage getLevelStorage() {
return this.levelStorage;
}
public DimensionDataStorage getDataStorage() {
return this.getChunkSource().getDataStorage();
}
@Nullable
@Override
public MapItemSavedData getMapData(final String string) {
return this.getServer().getLevel(DimensionType.OVERWORLD).getDataStorage().<MapItemSavedData>get(() -> new MapItemSavedData(string), string);
}
@Override
public void setMapData(final MapItemSavedData crd) {
this.getServer().getLevel(DimensionType.OVERWORLD).getDataStorage().set(crd);
}
@Override
public int getFreeMapId() {
return this.getServer().getLevel(DimensionType.OVERWORLD).getDataStorage().<MapIndex>computeIfAbsent(MapIndex::new, "idcounts").getFreeAuxValueForMap();
}
@Override
public void setSpawnPos(final BlockPos fk) {
final ChunkPos bje3 = new ChunkPos(new BlockPos(this.levelData.getXSpawn(), 0, this.levelData.getZSpawn()));
super.setSpawnPos(fk);
this.getChunkSource().<Unit>removeRegionTicket(TicketType.START, bje3, 11, Unit.INSTANCE);
this.getChunkSource().<Unit>addRegionTicket(TicketType.START, new ChunkPos(fk), 11, Unit.INSTANCE);
}
public LongSet getForcedChunks() {
final ForcedChunksSavedData bjo2 = this.getDataStorage().<ForcedChunksSavedData>get(ForcedChunksSavedData::new, "chunks");
return (LongSet)((bjo2 != null) ? LongSets.unmodifiable(bjo2.getChunks()) : LongSets.EMPTY_SET);
}
public boolean setChunkForced(final int integer1, final int integer2, final boolean boolean3) {
final ForcedChunksSavedData bjo5 = this.getDataStorage().<ForcedChunksSavedData>computeIfAbsent(ForcedChunksSavedData::new, "chunks");
final ChunkPos bje6 = new ChunkPos(integer1, integer2);
final long long7 = bje6.toLong();
boolean boolean4;
if (boolean3) {
boolean4 = bjo5.getChunks().add(long7);
if (boolean4) {
this.getChunk(integer1, integer2);
}
}
else {
boolean4 = bjo5.getChunks().remove(long7);
}
bjo5.setDirty(boolean4);
if (boolean4) {
this.getChunkSource().updateChunkForced(bje6, boolean3);
}
return boolean4;
}
@Override
public List<ServerPlayer> players() {
return this.players;
}
@Override
public void onBlockStateChange(final BlockPos fk, final BlockState byg2, final BlockState byg3) {
final Optional<PoiType> optional5 = PoiType.forState(byg2);
final Optional<PoiType> optional6 = PoiType.forState(byg3);
if (Objects.equals(optional5, optional6)) {
return;
}
final BlockPos fk2 = fk.immutable();
final BlockPos blockPos;
optional5.ifPresent(asr -> this.getServer().execute(() -> {
this.getPoiManager().remove(blockPos);
DebugPackets.sendPoiRemovedPacket(this, blockPos);
}));
final BlockPos blockPos2;
optional6.ifPresent(asr -> this.getServer().execute(() -> {
this.getPoiManager().add(blockPos2, asr);
DebugPackets.sendPoiAddedPacket(this, blockPos2);
}));
}
public PoiManager getPoiManager() {
return this.getChunkSource().getPoiManager();
}
public boolean isVillage(final BlockPos fk) {
return this.closeToVillage(fk, 1);
}
public boolean isVillage(final SectionPos gd) {
return this.isVillage(gd.center());
}
public boolean closeToVillage(final BlockPos fk, final int integer) {
return integer <= 6 && this.sectionsToVillage(SectionPos.of(fk)) <= integer;
}
public int sectionsToVillage(final SectionPos gd) {
return this.getPoiManager().sectionsToVillage(gd);
}
public Raids getRaids() {
return this.raids;
}
@Nullable
public Raid getRaidAt(final BlockPos fk) {
return this.raids.getNearbyRaid(fk, 9216);
}
public boolean isRaided(final BlockPos fk) {
return this.getRaidAt(fk) != null;
}
public void onReputationEvent(final ReputationEventType asl, final Entity akn, final ReputationEventHandler ali) {
ali.onReputationEventFrom(asl, akn);
}
public void saveDebugReport(final Path path) throws IOException {
final ChunkMap wp3 = this.getChunkSource().chunkMap;
try (final Writer writer4 = Files.newBufferedWriter(path.resolve("stats.txt"))) {
writer4.write(String.format("spawning_chunks: %d\n", wp3.getDistanceManager().getNaturalSpawnChunkCount()));
for (final Object2IntMap.Entry<MobCategory> entry7 : this.getMobCategoryCounts().object2IntEntrySet()) {
writer4.write(String.format("spawn_count.%s: %d\n", ((MobCategory)entry7.getKey()).getName(), entry7.getIntValue()));
}
writer4.write(String.format("entities: %d\n", this.entitiesById.size()));
writer4.write(String.format("block_entities: %d\n", this.blockEntityList.size()));
writer4.write(String.format("block_ticks: %d\n", this.getBlockTicks().size()));
writer4.write(String.format("fluid_ticks: %d\n", this.getLiquidTicks().size()));
writer4.write("distance_manager: " + wp3.getDistanceManager().getDebugStatus() + "\n");
writer4.write(String.format("pending_tasks: %d\n", this.getChunkSource().getPendingTasksCount()));
}
final CrashReport h4 = new CrashReport("Level dump", new Exception("dummy"));
this.fillReportDetails(h4);
try (final Writer writer5 = Files.newBufferedWriter(path.resolve("example_crash.txt"))) {
writer5.write(h4.getFriendlyReport());
}
final Path path2 = path.resolve("chunks.csv");
try (final Writer writer6 = Files.newBufferedWriter(path2)) {
wp3.dumpChunks(writer6);
}
final Path path3 = path.resolve("entities.csv");
try (final Writer writer7 = Files.newBufferedWriter(path3)) {
dumpEntities(writer7, (Iterable<Entity>)this.entitiesById.values());
}
final Path path4 = path.resolve("global_entities.csv");
try (final Writer writer8 = Files.newBufferedWriter(path4)) {
dumpEntities(writer8, this.globalEntities);
}
final Path path5 = path.resolve("block_entities.csv");
try (final Writer writer9 = Files.newBufferedWriter(path5)) {
this.dumpBlockEntities(writer9);
}
}
private static void dumpEntities(final Writer writer, final Iterable<Entity> iterable) throws IOException {
final CsvOutput abh3 = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("uuid").addColumn("type").addColumn("alive").addColumn("display_name").addColumn("custom_name").build(writer);
for (final Entity akn5 : iterable) {
final Component lf6 = akn5.getCustomName();
final Component lf7 = akn5.getDisplayName();
abh3.writeRow(akn5.getX(), akn5.getY(), akn5.getZ(), akn5.getUUID(), Registry.ENTITY_TYPE.getKey(akn5.getType()), akn5.isAlive(), lf7.getString(), (lf6 != null) ? lf6.getString() : null);
}
}
private void dumpBlockEntities(final Writer writer) throws IOException {
final CsvOutput abh3 = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("type").build(writer);
for (final BlockEntity bwi5 : this.blockEntityList) {
final BlockPos fk6 = bwi5.getBlockPos();
abh3.writeRow(fk6.getX(), fk6.getY(), fk6.getZ(), Registry.BLOCK_ENTITY_TYPE.getKey(bwi5.getType()));
}
}
@VisibleForTesting
public void clearBlockEvents(final BoundingBox cky) {
this.blockEvents.removeIf(bjc -> cky.isInside(bjc.getPos()));
}
static {
LOGGER = LogManager.getLogger();
}
}