Coder Social home page Coder Social logo

hephaistos's Introduction

banner banner

Minestom

license standard-readme compliant
javadocs wiki discord-banner

Minestom is an open-source library that enables developers to create their own Minecraft server software, without any code from Mojang.

The main difference between Mojang's vanilla server and a minestom-based server, is that ours does not contain any features by default! However, we have a complete API which is designed to allow you to make anything possible, with ease.

This is a developer API not meant to be used by end-users. Replacing Bukkit/Forge/Sponge with this will not work since we do not implement any of their APIs.

Table of contents

Install

Minestom is not installed like Bukkit/Forge/Sponge. As Minestom is a Java library, it must be loaded the same way any other Java library may be loaded. This means you need to add Minestom as a dependency, add your code and compile by yourself.

Minestom is available on Maven Central, and can be installed like the following (Gradle/Groovy):

repositories {
    mavenCentral()
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'net.minestom:minestom-snapshots:<???>'
}

Usage

An example of how to use the Minestom library is available here. Alternatively you can check the official wiki or the javadocs.

Why Minestom?

Minecraft has evolved a lot since its release, most of the servers today do not take advantage of vanilla features and even have to struggle because of them. Our target audience is those who want to make a server that benefits little from vanilla features. e.g. creative, kitpvp. The goal is to offer more performance for those who need it. In other words, it makes sense to use Minestom when it takes less time to implement every missing vanilla feature you want than removing every vanilla feature that will slow you down.

Advantages and Disadvantages

Minestom isn't perfect, our choices make it much better for some cases, worse for some others.

Advantages

  • Remove the overhead of vanilla features
  • Multi-threaded
  • Instance system (Collections of blocks and entities) which is much more scalable than worlds
  • Open-source
  • Modern API
  • No more legacy NMS

Disadvantages

  • Does not work with Bukkit/Forge/Sponge plugins or mods
  • Does not work with older clients (using a proxy with ViaBackwards is possible)
  • Bad for those who want a vanilla experience
  • Longer to develop something playable
  • Multi-threaded environments need extra consideration

API

Even if we do not include anything by default in the game, we simplify the way you add them, here is a preview.

Instances

It is our major concept, worlds are great for survival with friends, but when it scales up it can become unmanageable. The best examples can be found in Skyblock or minigames, not being able to separate each part properly and being forced to save everything in files, not to say the overhead caused by unnecessary data contained in them. Instances are a lightweight solution to it, being able to have every chunk in memory only, copying and sending it to another player in no time, with custom serialization and much more...

Being able to create instances directly on the go is a must-have, we believe it can push many more projects forward.

Instances also come with performance benefits, unlike some others which will be fully single-threaded or maybe using one thread per world we are using a set number of threads (pool) to manage all chunks independently from instances, meaning using more CPU power.

Blocks

Minestom by default does not know what is a chest, you will have to tell him that it opens an inventory. Every "special blocks" (which aren't only visual) need a specialized handler. After applying this handler, you have a block that can be placed anywhere simply. However, all blocks are visually there, they just won't have interaction by default.

Entities

The terms "passive" or "aggressive" monsters do not exist, nobody stops you from making a flying chicken rushing into any players coming too close, doing so with NMS is a real mess because of obfuscation and the large inheritance.

Inventories

It is a field where Minecraft evolved a lot, inventories are now used a lot as client<->server interface with clickable items and callback, we support these interactions natively without the need of programming your solution.

Commands

Commands are the simplest way of communication between clients and server. Since 1.13 Minecraft has incorporated a new library denominated "Brigadier", we then integrated an API designed to use the full potential of args types.

Credits

Contributing

See the contributing file! All WIP features are previewed as Draft PRs

License

This project is licensed under the Apache License Version 2.0.

hephaistos's People

Contributors

jglrxavpok avatar kezz avatar kodingdev avatar leodog896 avatar notthatrqd avatar outroddet avatar stepbystepler avatar themode avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

hephaistos's Issues

Proposal: Highlighting

In order to have fancy debug messages, there should be another module to hook into the SNBTReader and highlight certain parts of the NBT syntax.

Chunk file at [0, 23] is missing level data in minecraft logs when loading a modifed world

Minecraft version: 1.15.2
Java version : openjdk 17.0.3 2022-04-19
Hephaistos version: 2.4.8

I try to use the lib to fix a map that i receive, but the map contains tile entities with the name "Banner" but minecraft only accept tile entity id in lowercase.

Non [a-z0-9/._-] character in path of location: minecraft:Banner

So i made a script with java to fix the map but each time i open it with my game, minecraft find that the data is missing.

Chunk file at [24, 23] is missing level data, skipping

Here is the full code i use:

Path path = Path.of("map"); //Old map that need to be fixed
Path newPath = Path.of("newMap"); //Fixed map
Path regionPath = path.resolve("region");
Path newRegionPath = newPath.resolve("region");

Map<Pair<Integer, Integer>, RegionFile> regions = new HashMap<>();
Map<Pair<Integer, Integer>, RegionFile> newRegions = new HashMap<>();

for (int x = -4; x <= 3; x++) {
    for (int z = -4; z <= 3; z++) {
        var filename = RegionFile.Companion.createFileName(x, z);
        var path1 = regionPath.resolve(filename);
        var path2 = newRegionPath.resolve(filename);
        var tuple = new Pair<>(x, z);
        regions.put(tuple, new RegionFile(new RandomAccessFile(path1.toFile(), "r"), x, z));
        newRegions.put(tuple, new RegionFile(new RandomAccessFile(path2.toFile(), "rw"), x, z));
    }
}

ExecutorService executorService = Executors.newFixedThreadPool(6, runnable -> new Thread(runnable, "ScrapperThread"));

System.out.println("Regions loaded");

List<Future<?>> futures = new ArrayList<>();

regions.forEach((t, regionFile) -> {
    var regionX = regionFile.getRegionX();
    var regionZ = regionFile.getRegionZ();
    var newRegionFile = newRegions.get(t);

    futures.add(executorService.submit(() -> {
        try {
            for (int i = 0; i < 32; i++) {
                for (int z = 0; z < 32; z++) {
                    final var chunkX = regionX * 32 + i;
                    final var chunkZ = regionZ * 32 + z;
                    ChunkColumn chunkColumn = regionFile.getChunk(chunkX, chunkZ);
                    if (chunkColumn != null) {
                        List<NBTCompound> tilesEntities = chunkColumn.getTileEntities().asListView().stream().map(te -> {
                            var entityId = te.getString("id");
                            if (entityId == null) return te;
                            MutableNBTCompound mutable = te.toMutableCompound();
                            if (entityId.equals("Banner"))
                                mutable.setString("id", "banner");
                            return mutable.toCompound();
                        }).toList();
                        chunkColumn.setTileEntities(NBT.List(NBTType.TAG_Compound, tilesEntities));
                        newRegionFile.writeColumn(chunkColumn);
                        regionFile.forget(chunkColumn);
                    }
                }
            }
            regionFile.close();
            System.out.println("Region " + regionX + " " + regionZ + " finished");
        } catch (Exception e) {
            System.out.println("Exception as occurred: " + regionX + " " + regionZ);
            e.printStackTrace();
        }
    }));
});
for (Future<?> future : futures) {
    future.get();
}
System.out.println("Task finished");

List of proposals for v2

@jglrxavpok told me to make an issue with these, for easier tracking, so here we are.

Here's the list of proposals I have for things in v2:

  • Make NBTEnd an object, since it only needs one instance and doesn't ever need to be copied.
  • Add an EMPTY constant for NBTCompound, which is an immutable compound with an empty backing map. Also add one for NBTList, which is an immutable list with elements of type TAG_End backed by an empty list.
  • Add ONE and ZERO constants for NBTByte, which are both immutable with backing values of 1 and 0 respectively (for easier boolean conversions).
  • Allow getting/setting booleans on compounds, with functions such as getBoolean/setBoolean.
  • Add a new method for getting every type from a compound with a default value, and these methods should never return null. For example, getString("my_key", "my_default") would look for a string in the map with the key "my_key", or else it would return "my_default" if no such value was found.
  • Add constructors to NBTList and NBTCompound that accept lists and maps respectively, for easier construction.
  • Expose the backing map of an NBTCompound and the backing list of an NBTList in some way, whether this be an immutable copy, or just the actual map itself.
  • Possibly add a better way to read compound tags, instead of having to construct a new reader and then read and perform an unchecked cast.
  • Add support for ZLIB compression when reading/writing NBT data. For reference, Adventure does this by having a compression type pseudo enum with compress and decompress methods that are implemented in their respective types, perhaps you could do something similar?
  • Support initialising the NBTReader and NBTWriter with a Path object as well as with a File.
  • Support for calls like getOrElse and getOrNull on an NBTList. Would probably be better if NBTList just implemented List<Tag> instead of Iterable<Tag>.

Hope this helps you keep track of everything!

NBT DSL

Everything is in the title.

Provide a DSL to write NBT with Kotlin & Java.

Cannot load entities from world

Hi. I'm trying to load entities from saved world, but when I call ChunkColumn.getEntities(), it returns []. I tried to do it on Minestom, and opened discussion, because this attempt failed. I think, that this is Hephaitos problem, because this error related to chunk loader.

divided by zero exception

#23
Here is the new code:
(ChunkSection.kt line 151)

val sizeInBits = ceil(log2(biomePalette.elements.size.toDouble())).toInt()
val intPerLong = 64 / sizeInBits

Obviously,as log2(1)=0,it will throw /0 exception when a chunk has only 1 biome.
Sorry for my bad English.
B`Q$P6{T)02V_${}{WW}LC4

Error when loading SNBT with \u unicode

Example, in Minestom when you get an item with custom lore or other (exp: minecraft:oak_sign{BlockEntityTag:{Text1:'{"text":"","clickEvent":{"action":"run_command","value":"say YOLO"}}',Text2:'["",{"text":"Zebi la "},{"text":"mouche","bold":true,"color":"dark_red"}]'},display:{Name:'{"text":"Y\\u00e9"}'}})

And you save that

For the loading, you get this error:

[Ms-TickScheduler] [23:00:52] (ExceptionHandler.handleException) - ERROR - Error: java.lang.IllegalStateException: Unrecognized escape sequence: \u: java.lang.IllegalStateException: Unrecognized escape sequence: \u
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.unescape(SNBTParsingVisitor.kt:88)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitStringNBT(SNBTParsingVisitor.kt:101)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitStringNBT(SNBTParsingVisitor.kt:8)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$StringNBTContext.accept(SNBTParser.java:1098)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:46)
	at org.jglrxavpok.hephaistos.antlr.SNBTBaseVisitor.visitElement(SNBTBaseVisitor.java:27)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$ElementContext.accept(SNBTParser.java:197)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor$visitCompound$$inlined$Kompound$1.run(NBT.kt:224)
	at org.jglrxavpok.hephaistos.nbt.NBT$Companion.Compound(NBT.kt:108)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitCompound(SNBTParsingVisitor.kt:115)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitCompound(SNBTParsingVisitor.kt:8)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$CompoundContext.accept(SNBTParser.java:327)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:46)
	at org.jglrxavpok.hephaistos.antlr.SNBTBaseVisitor.visitElement(SNBTBaseVisitor.java:27)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$ElementContext.accept(SNBTParser.java:197)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor$visitCompound$$inlined$Kompound$1.run(NBT.kt:224)
	at org.jglrxavpok.hephaistos.nbt.NBT$Companion.Compound(NBT.kt:108)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitCompound(SNBTParsingVisitor.kt:115)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitCompound(SNBTParsingVisitor.kt:8)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$CompoundContext.accept(SNBTParser.java:327)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:46)
	at org.jglrxavpok.hephaistos.antlr.SNBTBaseVisitor.visitElement(SNBTBaseVisitor.java:27)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$ElementContext.accept(SNBTParser.java:197)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor$visitCompound$$inlined$Kompound$1.run(NBT.kt:224)
	at org.jglrxavpok.hephaistos.nbt.NBT$Companion.Compound(NBT.kt:108)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitCompound(SNBTParsingVisitor.kt:115)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitCompound(SNBTParsingVisitor.kt:8)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$CompoundContext.accept(SNBTParser.java:327)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:46)
	at org.jglrxavpok.hephaistos.antlr.SNBTBaseVisitor.visitElement(SNBTBaseVisitor.java:27)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$ElementContext.accept(SNBTParser.java:197)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor$visitCompound$$inlined$Kompound$1.run(NBT.kt:224)
	at org.jglrxavpok.hephaistos.nbt.NBT$Companion.Compound(NBT.kt:108)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitCompound(SNBTParsingVisitor.kt:115)
	at org.jglrxavpok.hephaistos.SNBTParsingVisitor.visitCompound(SNBTParsingVisitor.kt:8)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$CompoundContext.accept(SNBTParser.java:327)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:46)
	at org.jglrxavpok.hephaistos.antlr.SNBTBaseVisitor.visitElement(SNBTBaseVisitor.java:27)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$ElementContext.accept(SNBTParser.java:197)
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:46)
	at org.jglrxavpok.hephaistos.antlr.SNBTBaseVisitor.visitSnbt(SNBTBaseVisitor.java:20)
	at org.jglrxavpok.hephaistos.antlr.SNBTParser$SnbtContext.accept(SNBTParser.java:118)
	at org.jglrxavpok.hephaistos.parser.SNBTParser.parse(SNBTParser.kt:26)
	at fr.als.core.player.data.PlayerDataLoader.read(PlayerDataLoader.java:114)

Incorrect String Escaping in SNBTParser

Deserializing the following String results in incorrectly escaped output.

String input = "{\"Unbreakable\":1B,\"CustomModelData\":22,\"item_id\":\"test_back\",\"display\":{\"Lore\":[\"{\\\"text\\\":\\\"This is a test backpack! Used for wearing and testing! Put it on your back slot!\\\"}\"],\"Name\":\"{\\\"text\\\":\\\"Test Backpack\\\"}\"}}";
NBTCompound compound;
try {
        compound = (NBTCompound) new SNBTParser(new StringReader(input)).parse();
} catch (final NBTException e) {
        throw new RuntimeException(e);
}

Output:
{"Unbreakable":1B,"CustomModelData":22,"item_id":"test_back","display":{"Lore":["{\\"text\\":\\"This is a test backpack! Used for wearing and testing! Put it on your back slot!\\"}"],"Name":"{\\"text\\":\\"Test Backpack\\"}"}}

Expected Output:
{"Unbreakable":1B,"CustomModelData":22,"item_id":"test_back","display":{"Lore":["{\"text\":\"This is a test backpack! Used for wearing and testing! Put it on your back slot!\"}"],"Name":"{\"text\":\"Test Backpack\"}"}}

It should be possible to run compound.toString() back through an SNBTParser. Trying to do so with this incorrect escaping, like so:

String result = compound.toString(); //This should be the same as input
try {
        compound = (NBTCompound) new SNBTParser(new StringReader(result)).parse();
} catch (final NBTException e) {
        throw new RuntimeException(e);
}

Throws an error:

Caused by: com.google.gson.stream.MalformedJsonException: Expected name at line 1 column 2 path $.

Big floating point variables cannot be parsed

Deserializing following NBT's results in scientific notation number, which throws exception when trying to parse it.

val double = NBTDouble(10000000.0)
val float = NBTFloat(10000000F)
// Double -> 1.0E7D
// Float -> 1.0E7F

val doubleSNBT = double.toSNBT()
val floatSNBT = float.toSNBT()

try {
    SNBTParser(StringReader(doubleSNBT)).parse()
} catch (ex: NBTException) { ex.printStackTrace() }

try {
     SNBTParser(StringReader(floatSNBT)).parse()
} catch (ex: NBTException) { ex.printStackTrace() }

Throws:

Double: Failed to parse SNBT: Line 1, column 3 extraneous input 'E7D' expecting (EOF) ( {',', '}'} when parsing NBTCompound )
Float: Failed to parse SNBT: Line 1, column 3 extraneous input 'E7F' expecting (EOF)

Bug: ChunkReader.getYRange() includes empty chunk sections

You can see Eoghanmc22 and I as we were figuring this out here in the Minestom discord server

When placing a block that emits light at the height limit* (y=319) a server like Paper will save a chunk section with the lighting information. getYRange() should not include chunk sections that can not have blocks and do not have any block data, or there should be a separate function for Y range only including chunk sections with block data.

image

The chunk with a Y of 20 should be ignored because it is past the build height and has no block data

*This also probably happens when placing a block that emits light at the height min, but I haven't tested it

Create a new NBTParser class for snbt & path lookup

Deprecate SNBTParser in favor of a new NBTParser class hosting various static utils

NBT parseSnbt(String snbt)

NBT extractPath(NBTCompound compound, String path)

String extractPath(String compoundSnbt, String path)

NBTCompound replacePath(NBTCompound compound, String path, NBT nbt)

String replacePath(String compoundSnbt, String path, NBT nbt)

The new path system is suggested to become a perfect copy of sqlite's json path syntax: https://www.sqlite.org/json1.html#jex

MCA ChunkSection biomes processed incorrectly

On line 150 of org.jglrxavpok.hephaistos.mca.ChunkSection, sizeInBits is defined as compressedBiomes.size * 64 / biomeArraySize. This is incorrect, and causes the wrong biomes to be read from the file, and even causes an exception to be thrown on line 158 if the ChunkSection contains 5 or more biomes. sizeInBits should be ceil(log2(biomePalette.elements.size)). I would make a PR to fix this, but I am not familiar with Kotlin, and I would not know how to properly test the fix.

Wrong length for compacted heightmap with 1.16.1

I tried loading a 1.16.1 world, and gave this error:

org.jglrxavpok.hephaistos.mca.AnvilException: Wrong length for compacted heightmap
        at org.jglrxavpok.hephaistos.mca.Heightmap.<init>(Heightmap.kt:15)
        at org.jglrxavpok.hephaistos.mca.ChunkColumn.<init>(ChunkColumn.kt:70)
        at org.jglrxavpok.hephaistos.mca.RegionFile.readColumn(RegionFile.kt:149)
        at org.jglrxavpok.hephaistos.mca.RegionFile.access$readColumn(RegionFile.kt:23)
        at org.jglrxavpok.hephaistos.mca.RegionFile$getChunk$1.apply(RegionFile.kt:98)
        at org.jglrxavpok.hephaistos.mca.RegionFile$getChunk$1.apply(RegionFile.kt:23)
        at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705)
        at org.jglrxavpok.hephaistos.mca.RegionFile.getChunk(RegionFile.kt:98)
        at org.corbellumteam.mmo.World.AnvilChunkLoader.loadMCA(AnvilChunkLoader.java:62)
        at org.corbellumteam.mmo.World.AnvilChunkLoader.loadChunk(AnvilChunkLoader.java:51)
        at net.minestom.server.instance.InstanceContainer.retrieveChunk(InstanceContainer.java:430)
        at net.minestom.server.instance.InstanceContainer.loadOptionalChunk(InstanceContainer.java:307)
        at net.minestom.server.entity.Player.setInstance(Player.java:577)
        at net.minestom.server.entity.EntityManager.waitingPlayersTick(EntityManager.java:40)
        at net.minestom.server.entity.EntityManager.updateWaitingPlayers(EntityManager.java:22)
        at net.minestom.server.UpdateManager.lambda$start$0(UpdateManager.java:56)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)

This was using a freshly generated 1.16.1 world, with just a few chunks loaded.

The region files I used:
region.zip

Error when reading mca version 1.12.2

org.jglrxavpok.hephaistos.mca.AnvilException: Missing field named 'Status' (or of wrong type)
	at org.jglrxavpok.hephaistos.mca.AnvilException$Companion.missing(AnvilException.kt:15)
	at org.jglrxavpok.hephaistos.mca.readers.ChunkReader.getGenerationStatus(ChunkReader.kt:62)
	at org.jglrxavpok.hephaistos.mca.ChunkColumn.<init>(ChunkColumn.kt:125)
	at org.jglrxavpok.hephaistos.mca.RegionFile.readColumn(RegionFile.kt:185)
	at org.jglrxavpok.hephaistos.mca.RegionFile.getChunk$lambda-3(RegionFile.kt:111)
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
	at org.jglrxavpok.hephaistos.mca.RegionFile.getChunk(RegionFile.kt:111)

Issues when using a player head with custom skin

Basically what happens is that it wont let me select the custom skin head and remove it from my inventory.

This is the error:

java.nio.BufferUnderflowException
        at java.base/java.nio.Buffer.nextGetIndex(Buffer.java:699)
        at java.base/java.nio.DirectByteBuffer.get(DirectByteBuffer.java:324)
        at net.minestom.server.utils.binary.BinaryReader.readByte(BinaryReader.java:59)
        at net.minestom.server.utils.binary.BinaryReader.read(BinaryReader.java:259)
        at java.base/java.io.DataInputStream.readByte(DataInputStream.java:271)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readFullyFormedTag(Extensions.kt:12)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion$readContents$$inlined$Kompound$1.run(NBT.kt:222)
        at org.jglrxavpok.hephaistos.nbt.NBT$Companion.Compound(NBT.kt:108)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion.readContents(NBTCompound.kt:96)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion.readContents(NBTCompound.kt:58)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readTag(Extensions.kt:27)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readFullyFormedTag(Extensions.kt:18)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion$readContents$$inlined$Kompound$1.run(NBT.kt:222)
        at org.jglrxavpok.hephaistos.nbt.NBT$Companion.Compound(NBT.kt:108)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion.readContents(NBTCompound.kt:96)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion.readContents(NBTCompound.kt:58)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readTag(Extensions.kt:27)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readFullyFormedTag(Extensions.kt:18)
        at org.jglrxavpok.hephaistos.nbt.NBTReader.readNamed(NBTReader.kt:48)
        at org.jglrxavpok.hephaistos.nbt.NBTReader.read(NBTReader.kt:58)
        at net.minestom.server.utils.binary.BinaryReader.readTag(BinaryReader.java:274)
        at net.minestom.server.utils.NBTUtils.readItemStack(NBTUtils.java:116)
        at net.minestom.server.utils.binary.BinaryReader.readItemStack(BinaryReader.java:193)
        at net.minestom.server.network.packet.client.play.ClientClickWindowPacket$ChangedSlot.<init>(ClientClickWindowPacket.java:39)
        at net.minestom.server.utils.binary.BinaryReader.readList(BinaryReader.java:248)
        at net.minestom.server.utils.binary.BinaryReader.readVarIntList(BinaryReader.java:238)
        at net.minestom.server.network.packet.client.play.ClientClickWindowPacket.<init>(ClientClickWindowPacket.java:23)
        at net.minestom.server.network.packet.client.ClientPacketsHandler.create(ClientPacketsHandler.java:35)
        at net.minestom.server.network.PacketProcessor.create(PacketProcessor.java:33)
        at net.minestom.server.network.PacketProcessor.process(PacketProcessor.java:48)
        at net.minestom.server.network.player.PlayerSocketConnection.processPackets(PlayerSocketConnection.java:109)
        at net.minestom.server.network.socket.Worker.lambda$run$0(Worker.java:74)
        at java.base/sun.nio.ch.SelectorImpl.processReadyEvents(SelectorImpl.java:294)
        at java.base/sun.nio.ch.WEPollSelectorImpl.processEvents(WEPollSelectorImpl.java:180)
        at java.base/sun.nio.ch.WEPollSelectorImpl.doSelect(WEPollSelectorImpl.java:116)
        at java.base/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:129)
        at java.base/sun.nio.ch.SelectorImpl.select(SelectorImpl.java:167)
        at net.minestom.server.network.socket.Worker.run(Worker.java:63)
java.nio.BufferUnderflowException
        at java.base/java.nio.DirectByteBuffer.get(DirectByteBuffer.java:324)
        at net.minestom.server.utils.binary.BinaryReader.readByte(BinaryReader.java:59)
        at net.minestom.server.utils.binary.BinaryReader.read(BinaryReader.java:259)
        at java.base/java.io.DataInputStream.readByte(DataInputStream.java:271)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readFullyFormedTag(Extensions.kt:12)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion$readContents$$inlined$Kompound$1.run(NBT.kt:222)
        at org.jglrxavpok.hephaistos.nbt.NBT$Companion.Compound(NBT.kt:108)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion.readContents(NBTCompound.kt:96)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion.readContents(NBTCompound.kt:58)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readTag(Extensions.kt:27)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readFullyFormedTag(Extensions.kt:18)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion$readContents$$inlined$Kompound$1.run(NBT.kt:222)
        at org.jglrxavpok.hephaistos.nbt.NBT$Companion.Compound(NBT.kt:108)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion.readContents(NBTCompound.kt:96)
        at org.jglrxavpok.hephaistos.nbt.NBTCompound$Companion.readContents(NBTCompound.kt:58)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readTag(Extensions.kt:27)
        at org.jglrxavpok.hephaistos.nbt.ExtensionsKt.readFullyFormedTag(Extensions.kt:18)
        at org.jglrxavpok.hephaistos.nbt.NBTReader.readNamed(NBTReader.kt:48)
        at org.jglrxavpok.hephaistos.nbt.NBTReader.read(NBTReader.kt:58)
        at net.minestom.server.utils.binary.BinaryReader.readTag(BinaryReader.java:274)
        at net.minestom.server.utils.NBTUtils.readItemStack(NBTUtils.java:116)
        at net.minestom.server.utils.binary.BinaryReader.readItemStack(BinaryReader.java:193)
        at net.minestom.server.network.packet.client.play.ClientClickWindowPacket$ChangedSlot.<init>(ClientClickWindowPacket.java:39)
        at net.minestom.server.utils.binary.BinaryReader.readList(BinaryReader.java:248)
        at net.minestom.server.utils.binary.BinaryReader.readVarIntList(BinaryReader.java:238)
        at net.minestom.server.network.packet.client.play.ClientClickWindowPacket.<init>(ClientClickWindowPacket.java:23)
        at net.minestom.server.network.packet.client.ClientPacketsHandler.create(ClientPacketsHandler.java:35)
        at net.minestom.server.network.PacketProcessor.create(PacketProcessor.java:33)
        at net.minestom.server.network.PacketProcessor.process(PacketProcessor.java:48)
        at net.minestom.server.network.player.PlayerSocketConnection.processPackets(PlayerSocketConnection.java:109)
        at net.minestom.server.network.socket.Worker.lambda$run$0(Worker.java:74)
        at java.base/sun.nio.ch.SelectorImpl.processReadyEvents(SelectorImpl.java:294)
        at java.base/sun.nio.ch.WEPollSelectorImpl.processEvents(WEPollSelectorImpl.java:180)
        at java.base/sun.nio.ch.WEPollSelectorImpl.doSelect(WEPollSelectorImpl.java:116)
        at java.base/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:129)
        at java.base/sun.nio.ch.SelectorImpl.select(SelectorImpl.java:167)
        at net.minestom.server.network.socket.Worker.run(Worker.java:63)

AnvilException in ChunkColumn#getEntities()

Hi!
I want to load entities from my world (in minestom, version 1.19) and when I try to list the entities in ChunkColumn I get an AvilException named "Missing field named 'xPos' (or of wrong type)".
My code:

            Path path = Path.of("world/entities");

            int regionX = CoordinatesKt.chunkToRegion(event.getChunkX());
            int regionZ = CoordinatesKt.chunkToRegion(event.getChunkZ());

            Path regionPath = Path.of(RegionFile.Companion.createFileName(regionX, regionZ));

            try {
                RegionFile regionFile = new RegionFile(new RandomAccessFile(path.resolve(regionPath).toFile(), "rw"), regionX, regionZ, event.getInstance().getDimensionType().getMaxY() - 1);
                ChunkColumn chunkColumn = regionFile.getChunk(event.getChunkX(), event.getChunkZ());
                if (chunkColumn == null) {
                    return;
                }
                List<NBTCompound> list = chunkColumn.getEntities().asListView();
                System.out.println(list);
            } catch (AnvilException | IOException e) {
                throw new RuntimeException(e);
            }

I attach the compressed world file.
world.zip

Missing field named 'sections' (or of wrong type)

Hephaistos seems to throw Missing field named 'sections' (or of wrong type)

org.jglrxavpok.hephaistos.mca.AnvilException: Missing field named 'sections' (or of wrong type)
        at org.jglrxavpok.hephaistos.mca.AnvilException$Companion.missing(AnvilException.kt:15)
        at org.jglrxavpok.hephaistos.mca.readers.ChunkReader.getSections(ChunkReader.kt:57)
        at org.jglrxavpok.hephaistos.mca.readers.ChunkReader.getYRange(ChunkReader.kt:85)
        at net.minestom.server.instance.AnvilLoader.loadMCA(AnvilLoader.java:105)
        at net.minestom.server.instance.AnvilLoader.loadChunk(AnvilLoader.java:86)
        at net.minestom.server.instance.InstanceContainer.lambda$retrieveChunk$6(InstanceContainer.java:294)
        at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
        at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)

Whenever an ItemEntity from Minestom is spawned in my world for the first time.
Here's the world for reference: san_andreas.zip

The world is correctly loaded in vanilla and has also been upgraded using the Minecraft builtin tools, but Hephaistos still seems to error.

Allow clients of SNBTParser to see how much was read

SNBTParser requires a Reader to parse any SNBT, but it reads the entire reader. This is a problem because it does also not allow a way to see how much of the provided text was actually read. This means that it is impossible to read SNBT from a string while preserving any non-SNBT text at the end.

There are two main things necessary for this change:

  • Add a way for clients to decide if they want the parser to read any information after the end of the SNBT. For example, currently "text" in the input {}text would be read, but with this setting on, the parser would stop after reading {} because it has reached the end of the input it wanted. Possible ways to implement this include adding a boolean to the parse method that would correspond to this functionality.
  • Allow clients to somehow receive an integer from this method that represents the number of characters that were read. This would not include any characters that were read but caused errors. For example, the error that would result from parsing {}text (the error would be Line 1, column 2 extraneous input 'text' expecting <EOF>) would result in an integer that indicates that only two characters were read (which are {}). Possible ways to implement this include using Reader#mark(int).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.