Store server players are seen on & misc fixes

This commit is contained in:
Chipmunk 2024-11-07 00:09:40 -05:00
parent 9d41812df0
commit 62dfc72dbd
6 changed files with 74 additions and 25 deletions

2
bot.js
View file

@ -101,7 +101,7 @@ function createBot (options = {}) {
if (bot.autoReconnect && !options.client) { if (bot.autoReconnect && !options.client) {
setTimeout(() => { setTimeout(() => {
bot._initClient() bot._initClient()
}, 6000) }, 6000)
} }
}) })

View file

@ -41,9 +41,21 @@ module.exports = {
{ text: '', ...bot.styles.primary }, { text: '', ...bot.styles.primary },
{ text: username, ...bot.styles.secondary }, { text: username, ...bot.styles.secondary },
' was first seen on ', ' was first seen on ',
{ text: first, ...bot.styles.secondary }, { text: first.date + '', ...bot.styles.secondary },
' at ',
{ ...this.formatServer(first), ...bot.styles.secondary },
' and last seen on ', ' and last seen on ',
{ text: last, ...bot.styles.secondary } { text: last.date + '', ...bot.styles.secondary },
' at ',
{ ...this.formatServer(last), ...bot.styles.secondary }
], false) ], false)
},
formatServer (value) {
if (!value.host) return { text: 'unknown server', italic: true }
let text = value.host
if (value.port && value.port !== 25565) text += ':' + value.port
return { text }
} }
} }

View file

@ -54,7 +54,16 @@ async function inject (bot) {
bot.emit('player_data_unloading', player, data) bot.emit('player_data_unloading', player, data)
await data.unload(true) 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] delete bot.playerData[player.uuid]
}) })
} }
@ -64,7 +73,7 @@ async function saveAll () {
for (const uuid in playerData) { for (const uuid in playerData) {
const data = playerData[uuid] const data = playerData[uuid]
if (!data?.data) { if (!data?.data) {
// We _somehow_ found some unloaded data // We *somehow* found some unloaded data
delete playerData[uuid] delete playerData[uuid]
continue continue
} }
@ -72,7 +81,7 @@ async function saveAll () {
try { try {
await data.save() await data.save()
} catch (error) { } catch (error) {
console.error('Unable to write data for player %s:', data?.data?.username, error) console.error('Unable to write data for player %s (%s):', data?.data?.username, data?.filepath, error)
} }
} }
console.log('Saved!') console.log('Saved!')

View file

@ -4,20 +4,24 @@ function inject (bot) {
const seenData = data.data.seen const seenData = data.data.seen
if (seenData.first == null) { if (seenData.first == null) {
seenData.first = new Date() seenData.first = createSeenValue()
bot.tellraw([ bot.tellraw([
{ text: 'Welcome ', ...bot.styles.primary }, { text: 'Welcome ', ...bot.styles.primary },
{ text: player.username, ...bot.styles.secondary }, { text: player.username, ...bot.styles.secondary },
' to the server!' ' to the server!'
], '@a') ], '@a')
} }
seenData.last = new Date() seenData.last = createSeenValue()
}) })
bot.on('player_data_unloading', (player, data) => { bot.on('player_data_unloading', (player, data) => {
const seenData = data.data.seen const seenData = data.data.seen
if (seenData != null) seenData.last = new Date() if (seenData != null) seenData.last = createSeenValue()
}) })
function createSeenValue () {
return { date: new Date(), host: bot.host, port: bot.port ?? 25565 }
}
} }
module.exports = inject module.exports = inject

View file

@ -8,7 +8,7 @@ const COMMANDSPY_DISABLED_MESSAGE_2 = { extra: [ 'Successfully ', 'disabled', '
function inject (bot) { function inject (bot) {
let permissionLevel, gamemode, commandSpyEnabled, vanished, godEnabled let permissionLevel, gamemode, commandSpyEnabled, vanished, godEnabled
bot.on('packet.login', packet => {console.log(packet) bot.on('packet.login', packet => {
permissionLevel = 0 permissionLevel = 0
gamemode = packet.gameMode gamemode = packet.gameMode
commandSpyEnabled = false commandSpyEnabled = false

View file

@ -12,8 +12,8 @@ class PlayerData extends PersistentData {
if (data.seen?.value) { if (data.seen?.value) {
parsed.seen = {} parsed.seen = {}
if (data.seen.value.first?.value) parsed.seen.first = new Date(Number(data.seen.value.first?.value)) if (data.seen.value.first?.value) parsed.seen.first = this.#parseSeenValue(data.seen.value.first)
if (data.seen.value.last?.value) parsed.seen.last = new Date(Number(data.seen.value.last?.value)) 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)) { if (data.mail?.value?.value && Array.isArray(data.mail.value.value)) {
@ -26,26 +26,39 @@ class PlayerData extends PersistentData {
} }
#parseMail (mail) { #parseMail (mail) {
const signedPort = Number(mail?.port?.value ?? 25565)
const uint16Array = new Uint16Array(1)
uint16Array[0] = signedPort
const unsignedPort = uint16Array[0]
return { return {
sender: String(mail?.sender?.value), sender: String(mail?.sender?.value),
message: String(mail?.message?.value), message: String(mail?.message?.value),
host: String(mail?.host?.value), host: String(mail?.host?.value),
port: unsignedPort 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) { unparse (parsed) {
const data = {} const data = {}
if (parsed.username) data.username = nbt.string(parsed.username) if (parsed.username) data.username = nbt.string(parsed.username)
if (parsed.seen) { if (parsed.seen) {
data.seen = nbt.comp({ first: nbt.long(BigInt(parsed.seen.first.getTime())), last: nbt.long(BigInt(parsed.seen.last.getTime())) }) data.seen = nbt.comp({ first: this.#unparseSeenValue(parsed.seen.first), last: this.#unparseSeenValue(parsed.seen.last) })
} }
if (parsed.mail) { if (parsed.mail) {
@ -58,19 +71,30 @@ class PlayerData extends PersistentData {
} }
#unparseMail (mail) { #unparseMail (mail) {
const unsignedPort = mail.port ?? 25565
const int16Array = new Int16Array(1)
int16Array[0] = unsignedPort
const signedPort = int16Array[0]
const result = { const result = {
sender: nbt.string(mail.sender), sender: nbt.string(mail.sender),
message: nbt.string(mail.message), message: nbt.string(mail.message),
host: nbt.string(mail.host) host: nbt.string(mail.host)
} }
if (unsignedPort !== 25565) result.port = nbt.short(signedPort) if (mail.port !== 25565) result.port = nbt.short(this.#uint16ToInt16(mail.port))
return result 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 module.exports = PlayerData