LB-- / MCModify

WIP Java/C++ library for dealing with Minecraft files.
The Unlicense
21 stars 10 forks source link

filesize and fileformat of generated files #2

Open DonRudiX opened 11 years ago

DonRudiX commented 11 years ago

I managed to get this library working with my worldgenerator but there are two things that bother me:

  1. My fully explored source region from a Mincraft-1.6.2-Client has 4104KB but the generated Files always have 8200KB of filesize even if i did not change anything.
  2. Regions generated with this library are playable in Minecraft but can not be rendered by my favorite maping tool Overviewer, (which is the main reason why i am here :) ) which is either a bug or i am not using the library as it was intended to.

This is how I produced the "not so good" regionfile:

The masterfile can be rendered but the generated one not.

As a footnote: I really apreciate your work with this library, it is easy to use and saved me from being forced to create something similar on my own :) The worlds i am creating are very huge (mostly 20kmx20km and bigger) and that is why it is essential for me to have regionfiles that are not bigger than necessary and a map to navigate fast on these worlds.

This is the code example which I used to generate the second file:

import mcmodify.nbt.minecraft.Chunk;
import mcmodify.nbt.minecraft.IDs;
import mcmodify.nbt.minecraft.Region;

public class MinimalExample
{
    public static void main(String[] args)
    {
        try
        {
            Region region = new Region(new File("flatworld_master_r.0.0.mca"));
            String filename = "r.0.0.mca";
            Region newregion = new Region(new File(filename)); 

            for (int x = 0; x < 32; x++)
            {
                for (int y = 0; y < 32; y++)
                {
                    Chunk chunk = region.ReadChunk(x, y);

                    for (int k = 0; k < 16; k++)
                    {
                        for (int k2 = 0; k2 < 16; k2++)
                        {
                            chunk.BlockID(k, 0, k2, IDs.Bedrock);
                            chunk.BlockID(k, 1, k2, IDs.Grass);
                        }
                    }
                    newregion.WriteChunk(x, y, chunk);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
LB-- commented 11 years ago

My fully explored source region from a Mincraft-1.6.2-Client has 4104KB but the generated Files always have 8200KB of filesize even if i did not change anything.

I can't test right now, but does this happen if you region.WriteChunk(x, y, region.ReadChunk(x, y))? Or with your example?

Regions generated with this library are playable in Minecraft but can not be rendered by my favorite maping tool Overviewer, (which is the main reason why i am here :) ) which is either a bug or i am not using the library as it was intended to.

Weird. Could you set your launcher to reopen when the game closes and see if there are any warnings or errors in the log?

I am still trying ti maintain this library, it's a bit behind in terms of the new entities and such but most things should work. I'll look into your issues when I have time, I can't really think why they would happen.

LB-- commented 11 years ago

My fully explored source region from a Mincraft-1.6.2-Client has 4104KB but the generated Files always have 8200KB of filesize even if i did not change anything.

Actually another thing to note here is the javadoc on Region.WriteChunk:

Writes the given chunk to the region file in a lazy fashion. If the chunk exists in the region file and the given chunk can fit, it will be placed there and the sector size will be updated. Otherwise the chunk will be placed at the end of the region file without removing the old chunk, and the offset and sector size will be updated.

Not sure if this comes into play here or not.

DonRudiX commented 11 years ago

Short summary: I used the lib in the wrong way, now it works like a charm and both problems are solved :)

I forgot to mention that the target file in my first post does not exist. Reading your comments I reconsidered my code and came to the solution you can see below. Now the filesize is always 4102KB and the map can be rendered by Overviewer without any error.

Thank you very much for your fast help :)

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

import mcmodify.nbt.minecraft.Chunk;
import mcmodify.nbt.minecraft.IDs;
import mcmodify.nbt.minecraft.Region;

public class MinimalExample4
{
    public static void main(String[] args)
    {
        try
        {
            //Region region = new Region(new File("flatworld_master_r.0.0.mca"));
            String filename = "r.0.0.mca";
            //===================================================
            //the missing line that solved both problems
            copyFile("flatworld_master_r.0.0.mca",filename);
            //===================================================
            Region newregion = new Region(new File(filename)); 

            for (int x = 0; x < 32; x++)
            {
                for (int y = 0; y < 32; y++)
                {
                    Chunk chunk = newregion.ReadChunk(x, y);

                    for (int k = 0; k < 16; k++)
                    {
                        for (int k2 = 0; k2 < 16; k2++)
                        {
                            chunk.BlockID(k, 0, k2, IDs.Bedrock);
                            chunk.BlockID(k, 1, k2, IDs.Grass);
                        }
                    }
                    newregion.WriteChunk(x, y, chunk);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void copyFile(String sourceName, String targetName) throws IOException
    {
        File sourceFile = new File(sourceName);
        File destFile = new File(targetName);

        if (!destFile.exists())
        {
            destFile.createNewFile();
        }

        FileChannel source = null;
        FileChannel destination = null;
        try
        {
            source = new RandomAccessFile(sourceFile, "rw").getChannel();
            destination = new RandomAccessFile(destFile, "rw").getChannel();

            long position = 0;
            long count = source.size();

            source.transferTo(position, count, destination);
        }
        finally
        {
            if (source != null)
            {
                source.close();
            }
            if (destination != null)
            {
                destination.close();
            }
        }
    }
}
LB-- commented 11 years ago

Ah, I don't remember how well creating new regions from scratch works. I'll have to look into that. Glad you got it to work for you!