chipmunkbot3/plugins/players.js
Chipmunk 1a8d4a12e8 Support legacy versions
Hypothetically, the bot should now work on 1.14 and newer
2024-08-03 16:26:00 -04:00

95 lines
2.6 KiB
JavaScript

const { parseText } = require('../util/chat/utility')
const gamemodes = ['survival', 'creative', 'adventure', 'spectator']
function inject (bot) {
bot.players = []
bot.on('packet.player_info', packet => {
const usesBitfield = bot.supportFeature('playerInfoActionIsBitfield')
let f
if (usesBitfield) {
if (packet.action & 1) f = addPlayer
else f = updatePlayer
} else {
if (packet.action === 0) f = addPlayer
else if (packet.action === 4) f = p => removePlayer(p.uuid)
else f = updatePlayer
}
for (const player of packet.data) {
const parsed = parsePlayer(player)
f(parsed)
}
})
bot.on('packet.player_remove', packet => {
for (const uuid of packet.players) {
removePlayer(uuid)
}
})
function handleLegacyPlayerInfo (packet) {
for (const player of packet.data) {
switch (packet.action) {
case 0: addPlayer(player); break
case 4: removePlayer(player); break
default: updatePlayer(player)
}
}
}
function addPlayer (player) {
bot.players.filter(_player => _player.uuid !== player.uuid) // Remove duplicates
bot.players.push(player)
bot.emit('player_added', player)
}
function updatePlayer (player) {
const target = bot.players.find(_player => _player.uuid === player.uuid)
if (target == null) return
for (const key in player) {
if (player[key] == null) continue
target[key] = player[key]
}
}
async function removePlayer (uuid) {
const target = bot.players.find(_player => _player.uuid === uuid)
if (target == null) return
// Check that the player actually left
const completions = await bot.tabComplete('scoreboard players add ')
for (const match of completions.matches) {
if (match.tooltip) continue
if (match.match === target.username) {
target.listed = false
return
}
}
bot.players = bot.players.filter(player => player.uuid !== uuid)
bot.emit('player_removed', target)
}
// * It's backwards-compatible! (notice the fallbacks)
function parsePlayer (player) {
return {
uuid: player.uuid ?? player.UUID,
username: player.player?.name ?? player.name,
properties: player.player?.properties ?? player.properties,
chatSession: player.chatSession, // https://encyclopediadramatica.win/Shit_nobody_cares_about
gamemode: gamemodes[player.gamemode],
latency: player.latency ?? player.ping,
displayName: player.displayName ? parseText(player.displayName) : undefined
}
}
bot.on('end', () => (bot.players = []))
}
module.exports = inject