GenericBlockBulkUpdater interface
Пакет: com.hypixel.hytale.server.core.universe.world
Файл: com/hypixel/hytale/server/core/universe/world/World.java
Методы (1)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
abstract |
void |
applyvoid apply(World var1, T var2, long var3, WorldChunk var5, int var6, int var7, int var8, int var9, int var10, int var11) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.universe.world;
class="kw">import com.hypixel.hytale.assetstore.AssetRegistry;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.common.plugin.PluginIdentifier;
class="kw">import com.hypixel.hytale.common.util.FormatUtil;
class="kw">import com.hypixel.hytale.component.AddReason;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.component.IResourceStorage;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.data.unknown.UnknownComponents;
class="kw">import com.hypixel.hytale.event.EventRegistry;
class="kw">import com.hypixel.hytale.event.IEventDispatcher;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.logger.sentry.SkipSentryException;
class="kw">import com.hypixel.hytale.math.block.BlockUtil;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.vector.Rotation3f;
class="kw">import com.hypixel.hytale.math.vector.Transform;
class="kw">import com.hypixel.hytale.metrics.ExecutorMetricsRegistry;
class="kw">import com.hypixel.hytale.metrics.metric.HistoricMetric;
class="kw">import com.hypixel.hytale.protocol.packets.entities.SetEntitySeed;
class="kw">import com.hypixel.hytale.protocol.packets.player.JoinWorld;
class="kw">import com.hypixel.hytale.protocol.packets.player.SetClientId;
class="kw">import com.hypixel.hytale.protocol.packets.setup.ClientFeature;
class="kw">import com.hypixel.hytale.protocol.packets.setup.SetTimeDilation;
class="kw">import com.hypixel.hytale.protocol.packets.setup.SetUpdateRate;
class="kw">import com.hypixel.hytale.protocol.packets.setup.UpdateFeatures;
class="kw">import com.hypixel.hytale.protocol.packets.setup.ViewRadius;
class="kw">import com.hypixel.hytale.protocol.packets.world.ClearChunks;
class="kw">import com.hypixel.hytale.protocol.packets.world.ServerSetPaused;
class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.ShutdownReason;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.CombatConfig;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.DeathConfig;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.GameplayConfig;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.MutableDeathConfig;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.PlayerConfig;
class="kw">import com.hypixel.hytale.server.core.blocktype.component.BlockPhysics;
class="kw">import com.hypixel.hytale.server.core.console.ConsoleModule;
class="kw">import com.hypixel.hytale.server.core.entity.Entity;
class="kw">import com.hypixel.hytale.server.core.entity.EntityUtils;
class="kw">import com.hypixel.hytale.server.core.entity.UUIDComponent;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerConfigData;
class="kw">import com.hypixel.hytale.server.core.event.events.player.AddPlayerToWorldEvent;
class="kw">import com.hypixel.hytale.server.core.event.events.player.DrainPlayerFromWorldEvent;
class="kw">import com.hypixel.hytale.server.core.io.PacketHandler;
class="kw">import com.hypixel.hytale.server.core.modules.entity.EntityModule;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.Spectating;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.player.ChunkTracker;
class="kw">import com.hypixel.hytale.server.core.modules.entity.tracker.EntityTrackerSystems;
class="kw">import com.hypixel.hytale.server.core.modules.time.TimeResource;
class="kw">import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.IPrefabBuffer;
class="kw">import com.hypixel.hytale.server.core.receiver.IMessageReceiver;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.universe.world.accessor.ChunkAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.ChunkColumn;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.ChunkFlag;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.EntitySection;
class="kw">import com.hypixel.hytale.server.core.universe.world.events.StartWorldEvent;
class="kw">import com.hypixel.hytale.server.core.universe.world.lighting.ChunkLightingManager;
class="kw">import com.hypixel.hytale.server.core.universe.world.path.WorldPathConfig;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.resources.DiskResourceStorageProvider;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.IWorldGen;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.WorldGenLoadException;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.IWorldMap;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.WorldMapLoadException;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.WorldMapManager;
class="kw">import com.hypixel.hytale.server.core.util.FillerBlockUtil;
class="kw">import com.hypixel.hytale.server.core.util.MessageUtil;
class="kw">import com.hypixel.hytale.server.core.util.io.FileUtil;
class="kw">import com.hypixel.hytale.server.core.util.thread.TickingThread;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.longs.LongListIterator;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import java.awt.Color;
class="kw">import java.io.IOException;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.util.Collection;
class="kw">import java.util.Collections;
class="kw">import java.util.Deque;
class="kw">import java.util.EnumMap;
class="kw">import java.util.EnumSet;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Random;
class="kw">import java.util.UUID;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.CompletionException;
class="kw">import java.util.concurrent.CompletionStage;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.CopyOnWriteArrayList;
class="kw">import java.util.concurrent.Executor;
class="kw">import java.util.concurrent.LinkedBlockingDeque;
class="kw">import java.util.concurrent.ScheduledFuture;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.concurrent.atomic.AtomicBoolean;
class="kw">import java.util.concurrent.atomic.AtomicInteger;
class="kw">import java.util.function.IntUnaryOperator;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">public class World class="kw">extends TickingThread class="kw">implements Executor, ExecutorMetricsRegistry.ExecutorMetric, ChunkAccessor, IWorldChunks, IMessageReceiver {
class="kw">public class="kw">static class="kw">final float SAVE_INTERVAL = 10.0F;
class="kw">public class="kw">static class="kw">final String DEFAULT = "class="kw">default";
@Nonnull
class="kw">public class="kw">static class="kw">final ExecutorMetricsRegistry<World> METRICS_REGISTRY = new ExecutorMetricsRegistry<World>()
.register("Name", var0 -> var0.name, Codec.STRING)
.register("Alive", var0 -> var0.alive.get(), Codec.BOOLEAN)
.register("TickLength", TickingThread::getBufferedTickLengthMetricSet, HistoricMetric.METRICS_CODEC)
.register("EntityStore", World::getEntityStore, EntityStore.METRICS_REGISTRY)
.register("ChunkStore", World::getChunkStore, ChunkStore.METRICS_REGISTRY);
@Nonnull
class="kw">private class="kw">final HytaleLogger logger;
@Nonnull
class="kw">private class="kw">final String name;
@Nonnull
class="kw">private class="kw">final Path savePath;
@Nonnull
class="kw">private class="kw">final WorldConfig worldConfig;
@Nonnull
class="kw">private class="kw">final ChunkStore chunkStore = new ChunkStore(this);
@Nonnull
class="kw">private class="kw">final EntityStore entityStore = new EntityStore(this);
@Nonnull
class="kw">private class="kw">final ChunkLightingManager chunkLighting;
@Nonnull
class="kw">private class="kw">final WorldMapManager worldMapManager;
class="kw">private WorldPathConfig worldPathConfig;
class="kw">private class="kw">final AtomicBoolean acceptingTasks = new AtomicBoolean(true);
@Nonnull
class="kw">private class="kw">final Deque<Runnable> taskQueue = new LinkedBlockingDeque<>();
@Nonnull
class="kw">private class="kw">final AtomicBoolean alive = new AtomicBoolean(true);
@Nonnull
class="kw">private class="kw">final EventRegistry eventRegistry = new EventRegistry(new CopyOnWriteArrayList<>(), () -> true, null, HytaleServer.get().getEventBus());
@Nonnull
class="kw">private class="kw">final WorldNotificationHandler notificationHandler = new WorldNotificationHandler(this);
class="kw">private boolean isTicking;
class="kw">private boolean isPaused;
class="kw">private long tick;
@Nonnull
class="kw">private class="kw">final Random random = new Random();
@Nonnull
class="kw">private class="kw">final AtomicInteger entitySeed = new AtomicInteger();
@Nonnull
class="kw">private class="kw">final Map<UUID, PlayerRef> players = new ConcurrentHashMap<>();
@Nonnull
class="kw">private class="kw">final Collection<PlayerRef> playerRefs = Collections.unmodifiableCollection(this.players.values());
@Nonnull
class="kw">private class="kw">final Map<ClientFeature, Boolean> features = Collections.synchronizedMap(new EnumMap<>(ClientFeature.class));
class="kw">private class="kw">volatile boolean gcHasRun;
class="kw">private class="kw">final AtomicInteger savingLocks = new AtomicInteger(0);
class="kw">public World(@Nonnull String var1, @Nonnull Path var2, @Nonnull WorldConfig var3) {
super("WorldThread - " + var1);
this.name = var1;
this.logger = HytaleLogger.get("World|" + var1);
this.savePath = var2;
this.worldConfig = var3;
this.logger
.at(Level.INFO)
.log("Loading world '%s' with generator type: '%s' and chunk storage: '%s'...", var1, var3.getWorldGenProvider(), var3.getChunkStorageProvider());
this.worldMapManager = new WorldMapManager(this);
this.chunkLighting = new ChunkLightingManager(this);
this.isTicking = var3.isTicking();
for (ClientFeature var7 : ClientFeature.VALUES) {
this.features.put(var7, true);
}
GameplayConfig var8 = this.getGameplayConfig();
CombatConfig var9 = var8.getCombatConfig();
this.features.put(ClientFeature.DisplayHealthBars, var9.isDisplayHealthBars());
this.features.put(ClientFeature.DisplayCombatText, var9.isDisplayCombatText());
PlayerConfig.ArmorVisibilityOption var10 = var8.getPlayerConfig().getArmorVisibilityOption();
this.features.put(ClientFeature.CanHideHelmet, var10.canHideHelmet());
this.features.put(ClientFeature.CanHideCuirass, var10.canHideCuirass());
this.features.put(ClientFeature.CanHideGauntlets, var10.canHideGauntlets());
this.features.put(ClientFeature.CanHidePants, var10.canHidePants());
this.logger.at(Level.INFO).log("Added world '%s' - Seed: %s, GameTime: %s", var1, Long.toString(var3.getSeed()), var3.getGameTime());
}
@Nonnull
class="kw">public CompletableFuture<World> init() {
CompletableFuture var1;
if (this.worldConfig.isSavingConfig()) {
var1 = Universe.get().getWorldConfigProvider().save(this.savePath, this.worldConfig, this);
} else {
var1 = CompletableFuture.completedFuture(null);
}
CompletableFuture var2 = CompletableFuture.<World>supplyAsync(() -> {
try {
IWorldGen var1 = this.worldConfig.getWorldGenProvider().getGenerator();
this.chunkStore.setGenerator(var1);
this.worldConfig.setDefaultSpawnProvider(var1);
IWorldMap var6 = this.worldConfig.getWorldMapProvider().getGenerator(this);
this.worldMapManager.setGenerator(var6);
class="kw">return this;
} catch (WorldGenLoadException var3) {
if (this.name.equals(HytaleServer.get().getConfig().getDefaults().getWorld())) {
Message var5 = Message.translation("client.disconnection.shutdownReason.worldGen.detail").param("detail", var3.getTraceMessage("\n"));
HytaleServer.get().shutdownServer(ShutdownReason.WORLD_GEN.withMessage(var5));
}
throw new SkipSentryException("Failed to load WorldGen!", var3);
} catch (WorldMapLoadException var4) {
if (this.name.equals(HytaleServer.get().getConfig().getDefaults().getWorld())) {
Message var2 = Message.translation("client.disconnection.shutdownReason.worldGen.detail").param("detail", var4.getTraceMessage("\n"));
HytaleServer.get().shutdownServer(ShutdownReason.WORLD_GEN.withMessage(var2));
}
throw new SkipSentryException("Failed to load WorldGen!", var4);
}
}).whenComplete((var1x, var2x) -> {
if (var2x != null) {
((HytaleLogger.Api)this.logger.at(Level.WARNING).withCause(var2x)).log("Failed to load WorldGen for world '%s'", this.name);
}
});
CompletableFuture var3 = WorldPathConfig.load(this).thenAccept(var1x -> this.worldPathConfig = var1x);
class="kw">return this.worldConfig.getSpawnProvider() != null
? CompletableFuture.allOf(var1, var3).thenApply(var1x -> this)
: CompletableFuture.allOf(var1, var3).thenCompose(var1x -> var2);
}
@Override
class="kw">protected void onStart() {
DiskResourceStorageProvider.migrateFiles(this);
IResourceStorage var1 = this.worldConfig.getResourceStorageProvider().getResourceStorage(this);
this.chunkStore.start(var1);
this.entityStore.start(var1);
this.chunkLighting.start();
this.worldMapManager.updateTickingState(this.worldMapManager.isStarted());
Path var2 = this.savePath.resolve("rff");
if (Files.exists(var2)) {
throw new RuntimeException(var2 + " directory exists but this version of the server doesn't support migrating RFF worlds!");
}
IEventDispatcher var3 = HytaleServer.get().getEventBus().dispatchFor(StartWorldEvent.class, this.name);
if (var3.hasListener()) {
var3.dispatch(new StartWorldEvent(this));
}
}
class="kw">public void stopIndividualWorld() {
this.stopIndividualWorld(this.players);
}
class="kw">public void stopIndividualWorld(Map<UUID, PlayerRef> var1) {
this.logger.at(Level.INFO).log("Removing individual world: %s", this.name);
World var2 = Universe.get().getDefaultWorld();
if (var2 != null && !var2.equals(this)) {
Message var7;
if (this.getFailureException() == null) {
var7 = Message.translation("server.universe.worldRemoved");
} else if (this.getPossibleFailureCause() == null) {
var7 = Message.translation("server.universe.worldCrash.unknown");
} else {
var7 = Message.translation("server.universe.worldCrash.mod").param("mod", this.getPossibleFailureCause().toString());
}
var7.color(Color.RED);
for (PlayerRef var9 : var1.values()) {
var9.sendMessage(var7);
}
if (this.isInThread()) {
this.drainPlayersTo(var2, var1.values()).join();
} else {
CompletableFuture.<CompletableFuture<Void>>supplyAsync(() -> this.drainPlayersTo(var2, var1.values()), this)
.thenCompose(var0 -> (CompletionStage<Void>)var0)
.join();
}
} else {
Message var3;
if (this.getFailureException() == null) {
var3 = Message.translation("server.general.disconnect.worldRemoved");
} else if (this.getPossibleFailureCause() == null) {
var3 = Message.translation("server.general.disconnect.worldCrashed");
} else {
var3 = Message.translation("server.general.disconnect.worldCrashedCause").param("cause", this.getPossibleFailureCause().toString());
}
for (PlayerRef var5 : var1.values()) {
var5.getPacketHandler().disconnect(var3);
}
}
if (this.alive.getAndSet(false)) {
try {
super.stop();
} catch (Throwable var6) {
((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var6)).log("Exception while shutting down world:");
}
}
}
class="kw">public void validateDeleteOnRemove() {
if (this.worldConfig.isDeleteOnRemove()) {
try {
this.deleteWorldFromDisk();
} catch (Throwable var2) {
((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var2)).log("Exception while deleting world on remove:");
}
}
}
class="kw">private void deleteWorldFromDisk() class="kw">throws IOException {
Path var1 = this.savePath;
Path var2 = var1.getFileName();
String var3 = var2 + "_del" + UUID.randomUUID().toString().substring(0, 8);
Path var4 = Universe.get().getWorldsDeletedPath().resolve(var3);
Files.createDirectories(var4.getParent());
FileUtil.atomicMove(var1, var4);
FileUtil.deleteDirectory(var4);
}
@Override
class="kw">protected boolean isIdle() {
class="kw">return this.players.isEmpty();
}
@Override
class="kw">protected void tick(float var1) {
if (this.alive.get()) {
TimeResource var2 = this.entityStore.getStore().getResource(TimeResource.getResourceType());
var1 *= var2.getTimeDilationModifier();
AssetRegistry.ASSET_LOCK.readLock().lock();
try {
this.consumeTaskQueue();
if (!this.isPaused) {
this.entityStore.getStore().tick(var1);
} else {
this.entityStore.getStore().pausedTick(var1);
}
if (this.isTicking && !this.isPaused) {
this.chunkStore.getStore().tick(var1);
} else {
this.chunkStore.getStore().pausedTick(var1);
}
this.consumeTaskQueue();
} class="kw">finally {
AssetRegistry.ASSET_LOCK.readLock().unlock();
}
this.tick++;
}
}
@Override
class="kw">protected void onShutdown() {
this.logger.at(Level.INFO).log("Stopping world %s...", this.name);
this.logger.at(Level.INFO).log("Stopping background threads...");
long var1 = System.nanoTime();
while (this.chunkLighting.interrupt() || this.worldMapManager.interrupt()) {
this.consumeTaskQueue();
if (System.nanoTime() - var1 > 5000000000L) {
break;
}
}
this.chunkLighting.stop();
this.worldMapManager.stop();
this.logger.at(Level.INFO).log("Removing players...");
Object2ObjectOpenHashMap var3 = new Object2ObjectOpenHashMap(this.players);
for (PlayerRef var5 : this.playerRefs) {
if (var5.getReference() != null) {
var5.removeFromStore();
}
}
this.consumeTaskQueue();
this.logger.at(Level.INFO).log("Waiting for loading chunks...");
this.chunkStore.waitForLoadingChunks();
try {
this.logger.at(Level.INFO).log("Shutting down stores...");
HytaleServer.get().reportSingleplayerStatus(Message.translation("client.gameLoadingView.status.savingWorld").param("name", this.name));
this.chunkStore.shutdown();
this.consumeTaskQueue();
this.entityStore.shutdown();
this.consumeTaskQueue();
this.eventRegistry.shutdownAndCleanup(true);
} class="kw">finally {
this.logger.at(Level.INFO).log("Saving Config...");
if (this.worldConfig.isSavingConfig()) {
Universe.get().getWorldConfigProvider().save(this.savePath, this.worldConfig, this).join();
}
}
this.acceptingTasks.set(false);
if (this.alive.getAndSet(false)) {
this.stopIndividualWorld(var3);
Universe.get().removeWorldExceptionally(this.name, var3);
}
HytaleServer.get().reportSingleplayerStatus(Message.translation("client.gameLoadingView.status.closingWorld").param("name", this.name));
}
@Override
class="kw">public void setTps(int var1) {
super.setTps(var1);
SetUpdateRate var2 = new SetUpdateRate(var1);
this.entityStore
.getStore()
.forEachEntityParallel(
PlayerRef.getComponentType(), (var1x, var2x, var3) -> var2x.getComponent(var1x, PlayerRef.getComponentType()).getPacketHandler().writeNoCache(var2)
);
}
class="kw">public class="kw">static void setTimeDilation(float var0, @Nonnull ComponentAccessor<EntityStore> var1) {
World var2 = var1.getExternalData().getWorld();
if (!(var0 <= 0.01) && !(var0 > 4.0F)) {
TimeResource var3 = var1.getResource(TimeResource.getResourceType());
var3.setTimeDilationModifier(var0);
SetTimeDilation var4 = new SetTimeDilation(var0);
for (PlayerRef var6 : var2.playerRefs) {
var6.getPacketHandler().writeNoCache(var4);
}
} else {
throw new IllegalArgumentException("TimeDilation is out of bounds (<=0.01 or >4)");
}
}
@Nonnull
class="kw">public String getName() {
class="kw">return this.name;
}
class="kw">public boolean isAlive() {
class="kw">return this.alive.get();
}
@Nonnull
class="kw">public WorldConfig getWorldConfig() {
class="kw">return this.worldConfig;
}
@Nonnull
class="kw">public DeathConfig getDeathConfig() {
MutableDeathConfig var1 = this.worldConfig.getDeathConfigOverride();
class="kw">return var1 != null ? var1 : this.getGameplayConfig().getDeathConfig();
}
@Nullable
class="kw">public String getGameModeTypeOnDeath() {
String var1 = this.getDeathConfig().getGameModeTypeOnDeath();
class="kw">return var1 != null ? var1 : HytaleServer.get().getConfig().getDefaults().getGameModeTypeOnDeath();
}
class="kw">public int getDaytimeDurationSeconds() {
Integer var1 = this.worldConfig.getDaytimeDurationSecondsOverride();
class="kw">return var1 != null ? var1 : this.getGameplayConfig().getWorldConfig().getDaytimeDurationSeconds();
}
class="kw">public int getNighttimeDurationSeconds() {
Integer var1 = this.worldConfig.getNighttimeDurationSecondsOverride();
class="kw">return var1 != null ? var1 : this.getGameplayConfig().getWorldConfig().getNighttimeDurationSeconds();
}
class="kw">public boolean isTicking() {
class="kw">return this.isTicking;
}
class="kw">public void setTicking(boolean var1) {
this.isTicking = var1;
this.worldConfig.setTicking(var1);
this.worldConfig.markChanged();
}
class="kw">public boolean isPaused() {
class="kw">return this.isPaused;
}
class="kw">public void setPaused(boolean var1) {
if (this.isPaused != var1) {
this.isPaused = var1;
ServerSetPaused var2 = new ServerSetPaused(var1);
PlayerUtil.broadcastPacketToPlayersNoCache(this.entityStore.getStore(), var2);
}
}
class="kw">public long getTick() {
class="kw">return this.tick;
}
@Nonnull
class="kw">public HytaleLogger getLogger() {
class="kw">return this.logger;
}
class="kw">public boolean isCompassUpdating() {
class="kw">return this.worldConfig.isCompassUpdating();
}
class="kw">public void setCompassUpdating(boolean var1) {
boolean var2 = this.worldMapManager.shouldTick();
this.worldConfig.setCompassUpdating(var1);
this.worldConfig.markChanged();
this.worldMapManager.updateTickingState(var2);
}
class="kw">public <T> void getBlockBulkRelative(
@Nonnull Long2ObjectMap<T> var1,
@Nonnull IntUnaryOperator var2,
@Nonnull IntUnaryOperator var3,
@Nonnull IntUnaryOperator var4,
@Nonnull World.GenericBlockBulkUpdater<T> var5
) {
Long2ObjectMap var6 = new Long2ObjectOpenHashMap();
var1.forEach((var6x, var7) -> {
int var8 = BlockUtil.unpackX(var6x);
int var9 = BlockUtil.unpackY(var6x);
int var10 = BlockUtil.unpackZ(var6x);
int var11 = var2.applyAsInt(var8);
int var12 = var3.applyAsInt(var9);
int var13 = var4.applyAsInt(var10);
long var14 = ChunkUtil.indexChunkFromBlock(var11, var13);
WorldChunk var16 = (WorldChunk)var6.get(var14);
if (var16 == null) {
var16 = this.getNonTickingChunk(var14);
var6.put(var14, var16);
}
var5.apply(this, (T)var7, var14, var16, var11, var12, var13, var8, var9, var10);
});
}
@Nullable
@Override
class="kw">public WorldChunk loadChunkIfInMemory(long var1) {
if (!this.isInThread()) {
class="kw">return CompletableFuture.<WorldChunk>supplyAsync(() -> this.loadChunkIfInMemory(var1), this).join();
}
Ref var3 = this.chunkStore.getChunkReference(var1);
if (var3 == null) {
class="kw">return null;
}
WorldChunk var4 = this.chunkStore.getStore().getComponent(var3, WorldChunk.getComponentType());
assert var4 != null;
var4.setFlag(ChunkFlag.TICKING, true);
class="kw">return var4;
}
@Nullable
@Deprecated
@Override
class="kw">public WorldChunk getChunkIfInMemory(long var1) {
Ref var3 = this.chunkStore.getChunkReference(var1);
if (var3 == null) {
class="kw">return null;
} else {
class="kw">return !this.isInThread()
? CompletableFuture.<WorldChunk>supplyAsync(() -> this.getChunkIfInMemory(var1), this).join()
: this.chunkStore.getStore().getComponent(var3, WorldChunk.getComponentType());
}
}
@Nullable
@Deprecated
@Override
class="kw">public WorldChunk getChunkIfLoaded(long var1) {
if (!this.isInThread()) {
class="kw">return CompletableFuture.<WorldChunk>supplyAsync(() -> this.getChunkIfLoaded(var1), this).join();
}
Ref var3 = this.chunkStore.getChunkReference(var1);
if (var3 == null) {
class="kw">return null;
}
WorldChunk var4 = this.chunkStore.getStore().getComponent(var3, WorldChunk.getComponentType());
assert var4 != null;
class="kw">return var4.is(ChunkFlag.TICKING) ? var4 : null;
}
@Nullable
@Deprecated
@Override
class="kw">public WorldChunk getChunkIfNonTicking(long var1) {
if (!this.isInThread()) {
class="kw">return CompletableFuture.<WorldChunk>supplyAsync(() -> this.getChunkIfNonTicking(var1), this).join();
}
Ref var3 = this.chunkStore.getChunkReference(var1);
if (var3 == null) {
class="kw">return null;
}
WorldChunk var4 = this.chunkStore.getStore().getComponent(var3, WorldChunk.getComponentType());
assert var4 != null;
class="kw">return var4.is(ChunkFlag.TICKING) ? null : var4;
}
@Nonnull
@Deprecated
@Override
class="kw">public CompletableFuture<WorldChunk> getChunkAsync(long var1) {
class="kw">return this.chunkStore
.getChunkReferenceAsync(var1, 4)
.thenApplyAsync(var1x -> var1x == null ? null : this.chunkStore.getStore().getComponent((Ref<ChunkStore>)var1x, WorldChunk.getComponentType()), this);
}
@Nonnull
@Deprecated
@Override
class="kw">public CompletableFuture<WorldChunk> getNonTickingChunkAsync(long var1) {
class="kw">return this.chunkStore
.getChunkReferenceAsync(var1)
.thenApplyAsync(var1x -> var1x == null ? null : this.chunkStore.getStore().getComponent((Ref<ChunkStore>)var1x, WorldChunk.getComponentType()), this);
}
@Deprecated(forRemoval = true)
class="kw">public List<Player> getPlayers() {
if (!this.isInThread()) {
class="kw">return !this.isStarted() ? Collections.emptyList() : CompletableFuture.supplyAsync(this::getPlayers, this).join();
}
ObjectArrayList var1 = new ObjectArrayList(32);
this.entityStore.getStore().forEachChunk(Player.getComponentType(), (var1x, var2) -> {
var1.ensureCapacity(var1.size() + var1x.size());
for (int var3 = 0; var3 < var1x.size(); var3++) {
var1.add(var1x.getComponent(var3, Player.getComponentType()));
}
});
class="kw">return var1;
}
@Nullable
@Deprecated
class="kw">public Entity getEntity(@Nonnull UUID var1) {
if (!this.isInThread()) {
class="kw">return CompletableFuture.<Entity>supplyAsync(() -> this.getEntity(var1), this).join();
}
Ref var2 = this.entityStore.getRefFromUUID(var1);
class="kw">return EntityUtils.getEntity(var2, this.entityStore.getStore());
}
@Nullable
class="kw">public Ref<EntityStore> getEntityRef(@Nonnull UUID var1) {
class="kw">return !this.isInThread()
? CompletableFuture.<Ref<EntityStore>>supplyAsync(() -> this.getEntityRef(var1), this).join()
: this.entityStore.getRefFromUUID(var1);
}
class="kw">public int getPlayerCount() {
class="kw">return this.players.size();
}
class="kw">public int getNonSpectatorPlayerCount() {
int var1 = 0;
for (PlayerRef var3 : this.playerRefs) {
Ref var4 = var3.getReference();
if (var4 == null || !var4.isValid() || !this.entityStore.getStore().getArchetype(var4).contains(Spectating.getComponentType())) {
var1++;
}
}
class="kw">return var1;
}
@Nonnull
class="kw">public Collection<PlayerRef> getPlayerRefs() {
class="kw">return this.playerRefs;
}
class="kw">public void trackPlayerRef(@Nonnull PlayerRef var1) {
this.players.put(var1.getUuid(), var1);
}
class="kw">public void untrackPlayerRef(@Nonnull PlayerRef var1) {
this.players.remove(var1.getUuid(), var1);
}
@Deprecated
@Nullable
class="kw">public <T class="kw">extends Entity> T spawnEntity(T var1, @Nonnull Vector3d var2, Rotation3f var3) {
class="kw">return this.addEntity(var1, var2, var3, AddReason.SPAWN);
}
@Deprecated
@Nullable
class="kw">public <T class="kw">extends Entity> T addEntity(T var1, @Nonnull Vector3d var2, @Nullable Rotation3f var3, @Nonnull AddReason var4) {
if (!EntityModule.get().isKnown(var1)) {
throw new IllegalArgumentException("Unknown entity");
}
if (var1 class="kw">instanceof Player) {
throw new IllegalArgumentException("Entity can't be a Player!");
}
if (var1.getNetworkId() == -1) {
throw new IllegalArgumentException("Entity id can't be Entity.UNASSIGNED_ID (-1)!");
}
if (!this.equals(var1.getWorld())) {
throw new IllegalStateException("Expected entity to already have its world set to " + this.name + " but it has " + var1.getWorld());
}
if (var1.getReference() != null && var1.getReference().isValid()) {
throw new IllegalArgumentException("Entity already has a valid EntityReference: " + var1.getReference());
}
if (var2.y() < -32.0) {
throw new IllegalArgumentException("Unable to spawn entity below the world! -32 < " + var2);
}
if (!this.isInThread()) {
((HytaleLogger.Api)this.logger.at(Level.WARNING).withCause(new SkipSentryException())).log("Warning addEntity was called off thread!");
this.execute(() -> this.addEntity(var1, var2, var3, var4));
class="kw">return var1;
}
var1.unloadFromWorld();
Holder var5 = var1.toHolder();
HeadRotation var6 = var5.ensureAndGetComponent(HeadRotation.getComponentType());
if (var3 != null) {
var6.teleportRotation(var3);
}
var5.addComponent(TransformComponent.getComponentType(), new TransformComponent(var2, var3));
var5.ensureComponent(UUIDComponent.getComponentType());
this.entityStore.getStore().addEntity(var5, var4);
class="kw">return var1;
}
@Override
class="kw">public void sendMessage(@Nonnull Message var1) {
if (!this.isInThread()) {
this.execute(() -> this.sendMessage(var1));
} else {
this.entityStore.getStore().forEachEntityParallel(PlayerRef.getComponentType(), (var1x, var2, var3) -> {
PlayerRef var4 = var2.getComponent(var1x, PlayerRef.getComponentType());
assert var4 != null;
var4.sendMessage(var1);
});
this.logger.at(Level.INFO).log("[Broadcast] [Message] %s", MessageUtil.toAnsiString(var1).toAnsi(ConsoleModule.get().getTerminal()));
}
}
@Override
class="kw">public void execute(@Nonnull Runnable var1) {
if (!this.acceptingTasks.get()) {
throw new SkipSentryException(new IllegalThreadStateException("World thread is not accepting tasks: " + this.name + ", " + this.getThread()));
}
this.taskQueue.offer(var1);
}
class="kw">public ScheduledFuture<?> scheduleAfter(@Nonnull Runnable var1, long var2, @Nonnull TimeUnit var4) {
class="kw">return HytaleServer.SCHEDULED_EXECUTOR.schedule(() -> {
if (this.acceptingTasks.get()) {
this.taskQueue.offer(var1);
}
}, var2, var4);
}
@Override
class="kw">public void consumeTaskQueue() {
this.debugAssertInTickingThread();
int var1 = this.getTickStepNanos();
Runnable var2;
while ((var2 = this.taskQueue.poll()) != null) {
try {
long var3 = System.nanoTime();
var2.run();
long var5 = System.nanoTime();
long var7 = var5 - var3;
if (var7 > var1) {
this.logger.at(Level.WARNING).log("Task took %s ns: %s", FormatUtil.nanosToString(var7), var2);
}
} catch (Exception var9) {
((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var9)).log("Failed to run task!");
}
}
}
@Nonnull
class="kw">public ChunkStore getChunkStore() {
class="kw">return this.chunkStore;
}
@Nonnull
class="kw">public EntityStore getEntityStore() {
class="kw">return this.entityStore;
}
@Nonnull
class="kw">public ChunkLightingManager getChunkLighting() {
class="kw">return this.chunkLighting;
}
@Nonnull
class="kw">public WorldMapManager getWorldMapManager() {
class="kw">return this.worldMapManager;
}
class="kw">public WorldPathConfig getWorldPathConfig() {
class="kw">return this.worldPathConfig;
}
@Nonnull
class="kw">public WorldNotificationHandler getNotificationHandler() {
class="kw">return this.notificationHandler;
}
@Nonnull
class="kw">public EventRegistry getEventRegistry() {
class="kw">return this.eventRegistry;
}
@Nullable
class="kw">public CompletableFuture<PlayerRef> addPlayer(@Nonnull PlayerRef var1) {
class="kw">return this.addPlayer(var1, null);
}
@Nullable
class="kw">public CompletableFuture<PlayerRef> addPlayer(@Nonnull PlayerRef var1, @Nullable Transform var2) {
class="kw">return this.addPlayer(var1, var2, null, null);
}
@Nullable
class="kw">public CompletableFuture<PlayerRef> addPlayer(@Nonnull PlayerRef var1, @Nullable Transform var2, @Nullable Boolean var3, @Nullable Boolean var4) {
if (!this.alive.get()) {
class="kw">return CompletableFuture.failedFuture(new SkipSentryException(new IllegalStateException("This world has already been shutdown!")));
}
if (var1.getReference() != null) {
throw new IllegalStateException("Player is already in a world");
}
PacketHandler var5 = var1.getPacketHandler();
if (!var5.stillActive()) {
class="kw">return null;
}
Holder var6 = var1.getHolder();
assert var6 != null;
var1.setWorldUuid(this.worldConfig.getUuid());
TransformComponent var7 = var6.getComponent(TransformComponent.getComponentType());
if (var7 == null && var2 == null) {
var7 = SpawnUtil.applyFirstSpawnTransform(var6, this, this.worldConfig, var1.getUuid());
if (var7 == null) {
class="kw">return CompletableFuture.failedFuture(new IllegalStateException("Spawn provider cannot be null for positioning new entities!"));
}
}
assert var7 != null;
Player var8 = var6.getComponent(Player.getComponentType());
assert var8 != null;
boolean var9 = !var8.getPlayerConfigData().getPerWorldData().containsKey(this.name);
var8.setFirstSpawn(var9);
if (var2 != null) {
SpawnUtil.applyTransform(var6, var2);
}
Message var10 = Message.translation("server.general.playerJoinedWorld")
.param("username", var1.getUsername())
.param("world", this.worldConfig.getDisplayName() != null ? this.worldConfig.getDisplayName() : WorldConfig.formatDisplayName(this.name));
AddPlayerToWorldEvent var11 = HytaleServer.get()
.getEventBus()
.dispatchFor(AddPlayerToWorldEvent.class, this.name)
.dispatch(new AddPlayerToWorldEvent(var6, this, var10));
ChunkTracker var12 = var6.getComponent(ChunkTracker.getComponentType());
boolean var13 = var3 != null ? var3 : true;
boolean var14 = var4 != null ? var4 : true;
if (var12 != null && (var13 || var14)) {
var12.setReadyForChunks(false);
}
Vector3d var15 = var7.getPosition();
long var16 = ChunkUtil.indexChunkFromBlock(var15.x(), var15.z());
CompletableFuture var18 = this.chunkStore.getChunkReferenceAsync(var16, 32).thenAccept(var1x -> var8.startClientReadyTimeout());
CompletableFuture var19 = new CompletableFuture<>();
var5.setClientReadyForChunksFuture(var19);
CompletableFuture var20 = CompletableFuture.runAsync(() -> this.onSetupPlayerJoining(var6, var8, var1, var5, var2, var13, var14));
CompletableFuture var21 = var19.orTimeout(30L, TimeUnit.SECONDS);
class="kw">return CompletableFuture.allOf(var20, var21, var18)
.thenApplyAsync(var5x -> this.onFinishPlayerJoining(var8, var1, var5, var11.getJoinMessage(), var11.shouldBroadcastJoinMessage()), this)
.exceptionally(var2x -> {
((HytaleLogger.Api)this.logger.at(Level.WARNING).withCause(var2x)).log("Exception when adding player to world!");
PluginIdentifier var3 = PluginIdentifier.identifyThirdPartyPlugin(var2x);
if (var3 == null) {
var1.getPacketHandler().disconnect(Message.translation("server.general.disconnect.exceptionJoiningWorld"));
} else {
var1.getPacketHandler().disconnect(Message.translation("server.general.disconnect.exceptionJoiningWorldCause").param("cause", var3.toString()));
}
throw new RuntimeException("Exception when adding player '" + var1.getUsername() + "' to world '" + this.name + "'", var2x);
});
}
@Nonnull
class="kw">private PlayerRef onFinishPlayerJoining(@Nonnull Player var1, @Nonnull PlayerRef var2, @Nonnull PacketHandler var3, @Nullable Message var4, boolean var5) {
TimeResource var6 = this.entityStore.getStore().getResource(TimeResource.getResourceType());
float var7 = var6.getTimeDilationModifier();
int var8 = HytaleServer.get().getConfig().getMaxViewRadius();
var3.write(new ViewRadius(var8 * 32));
var3.write(new SetEntitySeed(this.entitySeed.get()), new SetClientId(var1.getNetworkId()), new SetTimeDilation(var7));
var3.write(new UpdateFeatures(this.features));
var3.write(this.worldConfig.getClientEffects().createSunSettingsPacket());
var3.write(this.worldConfig.getClientEffects().createPostFxSettingsPacket());
UUID var9 = var2.getUuid();
Store var10 = this.entityStore.getStore();
WorldTimeResource var11 = var10.getResource(WorldTimeResource.getResourceType());
World var12 = var10.getExternalData().getWorld();
var3.writeNoCache(new SetUpdateRate(this.getTps()));
if (this.isPaused) {
this.setPaused(false);
}
if (!var3.stillActive()) {
throw new IllegalStateException("Connection of joining player closed before they could be added to the world store");
}
Ref var13 = var2.addToStore(var10);
if (var13 != null && var13.isValid()) {
var11.sendTimePackets(var2);
WorldMapTracker var14 = var1.getWorldMapTracker();
var14.clear();
var14.sendSettings(var12);
if (var5) {
PlayerUtil.broadcastMessageToPlayers(var9, var4, var10);
}
TransformComponent var15 = var10.getComponent(var13, TransformComponent.getComponentType());
assert var15 != null;
String var16 = var15.getPosition().toString();
this.logger.at(Level.INFO).log("Player '%s' joined world '%s' at location %s (%s)", var2.getUsername(), this.name, var16, var9);
HeadRotation var17 = var10.getComponent(var13, HeadRotation.getComponentType());
assert var17 != null;
class="kw">return var2;
} else {
throw new IllegalStateException("Failed to add player ref of joining player to the world store");
}
}
class="kw">private void onSetupPlayerJoining(
@Nonnull Holder<EntityStore> var1,
@Nonnull Player var2,
@Nonnull PlayerRef var3,
@Nonnull PacketHandler var4,
@Nullable Transform var5,
boolean var6,
boolean var7
) {
UUID var8 = var3.getUuid();
this.logger.at(Level.INFO).log("Adding player '%s' to world '%s' at location %s (%s)", var3.getUsername(), this.name, var5, var8);
int var9 = this.entityStore.takeNextNetworkId();
var2.setNetworkId(var9);
PlayerConfigData var10 = var2.getPlayerConfigData();
var10.setWorld(this.name);
if (var6) {
EntityTrackerSystems.clear(var1);
ChunkTracker var11 = var1.getComponent(ChunkTracker.getComponentType());
if (var11 != null) {
var11.clear();
var4.writeNoCache(new ClearChunks());
}
}
var2.getPageManager().clearCustomPageAcknowledgements();
boolean var15 = this.chunkStore.supportsCubicSections();
Integer var12 = var15 ? null : 0;
Integer var13 = var15 ? null : 9;
JoinWorld var14 = new JoinWorld(var6, var7, this.worldConfig.getUuid(), var12, var13);
var4.write(var14);
var4.tryFlush();
HytaleLogger.getLogger().at(Level.INFO).log("%s: Sent %s", var4.getIdentifier(), var14);
var4.setQueuePackets(true);
}
@Nonnull
class="kw">public CompletableFuture<Void> drainPlayersTo(@Nonnull World var1, Collection<PlayerRef> var2) {
ObjectArrayList var3 = new ObjectArrayList();
for (PlayerRef var5 : var2) {
Holder var6 = var5.getReference() != null ? var5.removeFromStore() : var5.getHolder();
DrainPlayerFromWorldEvent var7 = HytaleServer.get()
.getEventBus()
.dispatchFor(DrainPlayerFromWorldEvent.class, this.name)
.dispatch(new DrainPlayerFromWorldEvent(var6, var1, null));
var3.add(var7.getWorld().addPlayer(var5, var7.getTransform()));
}
class="kw">return CompletableFuture.allOf((CompletableFuture<?>[])var3.toArray(CompletableFuture[]::new));
}
@Nonnull
class="kw">public GameplayConfig getGameplayConfig() {
String var1 = this.worldConfig.getGameplayConfig();
GameplayConfig var2 = GameplayConfig.getAssetMap().getAsset(var1);
if (var2 == null) {
var2 = GameplayConfig.DEFAULT;
}
class="kw">return var2;
}
@Nonnull
class="kw">public Map<ClientFeature, Boolean> getFeatures() {
class="kw">return Collections.unmodifiableMap(this.features);
}
class="kw">public boolean isFeatureEnabled(@Nonnull ClientFeature var1) {
class="kw">return this.features.getOrDefault(var1, false);
}
class="kw">public void registerFeature(@Nonnull ClientFeature var1, boolean var2) {
this.features.put(var1, var2);
this.broadcastFeatures();
}
class="kw">public void broadcastFeatures() {
UpdateFeatures var1 = new UpdateFeatures(this.features);
for (PlayerRef var3 : this.playerRefs) {
var3.getPacketHandler().write(var1);
}
}
@Nonnull
class="kw">public Path getSavePath() {
class="kw">return this.savePath;
}
class="kw">public void updateEntitySeed(@Nonnull Store<EntityStore> var1) {
int var2 = this.random.nextInt();
this.entitySeed.set(var2);
PlayerUtil.broadcastPacketToPlayers(var1, new SetEntitySeed(var2));
}
class="kw">public void markGCHasRun() {
this.gcHasRun = true;
}
class="kw">public boolean consumeGCHasRun() {
boolean var1 = this.gcHasRun;
this.gcHasRun = false;
class="kw">return var1;
}
class="kw">public boolean isSavingLocked() {
class="kw">return this.savingLocks.get() > 0;
}
class="kw">public void lockSaving() {
this.savingLocks.incrementAndGet();
}
class="kw">public void unlockSaving() {
int var1 = this.savingLocks.decrementAndGet();
assert var1 >= 0 : "savingLocks underflow";
}
@Override
class="kw">public int hashCode() {
class="kw">return this.name != null ? this.name.hashCode() : 0;
}
@Override
class="kw">public boolean equals(@Nullable Object var1) {
if (this == var1) {
class="kw">return true;
} else if (var1 != null && this.getClass() == var1.getClass()) {
World var2 = (World)var1;
class="kw">return this.name.equals(var2.name);
} else {
class="kw">return false;
}
}
@Nonnull
@Override
class="kw">public String toString() {
class="kw">return "World{name='"
+ this.name
+ "', alive="
+ this.alive.get()
+ ", loadedChunksCount="
+ this.chunkStore.getLoadedChunksCount()
+ ", totalLoadedChunksCount="
+ this.chunkStore.getTotalLoadedChunksCount()
+ ", totalGeneratedChunksCount="
+ this.chunkStore.getTotalGeneratedChunksCount()
+ ", entityCount="
+ (this.entityStore.getStore() != null ? this.entityStore.getStore().getEntityCount() : 0)
+ "}";
}
class="kw">public void validate(@Nonnull StringBuilder var1, @Nonnull IPrefabBuffer.RawBlockConsumer<Void> var2, @Nonnull EnumSet<ValidationOption> var3) class="kw">throws IOException {
this.setThread(Thread.currentThread());
this.onStart();
Store var4 = this.chunkStore.getStore();
StringBuilder var5 = new StringBuilder();
LongListIterator var6 = this.chunkStore.getLoader().getIndexes().iterator();
while (var6.hasNext()) {
long var7 = (Long)var6.next();
int var9 = ChunkUtil.xOfChunkIndex(var7);
int var10 = ChunkUtil.zOfChunkIndex(var7);
try {
CompletableFuture var11 = this.chunkStore.getChunkReferenceAsync(var7, 2);
while (!var11.isDone()) {
this.consumeTaskQueue();
}
Ref var12 = var11.join();
if (var12 != null && var12.isValid()) {
WorldChunk var13 = var4.getComponent(var12, WorldChunk.getComponentType());
ChunkColumn var14 = var4.getComponent(var12, ChunkColumn.getComponentType());
if (var14 != null) {
for (Ref var18 : var14.getSections()) {
class="kw">final ChunkSection var19 = var4.getComponent(var18, ChunkSection.getComponentType());
if (var3.contains(ValidationOption.ENTITIES)) {
ComponentType var20 = EntityStore.REGISTRY.getUnknownComponentType();
EntitySection var21 = var4.getComponent(var18, EntitySection.getComponentType());
if (var21 != null) {
for (Holder var23 : var21.getEntityHolders()) {
UnknownComponents var24 = var23.getComponent(var20);
if (var24 != null && !var24.getUnknownComponents().isEmpty()) {
var1.append("\tUnknown Entity Components: ").append(var24.getUnknownComponents()).append("\n");
}
}
}
}
BlockSection var36 = var4.getComponent(var18, BlockSection.getComponentType());
if (var36 != null) {
BlockPhysics var37 = var4.getComponent(var18, BlockPhysics.getComponentType());
for (int var38 = 0; var38 < 32; var38++) {
int var39 = (var19.getY() << 5) + var38;
for (int var40 = 0; var40 < 32; var40++) {
for (int var25 = 0; var25 < 32; var25++) {
int var26 = var36.get(var25, var38, var40);
int var27 = var36.getFiller(var25, var38, var40);
int var28 = var36.getRotationIndex(var25, var38, var40);
Holder var29 = var13.getBlockComponentHolder(var25, var39, var40);
int var30 = ChunkUtil.minBlock(var13.getX()) + var25;
int var31 = ChunkUtil.minBlock(var13.getZ()) + var40;
var2.accept(var30, var39, var31, var26, 0, 1.0F, var29, var37 != null ? var37.get(var25, var38, var40) : 0, var28, var27, null);
if (var3.contains(ValidationOption.BLOCK_FILLER)) {
var var32 = new FillerBlockUtil.FillerFetcher<BlockSection, ChunkStore>() {
class="kw">public int getBlock(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5) {
if (var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32) {
class="kw">return var1.get(var3x, var4, var5);
}
int var6 = var19.getX() + ChunkUtil.chunkCoordinate(var3x);
int var7 = var19.getY() + ChunkUtil.chunkCoordinate(var4);
int var8 = var19.getZ() + ChunkUtil.chunkCoordinate(var5);
CompletableFuture var9 = var2x.getChunkSectionReferenceAsync(var6, var7, var8);
while (!var9.isDone()) {
World.this.consumeTaskQueue();
}
Ref var10 = var9.join();
BlockSection var11 = var2x.getStore().getComponent(var10, BlockSection.getComponentType());
class="kw">return var11 == null ? Integer.MIN_VALUE : var11.get(var3x, var4, var5);
}
class="kw">public int getFiller(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5) {
if (var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32) {
class="kw">return var1.getFiller(var3x, var4, var5);
}
int var6 = var19.getX() + ChunkUtil.chunkCoordinate(var3x);
int var7 = var19.getY() + ChunkUtil.chunkCoordinate(var4);
int var8 = var19.getZ() + ChunkUtil.chunkCoordinate(var5);
CompletableFuture var9 = var2x.getChunkSectionReferenceAsync(var6, var7, var8);
while (!var9.isDone()) {
World.this.consumeTaskQueue();
}
Ref var10 = var9.join();
BlockSection var11 = var2x.getStore().getComponent(var10, BlockSection.getComponentType());
class="kw">return var11 == null ? Integer.MIN_VALUE : var11.getFiller(var3x, var4, var5);
}
class="kw">public int getRotationIndex(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5) {
if (var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32) {
class="kw">return var1.getFiller(var3x, var4, var5);
}
int var6 = var19.getX() + ChunkUtil.chunkCoordinate(var3x);
int var7 = var19.getY() + ChunkUtil.chunkCoordinate(var4);
int var8 = var19.getZ() + ChunkUtil.chunkCoordinate(var5);
CompletableFuture var9 = var2x.getChunkSectionReferenceAsync(var6, var7, var8);
while (!var9.isDone()) {
World.this.consumeTaskQueue();
}
Ref var10 = var9.join();
BlockSection var11 = var2x.getStore().getComponent(var10, BlockSection.getComponentType());
class="kw">return var11 == null ? Integer.MIN_VALUE : var11.getRotationIndex(var3x, var4, var5);
}
};
FillerBlockUtil.ValidationResult var33 = FillerBlockUtil.validateBlock(
var25, var38, var40, var26, var28, var27, var36, this.chunkStore, var32
);
class="kw">switch (var33) {
case OK:
class="kw">default:
break;
case INVALID_BLOCK: {
BlockType var41 = BlockType.getAssetMap().getAsset(var26);
var5.append("\tBlock ")
.append(var41 != null ? var41.getId() : "<missing>")
.append(" at ")
.append(var25)
.append(", ")
.append(var38)
.append(", ")
.append(var40)
.append(" is not valid filler")
.append('\n');
break;
}
case INVALID_FILLER: {
BlockType var34 = BlockType.getAssetMap().getAsset(var26);
var5.append("\tBlock ")
.append(var34 != null ? var34.getId() : "<missing>")
.append(" at ")
.append(var25)
.append(", ")
.append(var38)
.append(", ")
.append(var40)
.append(" has invalid/missing filler blocks")
.append('\n');
}
}
}
}
}
}
if (!var5.isEmpty()) {
var1.append("\tChunk ")
.append(var19.getX())
.append(", ")
.append(var19.getY())
.append(", ")
.append(var19.getZ())
.append(" validation errors:")
.append(var5);
var5.setLength(0);
}
}
}
var4.tick(1.0F);
}
}
} catch (CompletionException var35) {
((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var35)).log("Failed to validate chunk: %d, %d", var9, var10);
var1.append('\t')
.append("Exception validating chunk: ")
.append(var9)
.append(", ")
.append(var10)
.append('\n')
.append("\t\t")
.append(var35.getCause().getMessage())
.append('\n');
}
}
if (this.alive.getAndSet(false)) {
this.onShutdown();
}
this.setThread(null);
}
@FunctionalInterface
class="kw">public class="kw">interface GenericBlockBulkUpdater<T> {
void apply(World var1, T var2, long var3, WorldChunk var5, int var6, int var7, int var8, int var9, int var10, int var11);
}
}