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())) } } } } })()