Only map options if needed to replace seed (#1843)

* Only map options if needed to replace seed

* Add bukkit adapters.

Co-authored-by: wizjany <wizjany@gmail.com>
This commit is contained in:
Octavia Togami 2021-07-25 11:08:57 -07:00 committed by GitHub
parent f414af50f6
commit 8686672108
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 45 deletions

View File

@ -41,7 +41,6 @@
import com.sk89q.worldedit.fabric.mixin.AccessorLevelProperties;
import com.sk89q.worldedit.fabric.mixin.AccessorServerChunkManager;
import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -61,7 +60,6 @@
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
import net.minecraft.block.Block;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.ItemEntity;
@ -78,11 +76,11 @@
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.util.dynamic.RegistryOps;
import net.minecraft.util.dynamic.RegistryReadingOps;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
@ -325,30 +323,14 @@ private void doRegen(Region region, Extent extent, RegenOptions options) throws
LevelStorage levelStorage = LevelStorage.create(tempDir);
try (LevelStorage.Session session = levelStorage.createSession("WorldEditTempGen")) {
ServerWorld originalWorld = (ServerWorld) getWorld();
long seed = options.getSeed().orElse(originalWorld.getSeed());
AccessorLevelProperties levelProperties = (AccessorLevelProperties)
originalWorld.getServer().getSaveProperties();
GeneratorOptions originalOpts = levelProperties.getGeneratorOptions();
RegistryOps<NbtElement> nbtRegOps = RegistryOps.of(
NbtOps.INSTANCE,
((ExtendedMinecraftServer) originalWorld.getServer())
.getServerResourceManager().getResourceManager(),
(DynamicRegistryManager.Impl) originalWorld.getServer().getRegistryManager()
);
GeneratorOptions newOpts = GeneratorOptions.CODEC
.encodeStart(nbtRegOps, originalOpts)
.flatMap(tag ->
GeneratorOptions.CODEC.parse(
recursivelySetSeed(new Dynamic<>(nbtRegOps, tag), seed, new HashSet<>())
)
)
.get().map(
l -> l,
error -> {
throw new IllegalStateException("Unable to map GeneratorOptions: " + error.message());
}
);
long seed = options.getSeed().orElse(originalWorld.getSeed());
GeneratorOptions newOpts = options.getSeed().isPresent()
? replaceSeed(originalWorld, seed, originalOpts)
: originalOpts;
levelProperties.setGeneratorOptions(newOpts);
RegistryKey<World> worldRegKey = originalWorld.getRegistryKey();
@ -382,6 +364,33 @@ private void doRegen(Region region, Extent extent, RegenOptions options) throws
}
}
private GeneratorOptions replaceSeed(ServerWorld originalWorld, long seed, GeneratorOptions originalOpts) {
RegistryReadingOps<NbtElement> nbtRegReadOps = RegistryReadingOps.of(
NbtOps.INSTANCE,
originalWorld.getServer().getRegistryManager()
);
RegistryOps<NbtElement> nbtRegOps = RegistryOps.method_36574(
NbtOps.INSTANCE,
((ExtendedMinecraftServer) originalWorld.getServer())
.getServerResourceManager().getResourceManager(),
originalWorld.getServer().getRegistryManager()
);
return GeneratorOptions.CODEC
.encodeStart(nbtRegReadOps, originalOpts)
.flatMap(tag ->
GeneratorOptions.CODEC.parse(
recursivelySetSeed(new Dynamic<>(nbtRegOps, tag), seed, new HashSet<>())
)
)
.get()
.map(
l -> l,
error -> {
throw new IllegalStateException("Unable to map GeneratorOptions: " + error.message());
}
);
}
@SuppressWarnings("unchecked")
private Dynamic<NbtElement> recursivelySetSeed(Dynamic<NbtElement> dynamic, long seed, Set<Dynamic<NbtElement>> seen) {
if (!seen.add(dynamic)) {

View File

@ -41,7 +41,6 @@
import com.sk89q.worldedit.forge.internal.NBTConverter;
import com.sk89q.worldedit.forge.internal.TileEntityUtils;
import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.internal.util.BiomeMath;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
@ -62,7 +61,6 @@
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.inventory.IClearable;
@ -83,6 +81,7 @@
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.registry.DynamicRegistries;
import net.minecraft.util.registry.WorldGenSettingsExport;
import net.minecraft.util.registry.WorldSettingsImport;
import net.minecraft.world.Dimension;
import net.minecraft.world.World;
@ -335,30 +334,14 @@ private void doRegen(Region region, Extent extent, RegenOptions options) throws
SaveFormat levelStorage = SaveFormat.func_237269_a_(tempDir);
try (SaveFormat.LevelSave session = levelStorage.func_237274_c_("WorldEditTempGen")) {
ServerWorld originalWorld = (ServerWorld) getWorld();
long seed = options.getSeed().orElse(originalWorld.getSeed());
ServerWorldInfo levelProperties =
(ServerWorldInfo) originalWorld.getServer().func_240793_aU_();
DimensionGeneratorSettings originalOpts = levelProperties.field_237343_c_;
WorldSettingsImport<INBT> nbtRegOps = WorldSettingsImport.func_244335_a(
NBTDynamicOps.INSTANCE,
originalWorld.getServer().getDataPackRegistries().func_240970_h_(),
(DynamicRegistries.Impl) originalWorld.getServer().func_244267_aX()
);
Codec<DimensionGeneratorSettings> dimCodec = DimensionGeneratorSettings.field_236201_a_;
DimensionGeneratorSettings newOpts = dimCodec
.encodeStart(nbtRegOps, originalOpts)
.flatMap(tag ->
dimCodec.parse(
recursivelySetSeed(new Dynamic<>(nbtRegOps, tag), seed, new HashSet<>())
)
)
.get().map(
l -> l,
error -> {
throw new IllegalStateException("Unable to map GeneratorOptions: " + error.message());
}
);
long seed = options.getSeed().orElse(originalWorld.getSeed());
DimensionGeneratorSettings newOpts = options.getSeed().isPresent()
? replaceSeed(originalWorld, seed, originalOpts)
: originalOpts;
levelProperties.field_237343_c_ = newOpts;
RegistryKey<World> worldRegKey = originalWorld.func_234923_W_();
@ -393,6 +376,34 @@ private void doRegen(Region region, Extent extent, RegenOptions options) throws
}
}
private DimensionGeneratorSettings replaceSeed(ServerWorld originalWorld, long seed, DimensionGeneratorSettings originalOpts) {
WorldGenSettingsExport<INBT> nbtReadRegOps = WorldGenSettingsExport.func_240896_a_(
NBTDynamicOps.INSTANCE,
originalWorld.getServer().func_244267_aX()
);
WorldSettingsImport<INBT> nbtRegOps = WorldSettingsImport.func_244335_a(
NBTDynamicOps.INSTANCE,
originalWorld.getServer().getDataPackRegistries().func_240970_h_(),
(DynamicRegistries.Impl) originalWorld.getServer().func_244267_aX()
);
Codec<DimensionGeneratorSettings> dimCodec = DimensionGeneratorSettings.field_236201_a_;
DimensionGeneratorSettings newOpts = dimCodec
.encodeStart(nbtReadRegOps, originalOpts)
.flatMap(tag ->
dimCodec.parse(
recursivelySetSeed(new Dynamic<>(nbtRegOps, tag), seed, new HashSet<>())
)
)
.get()
.map(
l -> l,
error -> {
throw new IllegalStateException("Unable to map GeneratorOptions: " + error.message());
}
);
return newOpts;
}
@SuppressWarnings("unchecked")
private Dynamic<INBT> recursivelySetSeed(Dynamic<INBT> dynamic, long seed, Set<Dynamic<INBT>> seen) {
if (!seen.add(dynamic)) {