本帖最后由 taolu 于 2020-8-22 20:24 编辑
前言

Schematic(gzip压缩后)
temp(gzip压缩前)
其实Wiki里有关于Schematic的格式的介绍,但是我自己通过导出MCEdit发现和Wiki中有些不一样,比如有些项目我导出来并没有,这里我就按我导出的的文件格式讲一下Schematic的格式。格式

Schematic(gzip压缩后)
temp(gzip压缩前)

其实也能想象得出来,多了一维的情况下,公式变成了这样 (所在高度-1)×总的行数×总的列数+(所在行数-1)×总的列数+所在列数VB代码
前言
可能有些人的程序需要对Schematic格式的支持,所以我自己摸索了几天(其实还是去年暑假了)。
其实Wiki里有关于Schematic的格式的介绍,但是我自己通过导出MCEdit发现和Wiki中有些不一样,比如有些项目我导出来并没有,这里我就按我导出的的文件格式讲一下Schematic的格式。
格式对象 | 作用 | 大小 |
Schematic | 识别Schematic格式 | 12字节 |
Height | 高度Y 最大64K(mod突破高度限制?) | 2字节 |
Length | 长度Z 最大64K | 2字节 |
Width | 宽度X 最大64K | 2字节 |
Entities | 实体 | 不固定默认8字节 |
TileEntities | NBT | 不固定默认8字节 |
TileTicks | 方块要更新的数据 | 不固定默认8字节 |
Materials | 版本 默认Alpha 随意填其他没有事 | 不固定 |
Data | 方块数据 也就是setblock后面那个数字 | X × Y × Z字节 |
Biomes | 每个方块的生物群系 | X × Z字节 |
Block | 方块(数字ID, 1. 8及之后可以使用MCEdit-Unified查看) | X × Y × Z字节 |
- 如果生物群系对你有作用的话,请看下表
名称 | 数字ID | 数字ID(16进制) |
海洋 | 0 | 0 |
平原 | 1 | 1 |
沙漠 | 2 | 2 |
山地 | 3 | 3 |
森林 | 4 | 4 |
针叶林 | 5 | 5 |
沼泽 | 6 | 6 |
河流 | 7 | 7 |
下界荒地 | 8 | 8 |
末地 | 9 | 9 |
冻洋 | 10 | A |
冻河 | 11 | B |
积雪的冻原 | 12 | C |
雪山 | 13 | D |
蘑菇岛 | 14 | E |
蘑菇岛岸 | 15 | F |
沙滩 | 16 | 10 |
沙漠丘陵 | 17 | 11 |
繁茂的丘陵 | 18 | 12 |
针叶林丘陵 | 19 | 13 |
山地边缘 | 20 | 14 |
丛林 | 21 | 15 |
丛林丘陵 | 22 | 16 |
丛林边缘 | 23 | 17 |
深海 | 24 | 18 |
石岸 | 25 | 19 |
积雪的沙滩 | 26 | 1A |
桦木森林 | 27 | 1B |
桦木森林丘陵 | 28 | 1C |
黑森林 | 29 | 1D |
积雪的针叶林 | 30 | 1E |
积雪的针叶林丘陵 | 31 | 1F |
巨型针叶林 | 32 | 20 |
巨型针叶林丘陵 | 33 | 21 |
繁茂的山地 | 34 | 22 |
热带草原 | 35 | 23 |
热带高原 | 36 | 24 |
恶地 | 37 | 25 |
繁茂的恶地高原 | 38 | 26 |
恶地高原 | 39 | 27 |
末地小型岛屿 | 40 | 28 |
末地中型岛屿 | 41 | 29 |
末地高岛 | 42 | 2A |
末地荒岛 | 43 | 2B |
暖水海洋 | 44 | 2C |
温水海洋 | 45 | 2D |
冷水海洋 | 46 | 2E |
暖水深海 | 47 | 2F |
温水深海 | 48 | 30 |
冷水深海 | 49 | 31 |
封冻深海 | 50 | 32 |
虚空 | 127 | 7F |
向日葵平原 | 129 | 81 |
沙漠湖泊 | 130 | 82 |
沙砾山地 | 131 | 83 |
繁花森林 | 132 | 84 |
针叶林山地 | 133 | 85 |
沼泽山丘 | 134 | 86 |
冰刺平原 | 140 | 8C |
丛林变种 | 149 | 95 |
丛林边缘变种 | 151 | 97 |
高大桦木森林 | 155 | 9B |
高大桦木丘陵 | 156 | 9C |
黑森林丘陵 | 157 | 9D |
积雪的针叶林山地 | 158 | 9E |
巨型云杉针叶林 | 160 | A0 |
巨型云杉针叶林丘陵 | 161 | A1 |
沙砾山地+ | 162 | A2 |
破碎的热带草原 | 163 | A3 |
破碎的热带高原 | 164 | A4 |
被风蚀的恶地 | 165 | A5 |
繁茂的恶地高原变种 | 166 | A6 |
恶地高原变种 | 167 | A7 |
竹林 | 168 | A8 |
竹林丘陵 | 169 | A9 |
灵魂沙峡谷 | 170 | AA |
绯红森林 | 171 | AB |
诡异森林 | 172 | AC |
玄武岩三角洲 | 173 | AD |
- 谜?
对于其中的高度限制,我还是不太清楚。虽然说有些Mod可以突破高度限制,但是似乎Mcedit也有高度限制。几次实验后发现如果高度大于255,那么高度好像会从第一行重新写入,也就是说把从第一行已经生成的方块给覆盖掉。如果只有255方块,那么为什么大小要设置成两个字节,难道一个字节不就能用完呢?希望有人能帮我解惑。 - 格式中每个数据(姑且就这么叫吧)之间有指定的字符串去隔开,而在指定的字符串后还要声明此数据的长度。所以每一个数据的格式如下指定的分隔字节(两字节)+数据标题长度(一字节)+数据标题+数据长度(+数据)(当为Data,Biomes,Block…时)
值 | 识别对象 |
0x0A 0x00 | Schematic文件 |
0x02 0x00 | Height,Length,Width |
0x09 0x00 | Entities,TileEntities,TileTicks |
0x08 0x00 | Materials |
0x07 0x00 | Data,Biomes,Blocks |
- 知道了格式接下来就好做了。
将数据写入文件,再通过同目录下的gzip.exe压缩成x.gz文件,最后重命名为Schematic文件即可用MCEdit打开。

Schematic(gzip压缩后)

temp(gzip压缩前)
- 那么这里就讲一下data和block数据吧
通过立体坐标计算那么坐标为(X,Y,Z)的方块的data和block数据位于第(Y - 1) × (Width × Height) + ( Z - 1) × Width + X
个数据内(Width 和 Height为总的长和宽),只要在这个位置写入Block数据和Data数据就可以了。
可能你不怎么理解,如果看一下这张图和实例也许就知道了


- 按X和Z轴来进行,这里有一个5*5的二维平面。我们从第一个方块开始,给每一个方块标记数字。在二维中公式是这样的
(所在行数-1)×总的列数+所在列数
可见图中红色方块在第5行第4列,代入公式:
(5-1)×5+4=24 成立
你也可以去试试其他方块,得到的结果是一样的。
其实也能想象得出来,多了一维的情况下,公式变成了这样
其实也能想象得出来,多了一维的情况下,公式变成了这样
(所在高度-1)×总的行数×总的列数+(所在行数-1)×总的列数+所在列数VB代码
- Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
- Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
- Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
- Private Sub Gen()
- '....
- LoopDB = BmpWidth * BmpHeight * BY '长*宽*高
- LoopBI = BmpWidth * BmpHeight '长*宽
- TempHX = Replace(Format(Hex(BmpWidth), "@@@@"), " ", "0") '转换成16进制的字符串,以便于写入文件
- TempHY = Replace(Format(Hex(BY), "@@@@"), " ", "0")
- TempHZ = Replace(Format(Hex(BmpHeight), "@@@@"), " ", "0")
- TempHLoopDB = Replace(Format(Hex(LoopDB), "@@@@@@@@"), " ", "0")
- TempHLoopBI = Replace(Format(Hex(LoopBI), "@@@@@@@@"), " ", "0")
- HX = TempHX
- HY = TempHY
- HZ = TempHZ
- HLoopDB = TempHLoopDB
- HLoopBI = TempHLoopBI
- ReDim StrDT(LoopDB)
- ReDim StrBL(LoopDB)
- For Y=1 To BY
- For X=1 To BmpWidth
- For Z=1 To BmpHeight
- StrP = (Y - 1) * (BmpWidth * BmpHeight) + (Z - 1) * BmpWidth + X '3维方块对应Block和Data数据的位置
- StrBL(StrP) = m_Names(Block) '也许用结构体会好点?
- StrDT(StrP) = m_Nbt(Block)
- '....Block的处理
- Next
- Next
- Next
- Open App.Path & "\temp" For Binary As #1 '在当前目录下新建temp文件
- Put #1, , Chr$(10) & Chr$(0) & Chr$(9) & "Schematic" '指定的分隔字符串(两字节)+数据标题长度(一字节)+数据标题+数据长度(+数据)
- Put #1, , Chr$(2) & Chr$(0) & Chr$(6) & "Height"
- Put #1, , CByte("&H" & CStr(Left(HY, 2))) '数据的长度(要以二进制的文件写入)
- Put #1, , CByte("&H" & CStr(Right(HY, 2)))
- Put #1, , Chr$(2) & Chr$(0) & Chr$(6) & "Length"
- Put #1, , CByte("&H" & CStr(Left(HZ, 2)))
- Put #1, , CByte("&H" & CStr(Right(HZ, 2)))
- Put #1, , Chr$(2) & Chr$(0) & Chr$(5) & "Width"
- Put #1, , CByte("&H" & CStr(Left(HX, 2)))
- Put #1, , CByte("&H" & CStr(Right(HX, 2)))
- Put #1, , Chr$(9) & Chr$(0) & Chr$(8) & "Entities" & Chr$(1) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(9) & Chr$(0) & Chr$(12) & "TileEntities" & Chr$(1) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(9) & Chr$(0) & Chr$(9) & "TileTicks" & Chr$(1) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(8) & Chr$(0) & Chr$(9) & "Materials" & Chr$(0) & Chr$(5) & "Alpha" & Chr$(7) & Chr$(0) & Chr$(4) & "Data"
- Put #1, , CByte("&H" & CStr(Left(HLoopDB, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopDB, 3, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopDB, 5, 2)))
- Put #1, , CByte("&H" & CStr(Right(HLoopDB, 2)))
- For I = 0 To LoopDB - 1
- If Len(StrDT(I)) = 0 Then
- Put #1, , Chr$(0)
- Else
- Put #1, , CByte(StrDT(I)) 'VB的bug?直接Put #1, , StrDT每两个字节之间会多出00
- End If
- Next
- Put #1, , Chr$(7) & Chr$(0) & Chr$(6) & "Biomes"
- Put #1, , CByte("&H" & CStr(Left(HLoopBI, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopBI, 3, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopBI, 5, 2)))
- Put #1, , CByte("&H" & CStr(Right(HLoopBI, 2)))
- For I = 0 To LoopBI - 1
- Put #1, , Chr$(0)
- Next
- Put #1, , Chr$(7) & Chr$(0) & Chr$(6) & "Blocks"
- Put #1, , CByte("&H" & CStr(Left(HLoopDB, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopDB, 3, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopDB, 5, 2)))
- Put #1, , CByte("&H" & CStr(Right(HLoopDB, 2)))
- For I = 0 To LoopDB - 1
- If Len(StrBL(I)) = 0 Then
- Put #1, , Chr$(0)
- Else
- Put #1, , CByte(StrBL(I))
- End If
- Next
- Put #1, , Chr$(0)
- Close #1
- OutPut
- End Sub
- Private Sub OutPut()
- Dim Path As String
- Dim I As Long, R As Long, P As Long
- Path = SaveFile()'文件对话框,这里不多讲了,此时Path已经成为一个Schematic的目录
- I = Shell(App.Path & "\gzip.exe -f """ & App.Path & "\temp""", vbNormalFocus) '调用Gzip压缩(输出为.gz文件)
- P = OpenProcess(SYNCHRONIZE, False, I) '等待进程(文件都没有生成怎么进行下一步啊喂)
- R = WaitForSingleObject(P, INFINITE)
- R = CloseHandle(P)
- I = Shell("cmd /c copy """ & App.Path & "\temp.gz"" " & Path & " /y", vbNormalFocus)'重命名成.Schematic文件
- P = OpenProcess(SYNCHRONIZE, False, I)
- R = WaitForSingleObject(P, INFINITE)
- R = CloseHandle(P)
- I = Shell("cmd /c del /f /q """ & App.Path & "\temp.gz""", vbNormalFocus)'删除Temp
- P = OpenProcess(SYNCHRONIZE, False, I)
- R = WaitForSingleObject(P, INFINITE)
- R = CloseHandle(P)
- End Sub
- 在VB写入文件时,方块等数据不能使用Chr,这是因为当Chr的Acsii编码超过128的都会被翻译成”?”,所以需要通过写入Binary文件,调用CByte来写入文件。
- 除数据标题以外以上数据都以二进制的方式写入文件。
- 数据可以调换顺序。
2021.12 数据,可能有更多内容
前言可能有些人的程序需要对Schematic格式的支持,所以我自己摸索了几天(其实还是去年暑假了)。其实Wiki里有关于Schematic的格式的介绍,但是我自己通过导出MCEdit发现和Wiki中有些不一样,比如有些项目我导出来并没有,这里我就按我导出的的文件格式讲一下Schematic的格式。格式
对象 |
作用 |
大小 |
Schematic |
识别Schematic格式 |
12字节 |
Height |
高度Y 最大64K(mod突破高度限制?) |
2字节 |
Length |
长度Z 最大64K |
2字节 |
Width |
宽度X 最大64K |
2字节 |
Entities |
实体 |
不固定默认8字节 |
TileEntities |
NBT |
不固定默认8字节 |
TileTicks |
方块要更新的数据 |
不固定默认8字节 |
Materials |
版本 默认Alpha 随意填其他没有事 |
不固定 |
Data |
方块数据 也就是setblock后面那个数字 |
X × Y × Z字节 |
Biomes |
每个方块的生物群系 |
X × Z字节 |
Block |
方块(数字ID, 1. 8及之后可以使用MCEdit-Unified查看) |
X × Y × Z字节 |
- 如果生物群系对你有作用的话,请看下表
名称 |
数字ID |
数字ID(16进制) |
海洋 |
0 |
0 |
平原 |
1 |
1 |
沙漠 |
2 |
2 |
山地 |
3 |
3 |
森林 |
4 |
4 |
针叶林 |
5 |
5 |
沼泽 |
6 |
6 |
河流 |
7 |
7 |
下界荒地 |
8 |
8 |
末地 |
9 |
9 |
冻洋 |
10 |
A |
冻河 |
11 |
B |
积雪的冻原 |
12 |
C |
雪山 |
13 |
D |
蘑菇岛 |
14 |
E |
蘑菇岛岸 |
15 |
F |
沙滩 |
16 |
10 |
沙漠丘陵 |
17 |
11 |
繁茂的丘陵 |
18 |
12 |
针叶林丘陵 |
19 |
13 |
山地边缘 |
20 |
14 |
丛林 |
21 |
15 |
丛林丘陵 |
22 |
16 |
丛林边缘 |
23 |
17 |
深海 |
24 |
18 |
石岸 |
25 |
19 |
积雪的沙滩 |
26 |
1A |
桦木森林 |
27 |
1B |
桦木森林丘陵 |
28 |
1C |
黑森林 |
29 |
1D |
积雪的针叶林 |
30 |
1E |
积雪的针叶林丘陵 |
31 |
1F |
巨型针叶林 |
32 |
20 |
巨型针叶林丘陵 |
33 |
21 |
繁茂的山地 |
34 |
22 |
热带草原 |
35 |
23 |
热带高原 |
36 |
24 |
恶地 |
37 |
25 |
繁茂的恶地高原 |
38 |
26 |
恶地高原 |
39 |
27 |
末地小型岛屿 |
40 |
28 |
末地中型岛屿 |
41 |
29 |
末地高岛 |
42 |
2A |
末地荒岛 |
43 |
2B |
暖水海洋 |
44 |
2C |
温水海洋 |
45 |
2D |
冷水海洋 |
46 |
2E |
暖水深海 |
47 |
2F |
温水深海 |
48 |
30 |
冷水深海 |
49 |
31 |
封冻深海 |
50 |
32 |
虚空 |
127 |
7F |
向日葵平原 |
129 |
81 |
沙漠湖泊 |
130 |
82 |
沙砾山地 |
131 |
83 |
繁花森林 |
132 |
84 |
针叶林山地 |
133 |
85 |
沼泽山丘 |
134 |
86 |
冰刺平原 |
140 |
8C |
丛林变种 |
149 |
95 |
丛林边缘变种 |
151 |
97 |
高大桦木森林 |
155 |
9B |
高大桦木丘陵 |
156 |
9C |
黑森林丘陵 |
157 |
9D |
积雪的针叶林山地 |
158 |
9E |
巨型云杉针叶林 |
160 |
A0 |
巨型云杉针叶林丘陵 |
161 |
A1 |
沙砾山地+ |
162 |
A2 |
破碎的热带草原 |
163 |
A3 |
破碎的热带高原 |
164 |
A4 |
被风蚀的恶地 |
165 |
A5 |
繁茂的恶地高原变种 |
166 |
A6 |
恶地高原变种 |
167 |
A7 |
竹林 |
168 |
A8 |
竹林丘陵 |
169 |
A9 |
灵魂沙峡谷 |
170 |
AA |
绯红森林 |
171 |
AB |
诡异森林 |
172 |
AC |
玄武岩三角洲 |
173 |
AD |
- 谜?
对于其中的高度限制,我还是不太清楚。虽然说有些Mod可以突破高度限制,但是似乎Mcedit也有高度限制。几次实验后发现如果高度大于255,那么高度好像会从第一行重新写入,也就是说把从第一行已经生成的方块给覆盖掉。如果只有255方块,那么为什么大小要设置成两个字节,难道一个字节不就能用完呢?希望有人能帮我解惑。 - 格式中每个数据(姑且就这么叫吧)之间有指定的字符串去隔开,而在指定的字符串后还要声明此数据的长度。所以每一个数据的格式如下指定的分隔字节(两字节)+数据标题长度(一字节)+数据标题+数据长度(+数据)(当为Data,Biomes,Block…时)
值 |
识别对象 |
0x0A 0x00 |
Schematic文件 |
0x02 0x00 |
Height,Length,Width |
0x09 0x00 |
Entities,TileEntities,TileTicks |
0x08 0x00 |
Materials |
0x07 0x00 |
Data,Biomes,Blocks |
- 知道了格式接下来就好做了。
将数据写入文件,再通过同目录下的gzip.exe压缩成x.gz文件,最后重命名为Schematic文件即可用MCEdit打开。

Schematic(gzip压缩后)

temp(gzip压缩前)
- 那么这里就讲一下data和block数据吧
通过立体坐标计算那么坐标为(X,Y,Z)的方块的data和block数据位于第 (Y - 1) × (Width × Height) + ( Z - 1) × Width + X

- 按X和Z轴来进行,这里有一个5*5的二维平面。我们从第一个方块开始,给每一个方块标记数字。在二维中公式是这样的 (所在行数-1)×总的列数+所在列数
其实也能想象得出来,多了一维的情况下,公式变成了这样 (所在高度-1)×总的行数×总的列数+(所在行数-1)×总的列数+所在列数VB代码
- Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
- Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
- Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
- Private Sub Gen()
- '....
- LoopDB = BmpWidth * BmpHeight * BY '长*宽*高
- LoopBI = BmpWidth * BmpHeight '长*宽
- TempHX = Replace(Format(Hex(BmpWidth), "@@@@"), " ", "0") '转换成16进制的字符串,以便于写入文件
- TempHY = Replace(Format(Hex(BY), "@@@@"), " ", "0")
- TempHZ = Replace(Format(Hex(BmpHeight), "@@@@"), " ", "0")
- TempHLoopDB = Replace(Format(Hex(LoopDB), "@@@@@@@@"), " ", "0")
- TempHLoopBI = Replace(Format(Hex(LoopBI), "@@@@@@@@"), " ", "0")
- HX = TempHX
- HY = TempHY
- HZ = TempHZ
- HLoopDB = TempHLoopDB
- HLoopBI = TempHLoopBI
- ReDim StrDT(LoopDB)
- ReDim StrBL(LoopDB)
- For Y=1 To BY
- For X=1 To BmpWidth
- For Z=1 To BmpHeight
- StrP = (Y - 1) * (BmpWidth * BmpHeight) + (Z - 1) * BmpWidth+ X '3维方块对应Block和Data数据的位置
- StrBL(StrP) = m_Names(Block) '也许用结构体会好点?
- StrDT(StrP) = m_Nbt(Block)
- '....Block的处理
- Next
- Next
- Next
- Open App.Path & "\temp" For Binary As #1 '在当前目录下新建temp文件
- Put #1, , Chr$(10) & Chr$(0) & Chr$(9) & "Schematic" '指定的分隔字符串(两字节)+数据标题长度(一字节)+数据标题+数据长度(+数据)
- Put #1, , Chr$(2) & Chr$(0) & Chr$(6) & "Height"
- Put #1, , CByte("&H" & CStr(Left(HY, 2))) '数据的长度(要以二进制的文件写入)
- Put #1, , CByte("&H" & CStr(Right(HY, 2)))
- Put #1, , Chr$(2) & Chr$(0) & Chr$(6) & "Length"
- Put #1, , CByte("&H" & CStr(Left(HZ, 2)))
- Put #1, , CByte("&H" & CStr(Right(HZ, 2)))
- Put #1, , Chr$(2) & Chr$(0) & Chr$(5) & "Width"
- Put #1, , CByte("&H" & CStr(Left(HX, 2)))
- Put #1, , CByte("&H" & CStr(Right(HX, 2)))
- Put #1, , Chr$(9) & Chr$(0) & Chr$(8) & "Entities" & Chr$(1) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(9) & Chr$(0) & Chr$(12) & "TileEntities" & Chr$(1) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(9) & Chr$(0) & Chr$(9) & "TileTicks" & Chr$(1) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(0) & Chr$(8) & Chr$(0) & Chr$(9) & "Materials" & Chr$(0) & Chr$(5) & "Alpha" & Chr$(7) & Chr$(0) & Chr$(4) & "Data"
- Put #1, , CByte("&H" & CStr(Left(HLoopDB, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopDB, 3, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopDB, 5, 2)))
- Put #1, , CByte("&H" & CStr(Right(HLoopDB, 2)))
- For I = 0 To LoopDB - 1
- If Len(StrDT(I)) = 0 Then
- Put #1, , Chr$(0)
- Else
- Put #1, , CByte(StrDT(I)) 'VB的bug?直接Put #1, , StrDT每两个字节之间会多出00
- End If
- Next
- Put #1, , Chr$(7) & Chr$(0) & Chr$(6) & "Biomes"
- Put #1, , CByte("&H" & CStr(Left(HLoopBI, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopBI, 3, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopBI, 5, 2)))
- Put #1, , CByte("&H" & CStr(Right(HLoopBI, 2)))
- For I = 0 To LoopBI - 1
- Put #1, , Chr$(0)
- Next
- Put #1, , Chr$(7) & Chr$(0) & Chr$(6) & "Blocks"
- Put #1, , CByte("&H" & CStr(Left(HLoopDB, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopDB, 3, 2)))
- Put #1, , CByte("&H" & CStr(Mid(HLoopDB, 5, 2)))
- Put #1, , CByte("&H" & CStr(Right(HLoopDB, 2)))
- For I = 0 To LoopDB - 1
- If Len(StrBL(I)) = 0 Then
- Put #1, , Chr$(0)
- Else
- Put #1, , CByte(StrBL(I))
- End If
- Next
- Put #1, , Chr$(0)
- Close #1
- OutPut
- End Sub
- Private Sub OutPut()
- Dim Path As String
- Dim I As Long, R As Long, P As Long
- Path = SaveFile()'文件对话框,这里不多讲了,此时Path已经成为一个Schematic的目录
- I = Shell(App.Path & "\gzip.exe -f """ & App.Path & "\temp""", vbNormalFocus) '调用Gzip压缩(输出为.gz文件)
- P = OpenProcess(SYNCHRONIZE, False, I) '等待进程(文件都没有生成怎么进行下一步啊喂)
- R = WaitForSingleObject(P, INFINITE)
- R = CloseHandle(P)
- I = Shell("cmd /c copy """ & App.Path & "\temp.gz"" " & Path & " /y", vbNormalFocus)'重命名成.Schematic文件
- P = OpenProcess(SYNCHRONIZE, False, I)
- R = WaitForSingleObject(P, INFINITE)
- R = CloseHandle(P)
- I = Shell("cmd /c del /f /q """ & App.Path & "\temp.gz""", vbNormalFocus)'删除Temp
- P = OpenProcess(SYNCHRONIZE, False, I)
- R = WaitForSingleObject(P, INFINITE)
- R = CloseHandle(P)
- End Sub
- 在VB写入文件时,方块等数据不能使用Chr,这是因为当Chr的Acsii编码超过128的都会被翻译成”?”,所以需要通过写入Binary文件,调用CByte来写入文件。
- 除数据标题以外以上数据都以二进制的方式写入文件。
- 数据可以调换顺序。
欸,如果有支持基岩版的schematic制作软件就好了
投影mod的sch文件不通用吗
应该是可以互相用的吧
新版本还有高度限制吗
有些东西好厉害的样子看不懂
1930940598 发表于 2020-3-3 16:03
新版本还有高度限制吗
这个是根据Mcedit和投影mod的来的,我这里使用mcedit加载高度超过255的Schematic文件如果超过的话会会从Y=1重新写入,也就是第一层被256层给覆盖了。虽然说这个高度的值为2个字节,也就是65535层高,但是也就用了一个字节(255层)如果你要硬试的话,加上一个更高世界的mod可能会出错的(mod存储大于255层的方块和mc存档中的mca存档可能不是一样的)。
good job!!!