const PersistentData = require('./persistent_data') const nbt = require('prismarine-nbt') class PlayerData extends PersistentData { _bots = new Set() parse (data) { const parsed = {} data = data.value // * Convenient since I don't need to write data.value a bunch of times if (data.username) parsed.username = data.username?.value if (data.seen?.value) { parsed.seen = {} if (data.seen.value.first?.value) parsed.seen.first = this.#parseSeenValue(data.seen.value.first) if (data.seen.value.last?.value) parsed.seen.last = this.#parseSeenValue(data.seen.value.last) } if (data.mail?.value?.value && Array.isArray(data.mail.value.value)) { parsed.mail = data.mail.value.value.map(this.#parseMail) } parsed.mailUnread = !!data.mailUnread?.value return parsed } #parseMail (mail) { return { sender: String(mail?.sender?.value), message: String(mail?.message?.value), host: String(mail?.host?.value), port: this.#int16ToUint16(Number(mail?.port?.value ?? 25565)) } } #parseSeenValue (value) { if (typeof value.value === 'number' || typeof value.value === 'bigint' || value.type === 'long' /* BigIntExtended moment */) { return { date: new Date(Number(value.value)) } } const result = {} if (value.value?.date?.value) result.date = new Date(Number(value?.value?.date?.value)) if (value.value?.host?.value) result.host = String(value?.value?.host?.value) if (value.value?.port?.value) result.port = this.#int16ToUint16(Number(value?.value?.port?.value ?? 25565)) return result } #int16ToUint16 (value) { const uint16Array = new Uint16Array(1) uint16Array[0] = value return uint16Array[0] } unparse (parsed) { const data = {} if (parsed.username) data.username = nbt.string(parsed.username) if (parsed.seen) { data.seen = nbt.comp({ first: this.#unparseSeenValue(parsed.seen.first), last: this.#unparseSeenValue(parsed.seen.last) }) } if (parsed.mail) { data.mail = nbt.list(nbt.comp(parsed.mail.map(this.#unparseMail))) } if (parsed.mailUnread) data.mailUnread = nbt.byte(+parsed.mailUnread) return nbt.comp(data) } #unparseMail (mail) { const result = { sender: nbt.string(mail.sender), message: nbt.string(mail.message), host: nbt.string(mail.host) } if (mail.port !== 25565) result.port = nbt.short(this.#uint16ToInt16(mail.port)) return result } #unparseSeenValue (value) { if (value.host == null && value.port == null) return nbt.long(BigInt(value.date.getTime())) return nbt.comp({ date: nbt.long(BigInt(value.date.getTime())), host: nbt.string(value.host), port: nbt.short(this.#uint16ToInt16(value.port)) }) } #uint16ToInt16 (value) { const int16Array = new Int16Array(1) int16Array[0] = value return int16Array[0] } } module.exports = PlayerData