第一百三十五章 真正深入了解NBT-1
在之前的第一百章——“深入地了解一下NBT”中,其中的80%都有水的成分。所以今天,我們就真正深入地了解一下NBT。
——第一節(jié):NBT的格式
在之前,我們已經(jīng)講了很多NBT。這些NBT內(nèi)容都不一樣,但它們都有一個(gè)共同點(diǎn):
最外層都是使用“{}”包裹起來的。
沒錯(cuò),NBT和JSON的格式并不一樣。JSON最外層使用“[]”和“{}”都可以,NBT卻只能使用“{}”。
這是NBT的基本格式。
而NBT里面,是由N個(gè)標(biāo)簽組成的。每個(gè)標(biāo)簽之間必須用英文的半角逗號(hào)來區(qū)分。標(biāo)簽里包含標(biāo)簽名稱和值,它兩使用英文的半角冒號(hào)分隔:
{標(biāo)簽:值,標(biāo)簽:值,標(biāo)簽:值}
?。ㄗⅲ洪喿x平臺(tái)會(huì)自動(dòng)把半角改成全角,所以這里的符號(hào)是全角符號(hào),實(shí)際上在寫的時(shí)候是全是半角)
而這個(gè)標(biāo)簽中的標(biāo)簽名稱,它不是什么都能寫的,而是有一個(gè)規(guī)則:
1.標(biāo)簽名稱中只能出現(xiàn)字母a-z和A-Z、數(shù)字0~9、下劃線“_”。
2.標(biāo)簽名稱中不允許出現(xiàn)空格(空格都以下劃線替代)、中文以及特殊符號(hào)
3.標(biāo)簽名稱對(duì)大小寫敏感。
當(dāng)違反了上述規(guī)則的時(shí)候,就會(huì)報(bào)錯(cuò)(或者是被游戲理解為另外一種意思)。
而標(biāo)簽的值,大家應(yīng)該都知道標(biāo)簽的值類型是同標(biāo)簽中的標(biāo)簽名稱或由另一個(gè)標(biāo)簽決定的,所以不同的標(biāo)簽名稱,填的值格式都是不同的。
但實(shí)際上,值并不是直接寫上內(nèi)容就行了。當(dāng)標(biāo)簽名稱決定值的類型為特定類型時(shí),值實(shí)際上還會(huì)有一個(gè)可填可不填的格式,我們待會(huì)就會(huì)講到。
——第二節(jié):NBT數(shù)據(jù)類型
在之前,我們已經(jīng)提到了很多NBT數(shù)據(jù)類型的名詞:
單精度浮點(diǎn)型
雙精度浮點(diǎn)型
整形(整數(shù))
復(fù)合標(biāo)簽({})
列表([])
整型數(shù)組([I;1,2,3,4])
字符串
可以發(fā)現(xiàn),NBT的數(shù)據(jù)類型和JSON的并不一樣,而且類型還比JSON多。
其實(shí)并不是類型多,而是NBT的類型分得比較細(xì),實(shí)際上你搞個(gè)分類,就和JSON差不多了。
好的,現(xiàn)在請(qǐng)你拿出你的筆記本,并坐好,做一下心理準(zhǔn)備,我們的車馬上就要開動(dòng)了!
3
2
1
GO!
NBT一共有14種數(shù)據(jù)類型,分別是:
[字符]
字符串(String)
[數(shù)值]
{整形}
字節(jié)型(Byte:B)
短整型(Short:S)
整型(Int:I)
長(zhǎng)整型(Long:L)
{浮點(diǎn)型(小數(shù))}
單精度浮點(diǎn)型(Float:F)
雙精度浮點(diǎn)型(Double:D)
[數(shù)據(jù)]
復(fù)合標(biāo)簽(Compound)
列表(List)
[數(shù)組]
字節(jié)型數(shù)組(Byte Array:[B])
整型數(shù)組(Int Array:[I])
長(zhǎng)整型數(shù)組(Long Array:[L])
我們從字符串(String)這個(gè)最簡(jiǎn)單的類型入手。眾所周知,字符串類型的值其外層需要使用英文的半角雙引號(hào)(““)來包括。當(dāng)引號(hào)里的值要寫上引號(hào)時(shí),就需要使用轉(zhuǎn)義符號(hào)(\)放在引號(hào)前面轉(zhuǎn)義。要在里面寫上反斜杠(\)時(shí)也一樣。比如:
{text:“我叫\(zhòng)“小明\“,這是反斜杠:\\“}
你知道嗎?其實(shí)NBT的字符串并不一定需要使用雙引號(hào)來包括,單引號(hào)也可以,只不過這是1.14版本才更新的:
{text:'我叫\(zhòng)'小明\',這是反斜杠:\\'}
如上面這個(gè)例子,要在值里面寫上單引號(hào),也是需要使用轉(zhuǎn)義符號(hào)(\)的。
而這個(gè)字符串還遠(yuǎn)遠(yuǎn)不止那么簡(jiǎn)單。字符串的存儲(chǔ)上線是32767個(gè)字節(jié),可以含有中文、空格和特殊字符,編碼形式為UTF-8。所以這就是為什么命令方塊其字符上限就是32767,因?yàn)檫@就是字符串類型的值上線了。
只不過我們都知道,就連最基礎(chǔ)的漢字也要占用2字節(jié)的空間,而UTF-8作為萬國碼,存儲(chǔ)的字符就更多了。所以UTF-8的基礎(chǔ)漢字一個(gè)就是3字節(jié),而字符串的上限是32767字節(jié),并不是32767個(gè)字符。所以更準(zhǔn)確的來說,命令方塊的儲(chǔ)存上限是:
32767字節(jié)(UTF-8編碼)
而不是32767個(gè)字符,這種說法是錯(cuò)誤的。
總之,字符串的特性就是:
1.值大小上限為32767字節(jié)
2.使用UTF-8編碼
3.文本可含有中文、空格和特殊字符
4.需用雙引號(hào)(““)或單引號(hào)('')(1.14版本及以后)包裹。
5.如需要在文本里寫上引號(hào)或反斜杠,需在其前面加上轉(zhuǎn)義符號(hào)(\)
然后是我們的數(shù)值:
{整形}
字節(jié)型(Byte:B)
短整型(Short:S)
整型(Int:I)
長(zhǎng)整型(Long:L)
{浮點(diǎn)型(小數(shù))}
單精度浮點(diǎn)型(Float:F)
雙精度浮點(diǎn)型(Double:D)
可以發(fā)現(xiàn),NBT的數(shù)值細(xì)分到了整數(shù)和浮點(diǎn)數(shù)(小數(shù))。我們先從整數(shù)入手,整數(shù)類型的類型有:
字節(jié)型(Byte:B)
短整型(Short:S)
整型(Int:I)
長(zhǎng)整型(Long:L)
實(shí)際上這些都是存儲(chǔ)整數(shù)。它們的明顯差別只不過是名字的不同和數(shù)值上下限的不同。
最小的字節(jié)型(Byte:B),其值是存儲(chǔ)一個(gè)絕對(duì)值很小的整數(shù),范圍是:
-128~127「-(2?)~2?-1」
很簡(jiǎn)單對(duì)吧?
其實(shí)不簡(jiǎn)單。在第一節(jié)的最后,作者提到特定類型的值還有可填可不填的格式。這個(gè)字節(jié)型就是其中之一,其格式其實(shí)是這樣的:
{Byte:數(shù)值b}
沒錯(cuò),字節(jié)型的值需要你在填完數(shù)值之后再加上一個(gè)特定的字母,通常是這個(gè)類型其英文縮寫的小寫形式,比如字節(jié)型的Byet縮寫就是B,再小寫一下就是b。
為什么要這樣呢?其實(shí)這就是起到一個(gè)區(qū)分的作用,實(shí)際上你不在最后面寫b也是可以的,游戲大部分情況會(huì)自動(dòng)幫你加上去。當(dāng)出現(xiàn)錯(cuò)誤時(shí)可能才需要用到。短整型和長(zhǎng)整型以及其他的一些類型也是數(shù)值后面有類型字母的,當(dāng)然大部分情況它們不填也是可以的。
實(shí)際上Byte類型值不僅僅是個(gè)數(shù)值,它還有另一種值:
布爾值(false|true)
沒錯(cuò),Byte值也是布爾值,這個(gè)布爾值一般是數(shù)字形式的:
1和0
也有些情況下是true和false。
當(dāng)為字母形式時(shí),就不用填最后的b了,只需要類似于字符串那樣加上引號(hào)就可以了(好像不加也可以)。
這就是Byte類型。按理來說一個(gè)普通的MC指令教程說到這就可以了,但這本書并不普通。所以接下來我們要研究一個(gè)問題:
為什么這個(gè)值類型叫做“字節(jié)型”呢?
其實(shí)答案很簡(jiǎn)單。剛才的數(shù)值范圍大家也都知道,是:
-128~127,
也就是-(2?)~2?-1(二的七次冪的相反數(shù)到二的七次冪減一的差)
我們的一個(gè)字節(jié),也就是:
8bit(8個(gè)二進(jìn)制數(shù)字)
字節(jié)型數(shù)值的絕對(duì)值最大值是128,即2?,轉(zhuǎn)換成二進(jìn)制就是10000000,剛好一字節(jié)。
這就是字節(jié)型這個(gè)名稱的由來,是不是灰常簡(jiǎn)單?
總之,字節(jié)型(Byte:B)的特性就是:
1.值為整數(shù)或布爾值
2.當(dāng)值為數(shù)值時(shí),數(shù)值范圍為-128~127
3.當(dāng)值為數(shù)值時(shí),需要在值最后加上類型字母b
4.占用空間只有1字節(jié)
?。ò?,為什么最大值不是11111111,即511?)
?。ㄓ醒a(bǔ)碼懂不懂?有補(bǔ)碼才能區(qū)分正負(fù)?。?p> 比字節(jié)型范圍稍大的短整型(Short:S),在上面就有提到其也是有類型字母的。而這個(gè)類型字母就是:s,具體這個(gè)放在哪里大家都應(yīng)該知道的。
短整形的數(shù)值范圍是:
-32768~32767「-(21?)~21?-1」(占用2字節(jié))
是不是很熟悉?沒錯(cuò),1.13版本以下附魔的等級(jí)值就是短整形,所以當(dāng)時(shí)的附魔最大等級(jí)才是32767。
所以我們可以根據(jù)這個(gè)附魔的標(biāo)簽來舉個(gè)例子:
{ench:[{lvl:32767s,id:18s}]}——這就是短整形的最大值,也就是附魔等級(jí)的最大值
{ench:[{lvl:-32768s,id:18s}]}——這就是短整形的最小值,也是附魔等級(jí)的理論最小值(LV.-32767?)
?。?xì)心的朋友可能注意到了,1.13以前的id其值也是短整形)
到了1.13以后,情況就不一樣了。Mojang把lvl值類型改成了int整形,附魔的上限也就升級(jí)到了2147483647。但實(shí)際上,在新版本,lvl其值是int和Short混用的。具體是這樣的:
用附魔臺(tái)附魔或戰(zhàn)利品表生成的,是Short短整形,但是讀取時(shí)是按照int整形的時(shí)候來讀取的。其他的就直接是int了。
只不過這些東西,我們以后再說?,F(xiàn)在回到正題。
Short的內(nèi)容就是這么多??偟膩碚f,Short短整形的特性就是:
1.值范圍是-32768~32767(整數(shù))
2.類型字母為s
3.占用空間2字節(jié)
OK NBT標(biāo)簽的內(nèi)容就暫且到這里了,我們下一章再見。
?。ㄑa(bǔ)碼是什么?。浚?p> ?。ê?jiǎn)單來說,這八位的第一位是表示正負(fù)號(hào),0為正,1為負(fù)。所以負(fù)值最小可以到-128即10000000,正值最大可以到127即01111111。)
?。ㄅ抖硕耍?p> ?。ú还鈈yte有補(bǔ)碼,Minecraft的十四種NBT數(shù)據(jù)類型中,除了字符串、復(fù)合標(biāo)簽、列表這三樣,其他都有補(bǔ)碼)
?。▽?duì)了,byte作為布爾值時(shí)是沒有補(bǔ)碼的。實(shí)際上在Java語言中,byte數(shù)值沒有布爾值這個(gè)用途,表示布爾值的是一個(gè)叫boolean的數(shù)據(jù)類型,Minecraft的NBT中Mojang把boolean的功能合并到了byte中,所以這就是為什么byte還有一個(gè)挺突兀的布爾值功能)