Search in sources :

Example 1 with PrimaryLevelData

use of net.minecraft.world.level.storage.PrimaryLevelData in project SpongeCommon by SpongePowered.

the class ServerLevelMixin method save.

/**
 * @author zidane - December 17th, 2020 - Minecraft 1.16.4
 * @reason Honor our serialization behavior in performing saves
 */
@Overwrite
public void save(@Nullable final ProgressListener progress, final boolean flush, final boolean skipSave) {
    final Cause currentCause = Sponge.server().causeStackManager().currentCause();
    if (Sponge.eventManager().post(SpongeEventFactory.createSaveWorldEventPre(currentCause, ((ServerWorld) this)))) {
        // cancelled save
        return;
    }
    final PrimaryLevelData levelData = (PrimaryLevelData) this.shadow$getLevelData();
    final ServerChunkCache chunkProvider = ((ServerLevel) (Object) this).getChunkSource();
    if (!skipSave) {
        final SerializationBehavior behavior = ((PrimaryLevelDataBridge) levelData).bridge$serializationBehavior().orElse(SerializationBehavior.AUTOMATIC);
        if (progress != null) {
            progress.progressStartNoAbort(new TranslatableComponent("menu.savingLevel"));
        }
        // We always save the metadata unless it is NONE
        if (behavior != SerializationBehavior.NONE) {
            this.shadow$saveLevelData();
            // Sponge Start - We do per-world WorldInfo/WorldBorders/BossBars
            levelData.setWorldBorder(this.getWorldBorder().createSettings());
            levelData.setCustomBossEvents(((ServerLevelBridge) this).bridge$getBossBarManager().save());
            ((ServerLevelBridge) this).bridge$getLevelSave().saveDataTag(SpongeCommon.server().registryAccess(), (PrimaryLevelData) this.shadow$getLevelData(), this.shadow$dimension() == Level.OVERWORLD ? SpongeCommon.server().getPlayerList().getSingleplayerData() : null);
        // Sponge End
        }
        if (progress != null) {
            progress.progressStage(new TranslatableComponent("menu.savingChunks"));
        }
        final boolean canAutomaticallySave = !this.impl$isManualSave && behavior == SerializationBehavior.AUTOMATIC;
        final boolean canManuallySave = this.impl$isManualSave && behavior == SerializationBehavior.MANUAL;
        if (canAutomaticallySave || canManuallySave) {
            chunkProvider.save(flush);
        }
        Sponge.eventManager().post(SpongeEventFactory.createSaveWorldEventPost(currentCause, ((ServerWorld) this)));
    }
    this.impl$isManualSave = false;
}
Also used : PrimaryLevelData(net.minecraft.world.level.storage.PrimaryLevelData) ServerLevel(net.minecraft.server.level.ServerLevel) TranslatableComponent(net.minecraft.network.chat.TranslatableComponent) Cause(org.spongepowered.api.event.Cause) SerializationBehavior(org.spongepowered.api.world.SerializationBehavior) ServerChunkCache(net.minecraft.server.level.ServerChunkCache) ServerLevelBridge(org.spongepowered.common.bridge.server.level.ServerLevelBridge) PlatformServerLevelBridge(org.spongepowered.common.bridge.world.level.PlatformServerLevelBridge) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 2 with PrimaryLevelData

use of net.minecraft.world.level.storage.PrimaryLevelData in project SpongeCommon by SpongePowered.

the class LevelStorageSourceMixin_Vanilla method impl$readSpongeLevelData.

@Redirect(method = "lambda$getLevelData$4", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/LevelSettings;parse(Lcom/mojang/serialization/Dynamic;Lnet/minecraft/world/level/DataPackConfig;)Lnet/minecraft/world/level/LevelSettings;"), to = @At(value = "RETURN")), at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/PrimaryLevelData;parse(Lcom/mojang/serialization/Dynamic;Lcom/mojang/datafixers/DataFixer;ILnet/minecraft/nbt/CompoundTag;Lnet/minecraft/world/level/LevelSettings;Lnet/minecraft/world/level/storage/LevelVersion;Lnet/minecraft/world/level/levelgen/WorldGenSettings;Lcom/mojang/serialization/Lifecycle;)Lnet/minecraft/world/level/storage/PrimaryLevelData;"))
private static PrimaryLevelData impl$readSpongeLevelData(final Dynamic<Tag> p_237369_0_, final DataFixer p_237369_1_, final int p_237369_2_, final CompoundTag p_237369_3_, final LevelSettings p_237369_4_, final LevelVersion p_237369_5_, final WorldGenSettings p_237369_6_, final Lifecycle p_237369_7_) {
    final PrimaryLevelData levelData = PrimaryLevelData.parse(p_237369_0_, p_237369_1_, p_237369_2_, p_237369_3_, p_237369_4_, p_237369_5_, p_237369_6_, p_237369_7_);
    ((PrimaryLevelDataBridge) levelData).bridge$readSpongeLevelData(LevelStorageSourceMixin_Vanilla.impl$spongeLevelData);
    LevelStorageSourceMixin_Vanilla.impl$spongeLevelData = null;
    return levelData;
}
Also used : PrimaryLevelData(net.minecraft.world.level.storage.PrimaryLevelData) PrimaryLevelDataBridge(org.spongepowered.common.bridge.world.level.storage.PrimaryLevelDataBridge) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 3 with PrimaryLevelData

use of net.minecraft.world.level.storage.PrimaryLevelData in project SpongeCommon by SpongePowered.

the class SpongeWorldManager method loadProperties.

@Override
public CompletableFuture<Optional<ServerWorldProperties>> loadProperties(final ResourceKey key) {
    final net.minecraft.resources.ResourceKey<Level> registryKey = SpongeWorldManager.createRegistryKey(Objects.requireNonNull(key, "key"));
    if (this.worlds.get(registryKey) != null) {
        return CompletableFuture.completedFuture(Optional.empty());
    }
    if (!this.worldExists(key)) {
        return CompletableFuture.completedFuture(Optional.empty());
    }
    final boolean isVanillaWorld = this.isVanillaWorld(key);
    final String directoryName = this.getDirectoryName(key);
    final LevelStorageSource.LevelStorageAccess storageSource;
    try {
        if (isVanillaWorld) {
            storageSource = LevelStorageSource.createDefault(this.defaultWorldDirectory).createAccess(directoryName);
        } else {
            storageSource = LevelStorageSource.createDefault(this.customWorldsDirectory).createAccess(key.namespace() + File.separator + key.value());
        }
    } catch (final IOException e) {
        return FutureUtil.completedWithException(e);
    }
    final WorldData levelData;
    try {
        final PrimaryLevelData defaultLevelData = (PrimaryLevelData) this.server.getWorldData();
        final LevelSettings defaultLevelSettings = ((PrimaryLevelDataAccessor) defaultLevelData).accessor$settings();
        try {
            levelData = storageSource.getDataTag((DynamicOps<Tag>) BootstrapProperties.worldSettingsAdapter, defaultLevelSettings.getDataPackConfig());
        } catch (final Exception ex) {
            return FutureUtil.completedWithException(ex);
        }
    } finally {
        try {
            storageSource.close();
        } catch (final IOException ex) {
            return FutureUtil.completedWithException(ex);
        }
    }
    return this.loadTemplate(key).thenCompose(r -> {
        r.ifPresent(template -> {
            final LevelStem scratch = ((SpongeWorldTemplate) template).asDimension();
            ((PrimaryLevelDataBridge) levelData).bridge$populateFromDimension(scratch);
        });
        return CompletableFuture.completedFuture(Optional.of((ServerWorldProperties) levelData));
    });
}
Also used : ServerWorldProperties(org.spongepowered.api.world.server.storage.ServerWorldProperties) LevelStorageSource(net.minecraft.world.level.storage.LevelStorageSource) IOException(java.io.IOException) WorldData(net.minecraft.world.level.storage.WorldData) PrimaryLevelDataBridge(org.spongepowered.common.bridge.world.level.storage.PrimaryLevelDataBridge) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ReportedException(net.minecraft.ReportedException) PrimaryLevelData(net.minecraft.world.level.storage.PrimaryLevelData) LevelStem(net.minecraft.world.level.dimension.LevelStem) Level(net.minecraft.world.level.Level) ServerLevel(net.minecraft.server.level.ServerLevel) LevelSettings(net.minecraft.world.level.LevelSettings) PrimaryLevelDataAccessor(org.spongepowered.common.accessor.world.level.storage.PrimaryLevelDataAccessor) DynamicOps(com.mojang.serialization.DynamicOps)

Example 4 with PrimaryLevelData

use of net.minecraft.world.level.storage.PrimaryLevelData in project SpongeCommon by SpongePowered.

the class SpongeWorldManager method prepareWorld.

private ServerLevel prepareWorld(final ServerLevel world, final boolean isDebugGeneration) {
    final boolean isDefaultWorld = Level.OVERWORLD.equals(world.dimension());
    final PrimaryLevelData levelData = (PrimaryLevelData) world.getLevelData();
    if (isDefaultWorld) {
        // Initialize scoreboard data. This will hook to the ServerScoreboard, needs to be made multi-world aware
        ((MinecraftServerAccessor) this.server).accessor$readScoreboard(world.getDataStorage());
        ((MinecraftServerAccessor) this.server).accessor$commandStorage(new CommandStorage(world.getDataStorage()));
    }
    final boolean isInitialized = levelData.isInitialized();
    SpongeCommon.post(SpongeEventFactory.createLoadWorldEvent(PhaseTracker.getCauseStackManager().currentCause(), (org.spongepowered.api.world.server.ServerWorld) world, isInitialized));
    PlatformHooks.INSTANCE.getWorldHooks().postLoadWorld(world);
    // Set the view distance back on it's self to trigger the logic
    ((PrimaryLevelDataBridge) world.getLevelData()).bridge$viewDistance().ifPresent(v -> ((PrimaryLevelDataBridge) world.getLevelData()).bridge$setViewDistance(v));
    world.getWorldBorder().applySettings(levelData.getWorldBorder());
    if (!isInitialized) {
        try {
            final boolean hasSpawnAlready = ((PrimaryLevelDataBridge) world.getLevelData()).bridge$customSpawnPosition();
            if (!hasSpawnAlready) {
                if (isDefaultWorld || ((ServerWorldProperties) world.getLevelData()).performsSpawnLogic()) {
                    MinecraftServerAccessor.invoker$setInitialSpawn(world, levelData, levelData.worldGenSettings().generateBonusChest(), isDebugGeneration, !isDebugGeneration);
                } else if (Level.END.equals(world.dimension())) {
                    ((PrimaryLevelData) world.getLevelData()).setSpawn(ServerLevel.END_SPAWN_POINT, 0);
                }
            } else {
                Features.BONUS_CHEST.place(world, world.getChunkSource().getGenerator(), world.random, new BlockPos(levelData.getXSpawn(), levelData.getYSpawn(), levelData.getZSpawn()));
            }
            levelData.setInitialized(true);
            if (isDebugGeneration) {
                ((MinecraftServerAccessor) this.server).invoker$setupDebugLevel(levelData);
            }
        } catch (final Throwable throwable) {
            final CrashReport crashReport = CrashReport.forThrowable(throwable, "Exception initializing world '" + world.dimension().location() + "'");
            try {
                world.fillReportDetails(crashReport);
            } catch (final Throwable ignore) {
            }
            throw new ReportedException(crashReport);
        }
        levelData.setInitialized(true);
    }
    // Initialize PlayerData in PlayerList, add WorldBorder listener. We change the method in PlayerList to handle per-world border
    this.server.getPlayerList().setLevel(world);
    if (levelData.getCustomBossEvents() != null) {
        ((ServerLevelBridge) world).bridge$getBossBarManager().load(levelData.getCustomBossEvents());
    }
    return world;
}
Also used : PrimaryLevelData(net.minecraft.world.level.storage.PrimaryLevelData) MinecraftServerAccessor(org.spongepowered.common.accessor.server.MinecraftServerAccessor) CrashReport(net.minecraft.CrashReport) CommandStorage(net.minecraft.world.level.storage.CommandStorage) BlockPos(net.minecraft.core.BlockPos) PrimaryLevelDataBridge(org.spongepowered.common.bridge.world.level.storage.PrimaryLevelDataBridge) ReportedException(net.minecraft.ReportedException)

Example 5 with PrimaryLevelData

use of net.minecraft.world.level.storage.PrimaryLevelData in project SpongeCommon by SpongePowered.

the class SpongeWorldManager method postWorldLoad.

private CompletableFuture<ServerLevel> postWorldLoad(final ServerLevel world, final boolean blocking) {
    final PrimaryLevelData levelData = (PrimaryLevelData) world.getLevelData();
    final PrimaryLevelDataBridge levelBridge = (PrimaryLevelDataBridge) levelData;
    final boolean isDefaultWorld = this.isDefaultWorld((ResourceKey) (Object) world.dimension().location());
    if (isDefaultWorld || levelBridge.bridge$performsSpawnLogic()) {
        MinecraftServerAccessor.accessor$LOGGER().info("Preparing start region for world '{}' ({})", world.dimension().location(), RegistryTypes.WORLD_TYPE.get().valueKey((WorldType) world.dimensionType()));
        if (blocking) {
            this.loadSpawnChunks(world);
            // Chunk are generated
            return CompletableFuture.completedFuture(world);
        } else {
            // Chunks are NOT generated yet BUT will be when the future returns
            return this.loadSpawnChunksAsync(world);
        }
    }
    // Chunks are NOT generated AND will not generate unless prompted
    return CompletableFuture.completedFuture(world);
}
Also used : PrimaryLevelData(net.minecraft.world.level.storage.PrimaryLevelData) WorldType(org.spongepowered.api.world.WorldType) JsonObject(com.google.gson.JsonObject) PrimaryLevelDataBridge(org.spongepowered.common.bridge.world.level.storage.PrimaryLevelDataBridge)

Aggregations

PrimaryLevelData (net.minecraft.world.level.storage.PrimaryLevelData)7 PrimaryLevelDataBridge (org.spongepowered.common.bridge.world.level.storage.PrimaryLevelDataBridge)6 ServerLevel (net.minecraft.server.level.ServerLevel)4 JsonObject (com.google.gson.JsonObject)3 IOException (java.io.IOException)3 ExecutionException (java.util.concurrent.ExecutionException)3 Level (net.minecraft.world.level.Level)3 LevelSettings (net.minecraft.world.level.LevelSettings)3 LevelStem (net.minecraft.world.level.dimension.LevelStem)3 LevelStorageSource (net.minecraft.world.level.storage.LevelStorageSource)3 WorldType (org.spongepowered.api.world.WorldType)3 MinecraftServerAccessor (org.spongepowered.common.accessor.server.MinecraftServerAccessor)3 PrimaryLevelDataAccessor (org.spongepowered.common.accessor.world.level.storage.PrimaryLevelDataAccessor)3 DynamicOps (com.mojang.serialization.DynamicOps)2 Map (java.util.Map)2 ReportedException (net.minecraft.ReportedException)2 Tag (net.minecraft.nbt.Tag)2 ChunkProgressListener (net.minecraft.server.level.progress.ChunkProgressListener)2 Difficulty (net.minecraft.world.Difficulty)2 VillageSiege (net.minecraft.world.entity.ai.village.VillageSiege)2