chipmunkbot3/plugins/player_data.js

91 lines
2.3 KiB
JavaScript

const fs = require('fs/promises')
const path = require('path')
const nbt = require('prismarine-nbt')
const PlayerData = require('../util/player_data')
const fileExists = require('../util/file_exists')
const getOfflineUUID = require('../util/offline_player_uuid')
const playerData = {}
async function inject (bot) {
const persistentDir = bot.paths.persistent
const playerDataDir = path.join(persistentDir, 'playerdata')
bot.playerData = playerData
bot.loadPlayerData = loadPlayerData
bot.on('player_added', handlePlayerAdded)
async function handlePlayerAdded (player) {
if (player.uuid === bot.uuid) return
let data = playerData[player.uuid]
if (data) {
data._bots.add(bot)
return
}
data = await loadPlayerData(player.username)
data._bots.add(bot)
playerData[player.uuid] = data
data.data.username = player.username
bot.emit('player_data_loaded', player, data)
}
async function loadPlayerData (uuid) {
if (uuid.length <= 16) {
// Usernames
uuid = getOfflineUUID(uuid)
}
const data = new PlayerData(path.join(playerDataDir, uuid.substring(0, 2) + '/' + uuid.substring(2) + '.dat'))
await data.load()
return data
}
bot.on('player_removed', async player => {
const data = playerData[player.uuid]
if (!data) return
data._bots.delete(bot)
if (data._bots.size) return
bot.emit('player_data_unloading', player, data)
try {
await data.unload(true)
} catch (error) {
console.error('Failed to unload data for player %s (%s):', data?.data?.username, data?.filename, error)
try {
console.error('Contents:', JSON.stringify(data))
} catch {
console.log('Unable to print contents')
}
}
delete bot.playerData[player.uuid]
})
}
async function saveAll () {
console.log('Saving player data...')
for (const uuid in playerData) {
const data = playerData[uuid]
if (!data?.data) {
// We *somehow* found some unloaded data
delete playerData[uuid]
continue
}
try {
await data.save()
} catch (error) {
console.error('Unable to write data for player %s (%s):', data?.data?.username, data?.filepath, error)
}
}
console.log('Saved!')
}
setInterval(saveAll, 60 * 3 * 1000)
module.exports = inject