87 lines
3.9 KiB
JavaScript
87 lines
3.9 KiB
JavaScript
|
const { createRestAPIClient, createStreamingAPIClient } = require('masto'),
|
||
|
jsChessEngine = require('js-chess-engine'),
|
||
|
ChessImageGenerator = require('chess-image-generator'),
|
||
|
config = require('./config.js'),
|
||
|
fs = require('fs');
|
||
|
|
||
|
(async () => {
|
||
|
const nick = config.nick,
|
||
|
rest = createRestAPIClient({
|
||
|
url: `https://${config.url}`,
|
||
|
accessToken: config.accessToken,
|
||
|
requestInit: {
|
||
|
headers: [
|
||
|
['User-Agent', nick]
|
||
|
]
|
||
|
}
|
||
|
}),
|
||
|
ws = createStreamingAPIClient({
|
||
|
streamingApiUrl: `wss://${config.url}`,
|
||
|
accessToken: config.accessToken,
|
||
|
retry: true
|
||
|
}),
|
||
|
sendMessage = async (game, aimove, status, msg) => {
|
||
|
const imageGenerator = new ChessImageGenerator({
|
||
|
size: 720,
|
||
|
light: 'rgb(200, 200, 200)',
|
||
|
dark: '#333333',
|
||
|
style: 'merida'
|
||
|
})
|
||
|
await imageGenerator.loadFEN(game.exportFEN())
|
||
|
const buf = await imageGenerator.generateBuffer(),
|
||
|
statusImage = await rest.v2.media.create({
|
||
|
file: new Blob([buf], { type: 'image/png' }),
|
||
|
skipPolling: true,
|
||
|
description: aimove ? `Chessbot move ${Object.keys(aimove)[0]} to ${Object.values(aimove)[0]}` : 'Chessbot'
|
||
|
})
|
||
|
let canmove
|
||
|
if (aimove) {
|
||
|
moves = game.moves()
|
||
|
canmove = Object.keys(moves).map(key => `move ${key} to ${moves[key].join(', ')}`)
|
||
|
}
|
||
|
await rest.v1.statuses.create({
|
||
|
status: `${msg}${aimove ? '\nMovimientos posibles:\n' + canmove.join('\n') : ''}`,
|
||
|
mediaIds: [statusImage.id],
|
||
|
visibility: 'public',
|
||
|
inReplyToId: status?.id,
|
||
|
language: status?.language
|
||
|
})
|
||
|
}
|
||
|
let game
|
||
|
if (fs.existsSync('game.txt')) {
|
||
|
game = new jsChessEngine.Game(JSON.parse(fs.readFileSync('game.txt').toString()))
|
||
|
sendMessage(game, null, null, `Partida en juego. Su turno.`)
|
||
|
}
|
||
|
for await (const notification of ws.user.notification.subscribe()) {
|
||
|
if (notification.payload['type'] === 'mention' && notification.payload['status']) {
|
||
|
const status = notification.payload['status']
|
||
|
if (status && status.visibility !== 'direct' && status.account.acct !== nick && status.content.trim() !== '') {
|
||
|
const content = ('' + status.content).replace(/<[^>]*>?/gm, '').split(' ').filter(token => !token.startsWith('@'))
|
||
|
if (!game || game?.status?.isFinished) {
|
||
|
game = new jsChessEngine.Game()
|
||
|
sendMessage(game, status, 'Una partidita de ajedrez profesor Falken?')
|
||
|
}
|
||
|
else if (content.length > 1
|
||
|
&& content[0] === 'move'
|
||
|
&& content[1].match(/^[A-H]{1}[1-8]{1}$/)
|
||
|
&& content[2].match(/^[A-H]{1}[1-8]{1}$/)) {
|
||
|
game.move(content[1], content[2])
|
||
|
const d = Date.now(),
|
||
|
levelIA = Math.floor(Math.random() * 5),
|
||
|
aimove = game.aiMove(levelIA),
|
||
|
time = Date.now() - d
|
||
|
if (game?.status && game?.status?.checkMate) {
|
||
|
await sendMessage(game, aimove, status, 'Jaque.')
|
||
|
} else {
|
||
|
await sendMessage(game, aimove, status, `Su turno, movimiento IA ${Object.keys(aimove)[0]} a ${Object.values(aimove)[0]} nivel ${levelIA + 1} en ${time / 1000}s`)
|
||
|
}
|
||
|
}
|
||
|
if (game?.status?.isFinished) {
|
||
|
fs.rmSync('game.txt')
|
||
|
} else {
|
||
|
fs.writeFileSync('game.txt', JSON.stringify(game.exportJson()))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})()
|