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