commit f90e24df38088f1722e41353de50de565444d6bf Author: ale Date: Thu Jan 28 13:04:03 2021 +0100 Initial commit diff --git a/config.js b/config.js new file mode 100644 index 0000000..515c073 --- /dev/null +++ b/config.js @@ -0,0 +1,7 @@ +module.exports = { + nick: 'chessbot', + service: 'xmpp://domain.com', + username: 'user', + password: 'pass', + room: 'room@conference.domain.com' +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..760abde --- /dev/null +++ b/index.js @@ -0,0 +1,99 @@ +const { client, xml } = require('@xmpp/client'), + got = require('got'), + config = require('./config'), + ChessImageGenerator = require('chess-image-generator'), + jsChess = require('js-chess-engine'), + xmpp = client({ + service: config.service, + username: config.username, + password: config.password + }), + sendMessage = async message => { + await xmpp.send(xml( + 'message', + { type: 'groupchat', to: room }, + xml('body', {}, message) + )) + }, + room = config.room, + nick = config.nick, + game = new jsChess.Game(), + iaLevel = 3 // level 3 IA max deep + +let imageGenerator, + time + +xmpp.on('stanza', async stanza => { + if (stanza.is('message') && !stanza.getChild('delay')) { + const message = stanza.getChildText('body') + if (message && game.status && game.status.isFinished) { + sendMessage('Jaque mate. Juego terminado.') + } else if (message && game.status && game.status.checkMate) { + sendMessage('Jaque.') + } else if (message && message.split(' ').length === 3 + && message.split(' ')[0] === '.move' + && message.split(' ')[1].match(/^[A-H1-8]{2}$/) + && message.split(' ')[2].match(/^[A-H1-8]{2}$/)) { + const msg = message.split(' ') + msg.shift() + game.move(msg[0], msg[1]) + const d = Date.now() + game.aiMove(iaLevel) + time = Date.now() - d + imageGenerator = new ChessImageGenerator({ + size: 720, + light: 'rgb(200, 200, 200)', + dark: '#333333', + style: 'merida' + }) + await imageGenerator.loadFEN(game.exportFEN()) + const buf = await imageGenerator.generateBuffer() + await xmpp.send(xml( + 'iq', + { + type: 'get', + to: stanza.attrs.from.replace(/\/.*$/, '').split('@')[1], + id: 'step_' + Math.floor(Math.random() * 100) + }, + xml('request', + { + xmlns: 'urn:xmpp:http:upload:0', + filename: 'chess.png', + size: buf.byteLength, + 'content-type': 'image/png' + } + ) + )).catch(console.error) + } + } else if (stanza.is('iq') && stanza.attrs.type === 'result') { + const buf = await imageGenerator.generateBuffer() + if (imageGenerator && buf.byteLength > 0 && stanza.getChild('slot') && stanza.getChild('slot').getChild('put')) { + const req = await got.put(stanza.getChild('slot').getChild('put').attrs.url, { + body: buf + }).catch(console.error) + if (req && req.url) { + sendMessage('Su turno: ' + req.url + ' movimiento IA en ' + (time / 1000) + 's') + } + } + } +}) + +xmpp.on('online', async address => { + await xmpp.send(xml( + 'presence', + { to: room + '/' + nick }, + xml('x', + { xmlns: 'http://jabber.org/protocol/muc' } + ) + )).catch(console.error) + console.log('Connected like: ' + address) + sendMessage('Comienza la partida: .move \nEj: .move B2 B3') +}) + +xmpp.on('error', console.error) + +xmpp.on('offline', () => { + console.log('Go to offline') +}) + +xmpp.start().catch(console.error) \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..2044024 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "chessbot-xmpp", + "version": "1.0.0", + "description": "Chess Bot MUC XMPP", + "main": "index.js", + "private": true, + "scripts": { + "start": "node index.js" + }, + "repository": { + "type": "git", + "url": "https://git.manalejandro.com/ale/chessbot-xmpp" + }, + "keywords": [ + "bot", + "xmpp", + "muc", + "chess" + ], + "author": "ale", + "license": "MIT", + "dependencies": { + "@xmpp/client": "*", + "cheerio": "*", + "chess-image-generator": "*", + "got": "*", + "js-chess-engine": "*" + } +} \ No newline at end of file