mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 02:57:37 +01:00
Use Hephaistos v2.4.0 to correctly handle world heights
Should fix https://github.com/Minestom/Minestom/issues/559
This commit is contained in:
parent
c949bdd5ba
commit
c46d7bf506
@ -1,5 +1,7 @@
|
||||
package net.minestom.demo;
|
||||
|
||||
import demo.commands.GamemodeCommand;
|
||||
import net.minestom.demo.commands.SaveCommand;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.Player;
|
||||
@ -28,10 +30,14 @@ public class MainDemo {
|
||||
GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
||||
globalEventHandler.addListener(PlayerLoginEvent.class, event -> {
|
||||
final Player player = event.getPlayer();
|
||||
player.setPermissionLevel(2);
|
||||
event.setSpawningInstance(instanceContainer);
|
||||
player.setRespawnPoint(new Pos(0, 42, 0));
|
||||
});
|
||||
|
||||
MinecraftServer.getCommandManager().register(new SaveCommand());
|
||||
MinecraftServer.getCommandManager().register(new GamemodeCommand());
|
||||
|
||||
// Start the server on port 25565
|
||||
minecraftServer.start("0.0.0.0", 25565);
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package net.minestom.demo.commands;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.command.CommandSender;
|
||||
import net.minestom.server.command.builder.Command;
|
||||
import net.minestom.server.command.builder.CommandContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* A simple shutdown command.
|
||||
*/
|
||||
public class SaveCommand extends Command {
|
||||
|
||||
public SaveCommand() {
|
||||
super("save");
|
||||
addSyntax(this::execute);
|
||||
}
|
||||
|
||||
private void execute(@NotNull CommandSender commandSender, @NotNull CommandContext commandContext) {
|
||||
for(var instance : MinecraftServer.getInstanceManager().getInstances()) {
|
||||
CompletableFuture<Void> instanceSave = instance.saveInstance().thenCompose(v -> instance.saveChunksToStorage());
|
||||
try {
|
||||
instanceSave.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
}
|
||||
}
|
||||
commandSender.sendMessage("Saving done!");
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ kotlin = "1.6.10"
|
||||
hydrazine = "1.7.2"
|
||||
dependencyGetter = "v1.0.1"
|
||||
minestomData = "801b8007cf"
|
||||
hephaistos = "2.3.2"
|
||||
hephaistos = "2.4.0"
|
||||
jetbrainsAnnotations = "23.0.0"
|
||||
|
||||
# Terminal / Logging
|
||||
|
@ -80,7 +80,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
}
|
||||
|
||||
private @NotNull CompletableFuture<@Nullable Chunk> loadMCA(Instance instance, int chunkX, int chunkZ) throws IOException, AnvilException {
|
||||
final RegionFile mcaFile = getMCAFile(chunkX, chunkZ);
|
||||
final RegionFile mcaFile = getMCAFile(instance, chunkX, chunkZ);
|
||||
if (mcaFile == null)
|
||||
return CompletableFuture.completedFuture(null);
|
||||
final ChunkColumn fileChunk = mcaFile.getChunk(chunkX, chunkZ);
|
||||
@ -113,8 +113,9 @@ public class AnvilLoader implements IChunkLoader {
|
||||
loadBlocks(chunk, fileChunk);
|
||||
loadTileEntities(chunk, fileChunk);
|
||||
// Lights
|
||||
for (var chunkSection : fileChunk.getSections().values()) {
|
||||
Section section = chunk.getSection(chunkSection.getY());
|
||||
for (int sectionY = chunk.getMinSection(); sectionY < chunk.getMaxSection(); sectionY++) {
|
||||
var section = chunk.getSection(sectionY);
|
||||
var chunkSection = fileChunk.getSection((byte) sectionY);
|
||||
section.setSkyLight(chunkSection.getSkyLights());
|
||||
section.setBlockLight(chunkSection.getBlockLights());
|
||||
}
|
||||
@ -122,7 +123,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
return CompletableFuture.completedFuture(chunk);
|
||||
}
|
||||
|
||||
private @Nullable RegionFile getMCAFile(int chunkX, int chunkZ) {
|
||||
private @Nullable RegionFile getMCAFile(Instance instance, int chunkX, int chunkZ) {
|
||||
final int regionX = CoordinatesKt.chunkToRegion(chunkX);
|
||||
final int regionZ = CoordinatesKt.chunkToRegion(chunkZ);
|
||||
return alreadyLoaded.computeIfAbsent(RegionFile.Companion.createFileName(regionX, regionZ), n -> {
|
||||
@ -131,7 +132,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
if (!Files.exists(regionPath)) {
|
||||
return null;
|
||||
}
|
||||
return new RegionFile(new RandomAccessFile(regionPath.toFile(), "rw"), regionX, regionZ);
|
||||
return new RegionFile(new RandomAccessFile(regionPath.toFile(), "rw"), regionX, regionZ, instance.getDimensionType().getMinY(), instance.getDimensionType().getMaxY()-1);
|
||||
} catch (IOException | AnvilException e) {
|
||||
EXCEPTION_MANAGER.handleException(e);
|
||||
return null;
|
||||
@ -219,7 +220,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
final int chunkZ = chunk.getChunkZ();
|
||||
RegionFile mcaFile;
|
||||
synchronized (alreadyLoaded) {
|
||||
mcaFile = getMCAFile(chunkX, chunkZ);
|
||||
mcaFile = getMCAFile(chunk.instance, chunkX, chunkZ);
|
||||
if (mcaFile == null) {
|
||||
final int regionX = CoordinatesKt.chunkToRegion(chunkX);
|
||||
final int regionZ = CoordinatesKt.chunkToRegion(chunkZ);
|
||||
@ -263,15 +264,17 @@ public class AnvilLoader implements IChunkLoader {
|
||||
}
|
||||
|
||||
private void save(Chunk chunk, ChunkColumn chunkColumn) {
|
||||
chunkColumn.changeVersion(SupportedVersion.Companion.getLatest());
|
||||
chunkColumn.setYRange(chunk.getMinSection()*16, chunk.getMaxSection()*16-1);
|
||||
List<NBTCompound> tileEntities = new ArrayList<>();
|
||||
chunkColumn.setGenerationStatus(ChunkColumn.GenerationStatus.Full);
|
||||
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
||||
for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
for (int y = 0; y < 256; y++) { // TODO don't hardcode world height
|
||||
for (int y = chunkColumn.getMinY(); y < chunkColumn.getMaxY(); y++) {
|
||||
final Block block = chunk.getBlock(x, y, z);
|
||||
// Block
|
||||
chunkColumn.setBlockState(x, y, z, new BlockState(block.name(), block.properties()));
|
||||
chunkColumn.setBiome(x, 0, z, chunk.getBiome(x, y, z).name().asString());
|
||||
chunkColumn.setBiome(x, y, z, chunk.getBiome(x, y, z).name().asString());
|
||||
|
||||
// Tile entity
|
||||
final BlockHandler handler = block.handler();
|
||||
|
@ -44,6 +44,7 @@ public abstract class Chunk implements Block.Getter, Block.Setter, Biome.Getter,
|
||||
|
||||
protected Instance instance;
|
||||
protected final int chunkX, chunkZ;
|
||||
protected final int minSection, maxSection;
|
||||
|
||||
// Options
|
||||
private final boolean shouldGenerate;
|
||||
@ -64,6 +65,8 @@ public abstract class Chunk implements Block.Getter, Block.Setter, Biome.Getter,
|
||||
this.chunkX = chunkX;
|
||||
this.chunkZ = chunkZ;
|
||||
this.shouldGenerate = shouldGenerate;
|
||||
this.minSection = instance.getDimensionType().getMinY() / CHUNK_SECTION_SIZE;
|
||||
this.maxSection = (instance.getDimensionType().getMinY() + instance.getDimensionType().getHeight()) / CHUNK_SECTION_SIZE;
|
||||
|
||||
final EntityTracker tracker = instance.getEntityTracker();
|
||||
this.viewers.updateTracker(toPosition(), tracker);
|
||||
@ -181,6 +184,24 @@ public abstract class Chunk implements Block.Getter, Block.Setter, Biome.Getter,
|
||||
return chunkZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lowest (inclusive) section Y available in this chunk
|
||||
*
|
||||
* @return the lowest (inclusive) section Y available in this chunk
|
||||
*/
|
||||
public int getMinSection() {
|
||||
return minSection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the highest (exclusive) section Y available in this chunk
|
||||
*
|
||||
* @return the highest (exclusive) section Y available in this chunk
|
||||
*/
|
||||
public int getMaxSection() {
|
||||
return maxSection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world position of this chunk.
|
||||
*
|
||||
|
@ -36,7 +36,6 @@ import static net.minestom.server.utils.chunk.ChunkUtils.toSectionRelativeCoordi
|
||||
*/
|
||||
public class DynamicChunk extends Chunk {
|
||||
|
||||
private final int minSection, maxSection;
|
||||
private List<Section> sections;
|
||||
|
||||
// Key = ChunkUtils#getBlockIndex
|
||||
@ -49,8 +48,6 @@ public class DynamicChunk extends Chunk {
|
||||
|
||||
public DynamicChunk(@NotNull Instance instance, int chunkX, int chunkZ) {
|
||||
super(instance, chunkX, chunkZ, true);
|
||||
this.minSection = instance.getDimensionType().getMinY() / CHUNK_SECTION_SIZE;
|
||||
this.maxSection = (instance.getDimensionType().getMinY() + instance.getDimensionType().getHeight()) / CHUNK_SECTION_SIZE;
|
||||
var sectionsTemp = new Section[maxSection - minSection];
|
||||
Arrays.setAll(sectionsTemp, value -> new Section());
|
||||
this.sections = List.of(sectionsTemp);
|
||||
@ -144,7 +141,7 @@ public class DynamicChunk extends Chunk {
|
||||
public @NotNull Biome getBiome(int x, int y, int z) {
|
||||
final Section section = getSectionAt(y);
|
||||
final int id = section.biomePalette()
|
||||
.get(toSectionRelativeCoordinate(x) / 4, y / 4, toSectionRelativeCoordinate(z) / 4);
|
||||
.get(toSectionRelativeCoordinate(x) / 4, toSectionRelativeCoordinate(y) / 4, toSectionRelativeCoordinate(z) / 4);
|
||||
return MinecraftServer.getBiomeManager().getById(id);
|
||||
}
|
||||
|
||||
|
@ -209,6 +209,10 @@ public class DimensionType {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getMaxY() {
|
||||
return getMinY() + getHeight();
|
||||
}
|
||||
|
||||
public int getLogicalHeight() {
|
||||
return this.logicalHeight;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user