NBTedit

出于一些原因,我想用python来编辑minecraft的存档,用编辑nbt的方法再用mcedit导入是个很可行的方法,所以我就简单的写了一个py脚本来生成nbt文件。

文章项目地址:https://www.12skoko.com/archives/178

该文件需要NBT库的支持:https://github.com/twoolie/NBT

pip install nbt

直接py文件下载放在项目同目录就行,使用的时候直接import

import NBTeidtpy

这个脚本非常简单,里面只有一个类

class NBTedit:
    def __init__(self, sizes):
    def printNBT(self):
    def saveNBT(self, path):
    def addblockskind(self, block):
    def setblock(self, coor, block):
    def removeblock(self, coor):
    def setcommandblock(self, coor, command, type, name='@'):

创建NBT文件

刚开始创建NBT文件的时候,需要规定好文件的大小,初始化的时候就已经把所有的方块全部填上了air方块

mynbt=NBTeditpy.NBTedit([50,10,10])

方块字典

接下来就是要添加我们需要的方块了

注意nbt格式添加方块是先需要添加方块种类的

也就是说nbt格式储存方块是根据坐标和的方块种类,而不是直接方块的名字

不是这样的:

坐标x=0x=1x=2
z=0草方块草方块圆石
z=1草方块草方块圆石
z=2草方块空气圆石

而是这样的:

坐标x=0x=1x=2 方块字典
z=0方块2方块2方块3 方块1空气
z=1方块2方块2方块3 方块2草方块
z=2方块2方块1方块3 方块3圆石

所以我们要先在方块字典里面添加方块

def addblockskind(block):

我们先来看一看方块字典里的方块需要哪些东西

这是air方块:

TAG_Compound: {1 Entries}
{
    TAG_String('Name'): minecraft:air
}

这是command_block方块:

TAG_Compound: {2 Entries}
{
    TAG_String('Name'): minecraft:command_block
    TAG_Compound('Properties'): {2 Entries}
    {
        TAG_String('conditional'): false
        TAG_String('facing'): up
    }
}

我们可以看出来有一个固定的tag是'name',后面跟着方块的名字,然后有一个可选的'properties'是方块的属性

在NBTeditpy中,addblockskind函数中的block的类型为字典

block_new = {'Name': 'minecraft:stone', 'tag': 'stone'}

如果是有'properties'属性的方块则为

block_new = {'Name': 'minecraft:command_block', 'tag': 'cb',
            'Properties': {'conditional': 'flase', 'facing': 'north'}}

这里的tag是随便取的标识名字,为了是以后能方便的添加方块,只要自己认识随便写什么都是可以的。

注意这里面所有的变量属性都应该是字符串,'condition'的后面是'false'而不是false

把我们写好的字典传入就可以添加进nbt文件中的方块字典了

mynbt.addblockskind(block_new)

air方块在创建对象时已经添加,tag是'air'

添加方块

现在就可以在nbt中正式的添加方块了

def setblock(coor, block)

coor是一个列表,用来确定这个方块放置的具体坐标,注意不要超过一开始初始化时设置的坐标大小限制

coor=[2,3,5]

block是一个字典,只有一个必须的键值对

block_set={'tag':'stone'}

这里的tag就是在加入方块字典里是自己取的名字

方块的nbt格式也是储存在这里的,所以有一个可选的nbt键值对

cb = {'tag': 'cb', 'nbt': {'Command': 'time set 1000',
                           'Command_type': 'String',
                           'auto': 0,
                           'auto_type': 'Byte',
                           'id': 'minecraft:command_block',
                           'id_type': 'String',
                           'CustomName': '@',
                           'CustomName_type': 'String',
                           'powered': 0,
                           'powered_type': 'Byte',
                           'UpdateLastExecution': 1,
                           'UpdateLastExecution_type': 'Byte',
                           'conditionMet': 1,
                           'conditionMet_type': 'Byte',
                           'TrackOutput': 1,
                           'TrackOutput_type': 'Byte',
                           'SuccessCount': 1, 
                           'SuccessCount_type': 'Int',
                           'LastExecution': 0,
                           'LastExecution_type': 'Long'
                           }}

这里nbt字典里面的键值对根据需要自行添加。但需要注意的是,需要在添加的键中再添加一个'type'的键,值来表示nbt的格式

例如添加{'Command': 'time set 1000'}需要同时再加一个{'Command_type': 'String'}

目前支持的nbt格式有['String','Byte','Int','Long','Float','Double','Short'](注意大小写)

套娃的Compound格式并不支持。别问,问就是懒,有需求再加

然后就能用setblock函数添加方块了

setblock(coor, cb)

删除方块

这个没什么好说的,传入坐标数组就能把坐标的方块替换成air方块

def removeblock(coor)

保存

def saveNBT(path)

path为保存路径名字

saveNBT('mynbt.nbt')

命令方块

噔噔噔,我写这个主要是因为要放置命令方块,所以写了一个函数来专门放置命令方块

def setcommandblock(coor, command, type, name='@')

coor是坐标,command是命令,格式是string,name是命令方块的别名,是个可选参数

接下来就是type的格式了,type是一个由四个数组成的列表

众所周知命令方块有好几种(脉冲,连锁,循环),又有制约朝向啥的,所以我把它统一放在type列表里了

方块类型 制约 朝向 自动
0脉冲 0不受制约 0east x+ 0红石控制
1连锁 1条件制约 1south z+ 1始终开启
2循环 2west x-
3north z-
4up y+
5down y-

比如我要一个始终开启不受制约朝上的循环命令方块,则type=[2,0,4,1]

setcommandblock([1,2,3], 'time set day', [2,0,4,1])

注意,使用setcommandblock函数时是不需要添加方块字典的,这个函数会自动把不在方块字典里的命令方块加入方块字典

demo

import NBTeditpy

stone = {'Name': 'minecraft:stone', 'tag': 'stone', 'Properties':{'variant':'stone'}}
dirt = {'Name': 'minecraft:dirt', 'tag': 'dirt'}
grass = {'Name': 'minecraft:grass', 'tag': 'grass'}
cobblestone = {'Name': 'minecraft:cobblestone', 'tag': 'cobblestone'}

nn = NBTeditpy.NBTedit([2, 2, 2])

nn.addblockskind(stone)
nn.addblockskind(dirt)
nn.addblockskind(grass)
nn.addblockskind(cobblestone)

nn.setblock([0, 0, 0], {'tag': 'stone'})
nn.setblock([0, 0, 1], {'tag': 'dirt'})
nn.setblock([0, 1, 1], {'tag': 'grass'})
nn.setblock([1, 0, 1], {'tag': 'cobblestone'})
nn.setcommandblock([1, 1, 0], 'helloworld', [0, 0, 0, 0])

nn.printNBT()

nn.saveNBT('demo.nbt')
最后修改:2024 年 11 月 08 日
点个赞吧ヾ(๑╹◡╹)ノ"