feat: support reload

This commit is contained in:
Christian Bergschneider 2025-01-04 00:08:14 +01:00
parent 35bdc99873
commit 7711e67999
No known key found for this signature in database
GPG Key ID: 3991F97F5FA28D3E
12 changed files with 49 additions and 165 deletions

View File

@ -17,14 +17,20 @@ import com.dfsek.terra.minestom.biome.MinestomBiomeLoader;
import com.dfsek.terra.minestom.entity.MinestomEntityType; import com.dfsek.terra.minestom.entity.MinestomEntityType;
import com.dfsek.terra.minestom.item.MinestomItemHandle; import com.dfsek.terra.minestom.item.MinestomItemHandle;
import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper;
import com.dfsek.terra.minestom.world.MinestomWorldHandle; import com.dfsek.terra.minestom.world.MinestomWorldHandle;
import net.minestom.server.MinecraftServer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.ArrayList;
public final class MinestomPlatform extends AbstractPlatform { public final class MinestomPlatform extends AbstractPlatform {
private static final Logger LOGGER = LoggerFactory.getLogger(MinestomPlatform.class);
private static MinestomPlatform INSTANCE = null; private static MinestomPlatform INSTANCE = null;
private final MinestomWorldHandle worldHandle = new MinestomWorldHandle(); private final MinestomWorldHandle worldHandle = new MinestomWorldHandle();
private final MinestomItemHandle itemHandle = new MinestomItemHandle(); private final MinestomItemHandle itemHandle = new MinestomItemHandle();
@ -45,7 +51,20 @@ public final class MinestomPlatform extends AbstractPlatform {
@Override @Override
public boolean reload() { public boolean reload() {
return false; getTerraConfig().load(this);
getRawConfigRegistry().clear();
boolean succeed = getRawConfigRegistry().loadAll(this);
MinecraftServer.getInstanceManager().getInstances().forEach(world -> {
if(world.generator() instanceof MinestomChunkGeneratorWrapper wrapper) {
getConfigRegistry().get(wrapper.getPack().getRegistryKey()).ifPresent(pack -> {
wrapper.setPack(pack);
LOGGER.info("Replaced pack in chunk generator for instance {}", world.getUniqueId());
});
}
});
return succeed;
} }
@Override @Override

View File

@ -1,19 +1,11 @@
package com.dfsek.terra.minestom; package com.dfsek.terra.minestom;
import com.dfsek.terra.minestom.api.filter.ChunkFilter;
import com.dfsek.terra.minestom.api.filter.EvenChunkFilter;
import com.dfsek.terra.minestom.api.filter.NoFeaturesFilter;
import com.dfsek.terra.minestom.api.filter.NoTerrainFilter;
import com.dfsek.terra.minestom.api.filter.SpecificChunkFilter;
import com.dfsek.terra.minestom.api.filter.XFilter;
import com.dfsek.terra.minestom.api.filter.ZFilter;
import com.dfsek.terra.minestom.world.TerraMinestomWorld; import com.dfsek.terra.minestom.world.TerraMinestomWorld;
import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder; import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.command.builder.Command; import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.arguments.ArgumentLiteral;
import net.minestom.server.command.builder.arguments.number.ArgumentInteger; import net.minestom.server.command.builder.arguments.number.ArgumentInteger;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode; import net.minestom.server.entity.GameMode;
@ -21,7 +13,6 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.event.player.PlayerSpawnEvent;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.instance.LightingChunk; import net.minestom.server.instance.LightingChunk;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -40,11 +31,9 @@ public class TerraMinestomExample {
instance.setChunkSupplier(LightingChunk::new); instance.setChunkSupplier(LightingChunk::new);
} }
public void attachTerra(ChunkFilter filter) { public void attachTerra() {
world = TerraMinestomWorldBuilder.from(instance) world = TerraMinestomWorldBuilder.from(instance)
.defaultPack() .defaultPack()
// .seed(0)
.filtered(filter)
.attach(); .attach();
} }
@ -117,7 +106,7 @@ public class TerraMinestomExample {
public static void main(String[] args) { public static void main(String[] args) {
TerraMinestomExample example = new TerraMinestomExample(); TerraMinestomExample example = new TerraMinestomExample();
example.createNewInstance(); example.createNewInstance();
example.attachTerra(null); example.attachTerra();
example.preloadWorldAndMeasure(); example.preloadWorldAndMeasure();
example.addScheduler(); example.addScheduler();
example.addListeners(); example.addListeners();
@ -128,27 +117,13 @@ public class TerraMinestomExample {
public class RegenerateCommand extends Command { public class RegenerateCommand extends Command {
public RegenerateCommand() { public RegenerateCommand() {
super("regenerate"); super("regenerate");
setDefaultExecutor((sender, context) -> regenerate());
ArgumentInteger cx = new ArgumentInteger("cx");
ArgumentInteger cz = new ArgumentInteger("cz");
setDefaultExecutor((sender, context) -> regenerate(null));
addSyntax((sender, context) -> regenerate(new NoFeaturesFilter()), new ArgumentLiteral("noFeatures"));
addSyntax((sender, context) -> regenerate(new NoTerrainFilter()), new ArgumentLiteral("noTerrain"));
addSyntax((sender, context) -> regenerate(new EvenChunkFilter()), new ArgumentLiteral("evenChunks"));
addSyntax((sender, context) -> regenerate(new SpecificChunkFilter(context.get(cx), context.get(cz))), new ArgumentLiteral("chunk"), cx, cz);
addSyntax((sender, context) -> regenerate(new XFilter(context.get(cx))), new ArgumentLiteral("x"), cx);
addSyntax((sender, context) -> regenerate(new ZFilter(context.get(cz))), new ArgumentLiteral("z"), cz);
} }
private void regenerate(@Nullable ChunkFilter filter) { private void regenerate() {
if (filter == null) { instance.sendMessage(Component.text("Regenerating world"));
instance.sendMessage(Component.text("Regenerating world without filter "));
} else {
instance.sendMessage(Component.text("Regenerating world with filter " + filter.getClass().getSimpleName()));
}
createNewInstance(); createNewInstance();
attachTerra(filter); attachTerra();
preloadWorldAndMeasure(); preloadWorldAndMeasure();
MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player -> MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player ->
player.setInstance(instance, new Pos(0, 100, 0)) player.setInstance(instance, new Pos(0, 100, 0))

View File

@ -1,12 +0,0 @@
package com.dfsek.terra.minestom.api.filter;
/**
* This interface defines a filter for determining whether terrain and features
* should be placed during chunk generation. Implementations of this interface
* can apply custom logic to selectively control terrain and feature placement
* in specific chunks for debugging purposes.
*/
public interface ChunkFilter {
boolean shouldPlaceTerrain(int x, int z);
boolean shouldPlaceFeatures(int x, int z);
}

View File

@ -1,13 +0,0 @@
package com.dfsek.terra.minestom.api.filter;
public class EvenChunkFilter implements ChunkFilter {
@Override
public boolean shouldPlaceTerrain(int x, int z) {
return x % 2 == 0 && z % 2 == 0;
}
@Override
public boolean shouldPlaceFeatures(int x, int z) {
return x % 2 == 0 && z % 2 == 0;
}
}

View File

@ -1,13 +0,0 @@
package com.dfsek.terra.minestom.api.filter;
public class NoFeaturesFilter implements ChunkFilter {
@Override
public boolean shouldPlaceTerrain(int x, int z) {
return true;
}
@Override
public boolean shouldPlaceFeatures(int x, int z) {
return false;
}
}

View File

@ -1,13 +0,0 @@
package com.dfsek.terra.minestom.api.filter;
public class NoTerrainFilter implements ChunkFilter {
@Override
public boolean shouldPlaceTerrain(int x, int z) {
return false;
}
@Override
public boolean shouldPlaceFeatures(int x, int z) {
return true;
}
}

View File

@ -1,21 +0,0 @@
package com.dfsek.terra.minestom.api.filter;
public class SpecificChunkFilter implements ChunkFilter {
private final int x;
private final int z;
public SpecificChunkFilter(int x, int z) {
this.x = x;
this.z = z;
}
@Override
public boolean shouldPlaceTerrain(int x, int z) {
return this.x == x && this.z == z;
}
@Override
public boolean shouldPlaceFeatures(int x, int z) {
return this.x == x && this.z == z;
}
}

View File

@ -1,17 +0,0 @@
package com.dfsek.terra.minestom.api.filter;
public class XFilter implements ChunkFilter {
private final int x;
public XFilter(int x) { this.x = x; }
@Override
public boolean shouldPlaceTerrain(int x, int z) {
return this.x == x;
}
@Override
public boolean shouldPlaceFeatures(int x, int z) {
return this.x == x;
}
}

View File

@ -1,17 +0,0 @@
package com.dfsek.terra.minestom.api.filter;
public class ZFilter implements ChunkFilter {
private final int z;
public ZFilter(int z) { this.z = z; }
@Override
public boolean shouldPlaceTerrain(int x, int z) {
return this.z == z;
}
@Override
public boolean shouldPlaceFeatures(int x, int z) {
return this.z == z;
}
}

View File

@ -1,9 +1,9 @@
package com.dfsek.terra.minestom.world; package com.dfsek.terra.minestom.world;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
import com.dfsek.terra.minestom.api.filter.ChunkFilter;
import com.dfsek.terra.minestom.chunk.CachedChunk; import com.dfsek.terra.minestom.chunk.CachedChunk;
import com.dfsek.terra.minestom.chunk.GeneratedChunkCache; import com.dfsek.terra.minestom.chunk.GeneratedChunkCache;
@ -15,14 +15,14 @@ import org.jetbrains.annotations.NotNull;
public class MinestomChunkGeneratorWrapper implements Generator { public class MinestomChunkGeneratorWrapper implements Generator {
private final GeneratedChunkCache cache; private final GeneratedChunkCache cache;
private final ChunkGenerator generator; private ChunkGenerator generator;
private final TerraMinestomWorld world; private final TerraMinestomWorld world;
private final ChunkFilter filter; private ConfigPack pack;
public MinestomChunkGeneratorWrapper(ChunkGenerator generator, TerraMinestomWorld world, ChunkFilter filter) { public MinestomChunkGeneratorWrapper(ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) {
this.generator = generator; this.generator = generator;
this.world = world; this.world = world;
this.filter = filter; this.pack = pack;
this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world); this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world);
} }
@ -36,10 +36,8 @@ public class MinestomChunkGeneratorWrapper implements Generator {
int x = start.chunkX(); int x = start.chunkX();
int z = start.chunkZ(); int z = start.chunkZ();
CachedChunk chunk = cache.at(x, z); CachedChunk chunk = cache.at(x, z);
if(filter == null || filter.shouldPlaceTerrain(x, z))
chunk.writeRelative(unit.modifier()); chunk.writeRelative(unit.modifier());
if(filter == null || filter.shouldPlaceFeatures(x, z)) {
unit.fork(setter -> { unit.fork(setter -> {
MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter); MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter);
@ -48,6 +46,14 @@ public class MinestomChunkGeneratorWrapper implements Generator {
} }
}); });
} }
public ConfigPack getPack() {
return pack;
}
public void setPack(ConfigPack pack) {
this.pack = pack;
this.generator = pack.getGeneratorProvider().newInstance(pack);
} }
public void displayStats() { public void displayStats() {

View File

@ -16,7 +16,6 @@ import com.dfsek.terra.api.world.info.WorldProperties;
import com.dfsek.terra.minestom.api.BlockEntityFactory; import com.dfsek.terra.minestom.api.BlockEntityFactory;
import com.dfsek.terra.minestom.api.EntityFactory; import com.dfsek.terra.minestom.api.EntityFactory;
import com.dfsek.terra.minestom.block.MinestomBlockState; import com.dfsek.terra.minestom.block.MinestomBlockState;
import com.dfsek.terra.minestom.api.filter.ChunkFilter;
import com.dfsek.terra.minestom.entity.MinestomEntity; import com.dfsek.terra.minestom.entity.MinestomEntity;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
@ -43,7 +42,6 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
ConfigPack pack, ConfigPack pack,
long seed, long seed,
EntityFactory entityFactory, EntityFactory entityFactory,
ChunkFilter filter,
BlockEntityFactory blockEntityFactory BlockEntityFactory blockEntityFactory
) { ) {
this.instance = instance; this.instance = instance;
@ -56,7 +54,7 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
this.wrapper = new MinestomChunkGeneratorWrapper( this.wrapper = new MinestomChunkGeneratorWrapper(
pack.getGeneratorProvider().newInstance(pack), pack.getGeneratorProvider().newInstance(pack),
this, this,
filter pack
); );
this.entityFactory = entityFactory; this.entityFactory = entityFactory;

View File

@ -7,12 +7,10 @@ import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.minestom.MinestomPlatform; import com.dfsek.terra.minestom.MinestomPlatform;
import com.dfsek.terra.minestom.api.BlockEntityFactory; import com.dfsek.terra.minestom.api.BlockEntityFactory;
import com.dfsek.terra.minestom.api.EntityFactory; import com.dfsek.terra.minestom.api.EntityFactory;
import com.dfsek.terra.minestom.api.filter.ChunkFilter;
import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory; import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory;
import com.dfsek.terra.minestom.entity.DefaultEntityFactory; import com.dfsek.terra.minestom.entity.DefaultEntityFactory;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.Nullable;
import java.util.Random; import java.util.Random;
import java.util.function.Function; import java.util.function.Function;
@ -23,7 +21,6 @@ public class TerraMinestomWorldBuilder {
private ConfigPack pack; private ConfigPack pack;
private long seed = new Random().nextLong(); private long seed = new Random().nextLong();
private EntityFactory entityFactory = new DefaultEntityFactory(); private EntityFactory entityFactory = new DefaultEntityFactory();
private ChunkFilter filter;
private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory(); private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory();
private TerraMinestomWorldBuilder(Instance instance) { this.instance = instance; } private TerraMinestomWorldBuilder(Instance instance) { this.instance = instance; }
@ -75,12 +72,7 @@ public class TerraMinestomWorldBuilder {
return this; return this;
} }
public TerraMinestomWorldBuilder filtered(@Nullable ChunkFilter filter) {
this.filter = filter;
return this;
}
public TerraMinestomWorld attach() { public TerraMinestomWorld attach() {
return new TerraMinestomWorld(instance, pack, seed, entityFactory, filter, blockEntityFactory); return new TerraMinestomWorld(instance, pack, seed, entityFactory, blockEntityFactory);
} }
} }