UNPKG

bisco

Version:

Library for creating Discord bot.

185 lines (153 loc) 4.4 kB
const Discord = require('discord.js') const Command = require('./Command') const Helpers = require('./Helpers') const pack = require('../package.json') class Bisco { constructor(token) { this.token = token this.client = new Discord.Client() this.prefix = '!' this.versionString = '' this.commands = [] this.games = [] this.gameRooms = [] this.gameTimeout = 60 * 60 * 1000 this.eventListeners = [] this.onMessage(msg => { this.executeCommand(msg) this.eventListeners.forEach(listener => listener.callback(msg)) }) } registerDefaultCommands() { this.command('help', msg => { let fields = [ { name: 'version', value: this.versionString }, { name: 'コマンド一覧', value: this.commands.map(c => c.getDescField()).join('\n') } ] msg.reply({ embed: { title: `${this.client.user.tag}`, fields } }) }).setDescription('ヘルプを表示します。') this.command('games', msg => { msg.reply({ embed: { title: 'ゲーム一覧', description: this.games.map(g => g.getDescField()).join('\n') } }) }).setDescription('ゲーム一覧を表示します。') this.command('games.rooms.count', msg => { msg.reply(`現在${this.gameRooms.length}個のゲームがアクティブです。`) }).setDescription('現在プレイされているゲームの数を返します。') this.command('game.exit', msg => { const games = this.gameRooms.filter(room => room.isPlaying(msg.author)) if (games) { const game = games[0] game.exit() msg.reply(game.constructor.gameName + 'を終了しました。') return } else { msg.reply('参加中のゲームがありません。') } }).setDescription('参加中のゲームを終了します。') } executeCommand(msg) { if (this.prefix === '') throw new Error('[Bisco Error] prefix can not be empty. ') if (msg.author.bot) return if (!msg.content.startsWith(this.prefix)) return const cmd = msg.content.replace(this.prefix, '') if (cmd === 'bisco.version') { msg.reply(`Bisco v.${pack.version}`) return } for (let i = 0; i < this.commands.length; ++i) { let command = this.commands[i] if (command.getRegexp().test(cmd)) { command.execute(this, msg, cmd) return } } } setVersionString(string) { this.versionString = string } command(pattern, process) { const command = new Command(pattern, process) this.commands.push(command) return command } game(pattern, gameClass) { this.games.push(gameClass) return this.command(pattern, (msg, args) => { let room = this.gameRooms.find(g => g.isPlaying(msg.author)) if (room) { msg.reply('参加中のゲームがあります。') return } room = new gameClass(this, msg, args) room.symbol = Symbol('game') this.gameRooms.push(room) this.addOnMessage(room.symbol, msg => { room.onInput(msg) }) }) } exitGame(room) { this.removeOnMessage(room.symbol) this.gameRooms = this.gameRooms.filter(r => r !== room) } setPrefix(prefix) { this.prefix = prefix } createCallback(callback) { return () => { callback(this) } } onReady(callback) { this.client.on('ready', this.createCallback(callback)) } onMessage(callback) { this.client.on('message', callback) } addOnMessage(symbol, callback) { this.eventListeners.push({ symbol, callback }) } removeOnMessage(symbol) { this.eventListeners = this.eventListeners.filter(listener => { if (listener.symbol !== symbol) return listener }) } run() { this.registerDefaultCommands() this.client.login(this.token) setInterval(() => { let nowMs = Date.now() this.gameRooms.forEach(room => { let startedAtMs = room.startedAt if (nowMs - startedAtMs > this.gameTimeout) { room.onTimeout() room.exit() } }) }, 3000) } setGameTimeout(timeout) { this.gameTimeout = timeout } } Bisco.Game = require('./Game') Bisco.Helpers = Helpers module.exports = Bisco