Minecraft Mods

NBT File System (Compatible with All Minecraft Java Edition Releases)

  • 1,430 views, 4 today
  • 32 downloads, 0 today
  • 5
  • 1
  • 1
Low-power's Avatar Low-power
Level 37 : Artisan Miner
10
Note: this site has forced me to select a "compatible" game version, but this external program is compatible with any Minecraft version that using the original NBT format and Minecraft Region format (including a later variant the Anvil format).


The primary part of this project is a FUSE-based file system implementation which allowing NBT file or Minecraft Region file be mounted as a file system, and then modified using normal file operations.

NBT parser and writer are originally written by Lukas Niederbremer as cNBT project which this project is based on.

Download

Please get the source code directly from the git repository at sourceforge.net, by either cloning the repository using git(1) command like:
$ git clone https\://git.code.sf.net/p/nbtfsutils/code.git nbtfsutils or clicking the Download Snapshot button on the source code browsing page.

Install

To build it from source, make sure you have GCC or a compatible C compiler, GNU Make or BSD make, FUSE development library, as well as zlib development library installed, then type 'make'; some environment variables are useful to configure the build:
CC
C compiler
ARarchive tool for creating static library
CFLAGS
prepend flags to C compiler
LDFLAGS
prepend flags to linker (e.g. -L <path>)

Example

$ CC=gcc CFLAGS=-Os make
To install built programs and manual pages, type 'make install'; some attitional environment variables may be used here:
PREFIXinstalling prefix, default /usr/local
BINDIRdefault ${PREFIX}/bin
SBINDIRdefault ${PREFIX}/sbin
DATADIRdefault ${PREFIX}/share
MANDIRdefault ${DATADIR}/man


Use

Use program mount.nbt(8) to mount the file system from a NBT file or a Region file. The synopsis of the command line is:
mount.nbt [-o <fs-options>] [<other-options>] <mount-from-file> <mount-point>
The <fs-options> accepts both generic and FS-specific mount options; some of them are useful to specify here; see man page mount.nbt(8) (available below) for a detailed description of each FS-specific option.

Example

# mount.nbt -o ro,region,umask=0022 /usr/home/minecraft/aether-realm/world/AETHER/region/r.1.1.mca /mnt/region/
# ls -al /mnt/region/80/Level/
total 0
-rw-r--r-- 1 root wheel 256 Jan 1 1970 Biomes
drwxr-xr-x 1 root wheel 1 Jan 1 1970 Entities
drwxr-xr-x 1 root wheel 1024 Jan 1 1970 HeightMap
-rw-r--r-- 1 root wheel 7 Jan 1 1970 InhabitedTime
-rw-r--r-- 1 root wheel 10 Jan 1 1970 LastUpdate
-rw-r--r-- 1 root wheel 2 Jan 1 1970 LightPopulated
drwxr-xr-x 1 root wheel 25 Jan 1 1970 Sections
-rw-r--r-- 1 root wheel 2 Jan 1 1970 TerrainPopulated
drwxr-xr-x 1 root wheel 1 Jan 1 1970 TileEntities
-rw-r--r-- 1 root wheel 2 Jan 1 1970 V
-rw-r--r-- 1 root wheel 3 Jan 1 1970 xPos
-rw-r--r-- 1 root wheel 3 Jan 1 1970 zPos
# ls -al /mnt/region/80/Level/Sections/
total 0
-rw-r--r-- 1 root wheel 9 Jan 1 1970 .type
drwxr-xr-x 1 root wheel 6 Jan 1 1970 0
drwxr-xr-x 1 root wheel 6 Jan 1 1970 1
drwxr-xr-x 1 root wheel 6 Jan 1 1970 2
drwxr-xr-x 1 root wheel 6 Jan 1 1970 3
# cat /mnt/region/80/Level/?Pos
48
34
# umount /mnt/region/
# mount.nbt -o ro,region,umask=0022,typeprefix /usr/home/minecraft/aether-realm/world/AETHER/region/r.1.1.mca /mnt/region/
# ls -al /mnt/region/80/Level/
total 0
-rw-r--r-- 1 root wheel 3 Jan 1 1970 int32:xPos
-rw-r--r-- 1 root wheel 3 Jan 1 1970 int32:zPos
drwxr-xr-x 1 root wheel 1024 Jan 1 1970 int32array:HeightMap
-rw-r--r-- 1 root wheel 7 Jan 1 1970 int64:InhabitedTime
-rw-r--r-- 1 root wheel 10 Jan 1 1970 int64:LastUpdate
-rw-r--r-- 1 root wheel 2 Jan 1 1970 int8:LightPopulated
-rw-r--r-- 1 root wheel 2 Jan 1 1970 int8:TerrainPopulated
-rw-r--r-- 1 root wheel 2 Jan 1 1970 int8:V
-rw-r--r-- 1 root wheel 256 Jan 1 1970 int8array:Biomes
drwxr-xr-x 1 root wheel 1 Jan 1 1970 list:Entities
drwxr-xr-x 1 root wheel 25 Jan 1 1970 list:Sections
drwxr-xr-x 1 root wheel 1 Jan 1 1970 list:TileEntities


Read the following man page for a detailed description of the file system.
mount.nbt(8) Manual Page
MOUNT.NBT(8) FreeBSD System Manager's Manual MOUNT.NBT(8)

NAME
mount.nbt - Mount a Named Binary Tag File System

SYNOPSIS
mount.nbt [-o <fs-option>[,...]] [-fnrvwh] <nbt-file> <mount-point>

DESCRIPTION
This tool is a FUSE-based file system implementation for accessing NBT
formatted data, which is used by Minecraft to store various data about
the game. Running this tool mounts a file system from the file
specified by <nbt-file>; both standalone NBT file (usually have suffix
.dat) and Minecraft Region file (usually have suffix .mcr or .mca) are
supported.

OPTIONS

-f Operate in foreground. Useful for debugging.

-h Print a brief usage message. The program will exit afterward.

-n Ignored.

-o <fs-option>[,...]
Pass gereric mount options, FUSE-specific options, and/or NBT-
specific options, in a comma-separated list. See mount(8) and
fuse(8) for generic mount options and FUSE-specific options.

NBT-specific options are:

ro Mount the file system read-only, useful to mount from a
file that can't be written to, or to prevent accidentally
changing it; but see writefile option below.

rw Revert any ro option that may be specified early.

region Specify the <nbt-file> is a Minecraft Region file instead
of a standalone NBT file.

typeprefix
Use node type prefix for node names when listing compound
nodes as a directory. This option affects directory
listing only, existing nodes where their name contains no
colon can always be accessed either with or without the
type prefix.

umask=<mask>
Set file mode mask using an octal number for NBT nodes,
default 0.

writefile=<path>
Set an alternative path for writing NBT data; the
original <nbt-file> won't be written to if this is
specified. Will have no effect when file system is
mounted read-only.

compression={gzip|zlib}
Set compression format for writing NBT data; default gzip
for standalone NBT file, zlib for Minecraft Region file.
Will have no effect when file system is mounted read-
only.

chunksymlink={hidden|visible}
Set whether the symbolic links in form of <x>,<z> for
chunks, be visible in the region root directory; default
hidden. This option is meaningful only when mounting a
Minecraft Region file.

arraybyteorder={host|big|little}
Set integer byte order for presenting data of int32array
and int64array nodes; default host. This option is
meaningful only when direct read(2)ing of directories is
supported by the operating system and the FUSE
implementation.

-r Mount the file system read-only. Same as specifying -o ro.

-v Be Verbose during mounting.

-V Display version, copyright and licensing information of this
tool. The program will exit afterward.

-w Mount the file system read-write. Same as specifying -o rw.

NODE TYPES
NBT specification defined several types for a tag, they are mapped into
file types as followings:

┌────────────────────────────────────────────────────┐
│NBT Tag Type File Type Type Prefix Name │
│TAG_Byte Regular int8, byte │
│TAG_Short Regular int16 │
│TAG_Int Regular int32 │
│TAG_Long Regular int64 │
│TAG_Float Regular float32, float, single │
│TAG_Double Regular float64, double │
│TAG_Byte_Array Regular int8array, bytearray │
│TAG_String Regular string │
│TAG_List Directory list │
│TAG_Compound Directory compound │
│TAG_Int_Array Directory int32array │
│TAG_Long_Array Directory int64array │
└────────────────────────────────────────────────────┘

ACCESSING NODES
Referencing Nodes Under Compound
For nodes directly under a compound, they can be accessed using their
name; a type prefix can also be prepended to an name to reference a
node, as typeprefix:name. For example an int64 node named RandomSeed
under a compound named Data, the following 2 pathes would referencing
the exactly same node:
Data/int64:RandomSeed
compound:Data/RandomSeed
Turning on mount option typeprefix will having this type prefix be
automatically prepended to node names, when listing a compound using
readdir(3); this could be useful to preserve the type information when
copying a compound node recursively (such as using tar(1)), so it is
possible for the copied nodes be restored into another NBT later.

To avoid ambiguity, nodes can be listed and accessed only with the
corresponding type prefix when their name containing the colon.

Referencing Nodes Under List
Nodes under a list are accessed using index numbers starting with 0.
They will also have same type; a pseudo file .type is available under
any list to indicate node type the list contains.

Accessing Individual Node
Any node which the file type is regular file can be read and written
directly using read(2) and write(2); they can also be truncate(2)d to
empty, but number typed ( int8 , int16 , int32 , int64 , float32 and
float64 ) nodes will turn its value into 0 after that. Nodes with type
int8array or string support lseek(2) and unlimited truncate(2)
operations. Reading from a string node will have an additional line
feed character (\n) appended to the end automatically; similarly,
writing to a string node will have the ending line feed character
stripped if exist.

list and compound nodes can contain other nodes, accessing them
according to above rules.

int32array and int64array nodes are represented as directories, the
array elements are accessed using an index number starting with 0, as
regular files under the directory. Creating a new regular file with
appreciate index number under the directory extends the array, and any
element between the old tail index and new index will appear
automatically as well; newly added elements will initialized to 0. An
array can also be shrunk by removing (unlink(2)) the tail element, one
element at a time; as a design limitation, only the tail element can be
removed. On supported platforms, the array nodes may also be read
directly (using read(2)); in this case seeking is supported only when
aligned to element size, which is 4 or 8 for int32array or int64array
respectively. The data stream read directly from an array will be the
binary representation of the array elements in a byte order specified
by the mount option arraybyteorder, which is host byte order by
default.


ADDING AND REMOVING NODES
Under Compound
Nodes under a compound can be removed by using unlink(2) or rmdir(2),
according to their represented file type; usual file system
restrictions on directory apply, meaning nodes that being represented
as directories can not be removed unless empty.

Unlike referencing an existing node, creating a new node under a
compound requires the use of a type-prefixed name.

Under List
Like compound, nodes under a list may be removed by using either
unlink(2) or rmdir(2); if a non-tail node was removed, the index number
of later nodes will be shifted backward by 1, which could be surprising
when trying to remove multiple nodes.

New node may be added only to the tail of a list, there is currently
not possible to insert a node in middle of a list. Newly created node
will have the type specified by the list type, indicated by the .type
pseudo file.

The list type may also be changed by writing a type prefix name into
.type, but only when the list is empty.

Special Requirement For Creating List Node
A list node may be created under either compound or list using mkdir(2)
according to rules above, but please note newly created list will have
an invalid list type; no node can be created under such list, and if a
file system is unmounted with it, writing NBT data will fail, causing
all modifications to be lost! Any newly created list must be
initialized with a supported list type, by writing the type prefix
name to its .type pseudo file.

MOVING (RENAMING) NODES
Any node can be moved from a compound or list, to same or another
compound or list, by using rename(2).

Moving into Compound
If the new name is specified with a type prefix, the specified type
prefix name must match the type of the node being moved.

If another node in target compound with the new name already exists, it
will be overwritten if:
both node is considered as a regular file by the file system, or

both node is considered as a directory by the file system, and
the node being overwritten is an empty compound or list, or an
int32array or int64array.

Moving into List
The node being moved must have a type that fit the list type.

The new name must be an index number. The index number must be point to
either the tail of the list, or an existing node in the list; if it is
pointing to an existing node and the node isn't a non-empty compound or
list, the node will be overwritten.

CAVEATS
Data is committed to underlying <nbt-file> only upon unmounting; if
anything went wrong during this process, the error message will be sent
to syslog(3), and the file system will be unmounted without saving some
or all data.

When modifying a Minecraft Region file, it is currently not possible to
extend a modified chunk beyond the space available for the chunk in
that Region file; although this rarely happen unless a considerable
amount of additional data was copied into a chunk. If this happens,
such chunk will not be saved.

EXAMPLES
The following examples took place in an Unix shell (sh(1)).

Mount a standalone NBT file /tmp/level.dat at /mnt/nbt, prepare to
write a new NBT file at /tmp/new-level.dat:

mount.nbt -o writefile=/tmp/new-level.dat /tmp/level.dat /mnt/nbt

Mount a Minecraft Region file /tmp/r.0.-1.mcr at /mnt/region, with type
prefix turned on for node name listing:

mount.nbt -o region,typeprefix /tmp/r.0.-1.mcr /mnt/region

Working in a compound, create and write a new string node named id:

echo Villager > string:id

Working in a compound, create a new list node Pos with list type set to
float64, then create and write first node in the list:

mkdir list:Pos
echo float64 > Pos/.type
echo 31.5 > Pos/0


AUTHOR
mount.nbt was written by WHR <whr@rivoreo.one>.

SEE ALSO
fuse(8), fusermount(8), mount(8)

Named Binary Tag specification by Mojang

nbtfsutils 2023 MOUNT.NBT(8)


License

The file system implementation mount.nbt(8) is distributed under Mozilla Public License 2.0. Other parts have different licenses, please see individual source files for the exact license terms.

Disclaimer of Warranty

This program is provided here "as is", in hope that it could be useful for some users, but without warranty of any kind. The user must take full risk and responsibility by using this program. The author is not responsible for any damage including but not limited to loss of profit, service interruption, data corruption, and hardware failure, that may be caused by using this program.
CreditLukas Niederbremer for creating library cNBT
Progress100% complete
Game VersionMinecraft 1.8
Tags

1 Update Logs

Update #1 : by Low-power 04/07/2022 4:09:53 amApr 7th, 2022

Node renaming support has been implemented in recent commits, alone with some bug fixes.

Create an account or sign in to comment.

1
04/01/2022 2:26 pm
Level 2 : Apprentice Miner
sigstop
sigstop's Avatar
Cool, I would prefer to use some cli program for nbt manipulation, although I could learn how to mount some custom fs by looking up in your project.
Planet Minecraft

Website

© 2010 - 2024
www.planetminecraft.com

Welcome