74 lines
1.6 KiB
JavaScript
74 lines
1.6 KiB
JavaScript
const fs = require('fs/promises')
|
|
const path = require('path')
|
|
const { createWriteStream } = require('fs')
|
|
const zlib = require('zlib')
|
|
const stream = require('stream/promises')
|
|
const nbt = require('prismarine-nbt')
|
|
const fileExists = require('./file_exists')
|
|
|
|
class PersistentData {
|
|
#endianness
|
|
data = null
|
|
|
|
constructor (filepath) {
|
|
this.filepath = filepath
|
|
this.loaded = false
|
|
}
|
|
|
|
async load () {
|
|
const { parsed, type } = await this.#loadData(this.filepath, true)
|
|
|
|
this.data = this.parse(parsed)
|
|
this.#endianness = type
|
|
this.loaded = true
|
|
}
|
|
|
|
async #loadData (filepath, tryBackup) {
|
|
if (!await fileExists(filepath)) {
|
|
return { parsed: nbt.comp({}), type: 'big' }
|
|
}
|
|
|
|
const buffer = await fs.readFile(filepath)
|
|
|
|
try {
|
|
return nbt.parse(buffer)
|
|
} catch (error) {
|
|
if (tryBackup) return this.#loadData(filepath + '_old', false)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async save () {
|
|
await fs.mkdir(path.dirname(this.filepath), { recursive: true })
|
|
|
|
const data = this.unparse(this.data)
|
|
if (await fileExists(this.filepath)) await fs.copyFile(this.filepath, this.filepath + '_old') // Back up our data before a save
|
|
|
|
const gzip = zlib.createGzip()
|
|
const out = createWriteStream(this.filepath)
|
|
|
|
gzip.pipe(out)
|
|
gzip.write(nbt.writeUncompressed(data))
|
|
gzip.end()
|
|
|
|
await stream.finished(gzip)
|
|
}
|
|
|
|
async unload (save) {
|
|
if (save) await this.save()
|
|
|
|
this.data = null
|
|
this.#endianness = undefined
|
|
this.loaded = false
|
|
}
|
|
|
|
parse (data) {
|
|
return data
|
|
}
|
|
|
|
unparse (data) {
|
|
return data
|
|
}
|
|
}
|
|
|
|
module.exports = PersistentData
|