chipmunkbot3/commands/client.js
2024-07-31 22:34:19 -04:00

118 lines
3.3 KiB
JavaScript

const { literal, argument, string, DynamicCommandExceptionType } = require('brigadier-commands')
const { json } = require('../util/command/argument/json')
const TextMessage = require('../util/command/text_message')
const mc = require('minecraft-protocol')
const UNKNOWN_CLIENT_ERROR = new DynamicCommandExceptionType(string => new TextMessage(['Unknown client: ', string]))
module.exports = {
clients: [],
create () {
return Object.create(this)
},
register (dispatcher) {
const node = dispatcher.register(
literal('client')
.then(
literal('create')
.then(
argument('options', json())
.executes(c => this.createCommand(c))
)
)
.then(
literal('write')
.then(
argument('client', string())
.then(
argument('name', string())
.then(
argument('data', json())
.executes(c => this.writeCommand(c))
)
)
)
)
.then(
literal('end')
.then(
argument('client', string())
.executes(c => this.endCommand(c))
)
)
.then(
literal('list')
.executes(c => this.listCommand(c))
)
)
node.description = 'Creates and manages this.clients using minecraft-protocol'
node.permissionLevel = 0
},
cleanup () {
this.clients.forEach(client => client.end())
},
createCommand (context) {
const source = context.source
const bot = source.bot
const options = { host: bot.host, port: bot.port, ...context.getArgument('options') }
const client = mc.createClient(options)
const idx = this.clients.length
client.once('login', () => source.sendFeedback([{ text: client.username, ...bot.styles.primary }, ' logged in']), false)
client.on('end', () => {
this.clients.splice(idx, 1)
source.sendFeedback([{ text: client.username, ...bot.styles.primary }, ' ended'], false)
})
client.on('error', (err) => bot.tellraw({ text: err.toString(), ...bot.styles.error }, '@a'))
this.clients.push(client)
},
writeCommand (context) {
const idx = this.findClientIdxByString(context.getArgument('client'))
const name = context.getArgument('name')
const data = context.getArgument('data')
this.clients[idx].write(name, data)
},
endCommand (context) {
const source = context.source
const idx = this.findClientIdxByString(context.getArgument('client'))
this.clients[idx].end()
this.clients.splice(idx, 1)
},
listCommand (context) {
const source = context.source
const bot = source.bot
const list = []
for (let i = 0; i < this.clients.length; i++) {
const client = this.clients[i]
if (i !== 0) list.push(', ')
list.push(client.username)
}
source.sendFeedback([{ text: 'Clients: ', ...bot.styles.primary }, list], false)
},
findClientIdxByString (string) {
let idx = Number(string)
if (!this.clients[idx]) this.clients.forEach((client, cidx) => { if (client.username === string) idx = cidx })
if (!this.clients[idx]) throw UNKNOWN_CLIENT_ERROR.create(string)
return idx
}
}