class PlayerList { list = [] addPlayer (player) { this.removePlayer(player) this.list.push(player) } hasPlayer (player) { return this.getPlayer(player) !== undefined } getPlayer (player) { let identifier switch (typeof player) { case 'object': identifier = player.UUID break case 'string': identifier = player break default: throw new Error(`Get player called with ${player}`) } return this.list.find((player) => [player.UUID, player.name].some((item) => item === identifier)) } getPlayers () { return Array.from(this.list) } removePlayer (player) { this.list = this.list.filter(({ UUID }) => UUID !== player.UUID) } } class TabCompletePlayerRequester { id = 0 queue = {} bot constructor (bot) { this.bot = bot bot._client.on('target_packet', (name, data) => { if (name !== 'tab_complete') return const players = data.matches .filter((match) => !match.tooltip) .map((match) => match.match) this.returnPlayerList(data.transactionId, players) }) } getPlayerList () { return new Promise((resolve) => { this.id++ this.id %= 256 this.queue[this.id] = resolve setTimeout(() => this.returnPlayerList(this.id, this.getPlayerList()), 1000 * 5) this.bot.write('tab_complete', { transactionId: this.id, text: '/scoreboard players add ' }) }) } returnPlayerList (id, players) { if (!this.queue[id]) return this.queue[id](players) delete this.queue[id] } } function inject (bot, dcclient, config) { bot.players = new PlayerList() bot.requester = new TabCompletePlayerRequester(bot) bot._client.on('player_info', (packet) => { for (const player of packet.data) { switch (packet.action) { case 0: addPlayer(player, packet) break case 1: updateGamemode(player, packet) break case 2: updatePing(player, packet) break case 3: updateDisplayName(player, packet) break case 4: removePlayer(player, packet) break } } }) function addPlayer (player, packet) { // if (bot.players.getPlayer(player)) bot.emit('player_unvanished', player, packet); /* else */bot.emit('player_added', player, packet) bot.players.addPlayer(player) } function updateGamemode (player, packet) { const fullPlayer = bot.players.getPlayer(player) bot.emit('onPlayerGamemodeUpdate', player, packet) if (fullPlayer === undefined) return fullPlayer.gamemode = player.gamemode } function updatePing (player, packet) { const fullPlayer = bot.players.getPlayer(player) bot.emit('player_ping_updated', player, packet) if (fullPlayer === undefined) return fullPlayer.ping = player.ping } function updateDisplayName (player, packet) { const fullPlayer = bot.players.getPlayer(player) bot.emit('player_display_name_updated', player, packet) if (fullPlayer === undefined) return fullPlayer.displayName = player.displayName } async function removePlayer (player, packet) { // const fullPlayer = bot.players.getPlayer(player); // const players = await bot.requester.getPlayerList(); // // if (fullPlayer && players.some((name) => name === fullPlayer.name)) bot.emit('player_vanished', player); /* else */bot.emit('player_removed', player, packet) bot.players.removePlayer(player) } } module.exports = { inject }