前情提要: [没什么用的教程] 完全反序列化internal
这个存储方法的确极限压缩的nbt文本的占用体积,恰巧上午我不知道怎么查看.dat文件,还去下了个NBTExplorer玩()
刚才我就突发奇想。。。这.dat文件。。。不会也是这么存的吧?
测了一下发现确实()
测试代码如下:复制代码我对我服务端内world世界的scoreboard.dat文件进行了解析。
后台返回值如下:复制代码很完美对吧()
这个存储方法的确极限压缩的nbt文本的占用体积,恰巧上午我不知道怎么查看.dat文件,还去下了个NBTExplorer玩()
刚才我就突发奇想。。。这.dat文件。。。不会也是这么存的吧?
测了一下发现确实()
测试代码如下:
- const ByteArray = Java.type("byte[]")
- const IntArray = Java.type("int[]")
- const LongArray = Java.type("long[]")
- const ArrayList = Packages.java.util.ArrayList
- const HashMap = Packages.java.util.HashMap
- const GZIPInputStream = Packages.java.util.zip.GZIPInputStream
- const BufferedInputStream = Packages.java.io.BufferedInputStream
- const DataInputStream = Packages.java.io.DataInputStream
- const YamlConfiguration = Packages.org.bukkit.configuration.file.YamlConfiguration
- const FileInputStream = Packages.java.io.FileInputStream
- const File = Packages.java.io.File
- // 这里对应Bukkit的NBTTagTypes
- const types = [
- // END类型, 代表已达当前Compound结尾
- function() { return null },
- // Byte类型, 直接读取
- function(dataInputStream) { return dataInputStream.readByte() },
- // Short类型, 直接读取
- function(dataInputStream) { return dataInputStream.readShort() },
- // Int类型, 直接读取
- function(dataInputStream) { return dataInputStream.readInt() },
- // Long类型, 直接读取
- function(dataInputStream) { return dataInputStream.readLong() },
- // Float类型, 直接读取
- function(dataInputStream) { return dataInputStream.readFloat() },
- // Double类型, 直接读取
- function(dataInputStream) { return dataInputStream.readDouble() },
- // ByteArray类型
- function(dataInputStream) {
- // 首位Int用于存储数组长度
- const length = dataInputStream.readInt()
- // 创建相应长度的数组
- const byteArray = new ByteArray(length)
- // byte[]不用整那么多花活儿, 直接readFully就行
- dataInputStream.readFully(byteArray)
- return byteArray
- },
- // String类型, 直接读取
- function(dataInputStream) { return dataInputStream.readUTF() },
- // List类型
- function(dataInputStream) {
- // 用于存储List内容
- const arrayList = new ArrayList()
- // 读取数据类型
- const type = dataInputStream.readByte()
- // 读取列表长度
- const length = dataInputStream.readInt()
- // 如果数据类型是0, 说明这玩意儿有问题; 如果列表长度是0, 直接返回就行
- if (type != 0 && length != 0) {
- // 获取相应类型的读取函数
- const func = types[Number(type)]
- // 逐个读取并存入列表
- for (let index = 0; index < length; index++) {
- arrayList.add(func(dataInputStream))
- }
- }
- // 返回内容
- return arrayList
- },
- // Compound类型
- function(dataInputStream) {
- // 用于存储Compound内容
- const hashMap = new HashMap()
- // 读取数据类型
- let type = dataInputStream.readByte()
- // 如果尚未达到Compound结尾
- while (type != 0) {
- // 读取数据键
- const key = dataInputStream.readUTF()
- // 存入数据值
- hashMap[key] = types[Number(type)](dataInputStream)
- // 读取下一位数据类型
- type = dataInputStream.readByte()
- }
- // 返回内容
- return hashMap
- },
- // IntArray类型
- function(dataInputStream) {
- // 首位Int用于存储数组长度
- const length = dataInputStream.readInt()
- // 创建相应长度的数组
- const intArray = new IntArray(length)
- // 逐个读取Int并存入数组
- for (let index = 0; index < length; index++) {
- intArray[index] = dataInputStream.readInt()
- }
- return intArray
- },
- // LongArray类型
- function(dataInputStream) {
- // 首位Int用于存储数组长度
- const length = dataInputStream.readInt()
- // 创建相应长度的数组
- const longArray = new LongArray(length)
- // 逐个读取Long并存入数组
- for (let index = 0; index < length; index++) {
- longArray[index] = dataInputStream.readLong()
- }
- return longArray
- }
- ]
- function readDat(file) {
- const dataInputStream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(new FileInputStream(file))))
- const type = dataInputStream.readByte()
- dataInputStream.readByte()
- dataInputStream.readByte()
- const result = types[Number(type)](dataInputStream)
- dataInputStream.close()
- return result
- }
- const map = readDat(new File("G:" + File.separator + "Server" + File.separator + "测试用服务端" + File.separator + "1.16.5NI测试" + File.separator + "world" + File.separator + "data" + File.separator + "scoreboard.dat"))
- let itemString = new YamlConfiguration()
- itemString.set("QAZXSWEDCVFR", map)
- itemString = itemString.saveToString().replace("QAZXSWEDCVFR:\n ", "").replace(/\n /g, "\n")
- print(itemString)
后台返回值如下:
- [21:37:04 INFO]: data:
- [21:37:04 INFO]: PlayerScores:
- [21:37:04 INFO]: - Objective: NeigeMana
- [21:37:04 INFO]: Locked: 1
- [21:37:04 INFO]: Score: 20
- [21:37:04 INFO]: Name: Neige
- [21:37:04 INFO]: Objectives:
- [21:37:04 INFO]: - CriteriaName: dummy
- [21:37:04 INFO]: DisplayName: '{"text":"NeigeMana"}'
- [21:37:04 INFO]: RenderType: integer
- [21:37:04 INFO]: Name: NeigeMana
- [21:37:04 INFO]: Teams:
- [21:37:04 INFO]: - CollisionRule: always
- [21:37:04 INFO]: DeathMessageVisibility: always
- [21:37:04 INFO]: AllowFriendlyFire: 1
- [21:37:04 INFO]: MemberNamePrefix: '{"text":""}'
- [21:37:04 INFO]: SeeFriendlyInvisibles: 1
- [21:37:04 INFO]: DisplayName: '{"text":"LD_NoName"}'
- [21:37:04 INFO]: MemberNameSuffix: '{"text":""}'
- [21:37:04 INFO]: NameTagVisibility: never
- [21:37:04 INFO]: Name: LD_NoName
- [21:37:04 INFO]: Players:
- [21:37:04 INFO]: -
- [21:37:04 INFO]: DataVersion: 2586
windows,用中文做目录名……小伙子很勇嘛
teddyxlandlee 发表于 2022-8-13 20:02
windows,用中文做目录名……小伙子很勇嘛
测试端,遇到问题再看就是了