feat: Command handler.
This commit is contained in:
parent
70cb8b84ee
commit
38ad751644
10 changed files with 148 additions and 66 deletions
|
@ -12,13 +12,13 @@ export default class ChatBot {
|
||||||
set trainType(value: TrainType) {
|
set trainType(value: TrainType) {
|
||||||
this._trainType = value
|
this._trainType = value
|
||||||
}
|
}
|
||||||
private db = new Database(join(__dirname, '..', 'db', 'db.sqlite3'))
|
public db = new Database(join(__dirname, '..', 'db', 'db.sqlite3'))
|
||||||
private _trainType: TrainType = 'All'
|
private _trainType: TrainType = 'All'
|
||||||
public constructor() {}
|
public constructor() {}
|
||||||
|
|
||||||
public getResponse(msg: Message, sendMsg?: boolean): ChatBot {
|
public getResponse(msg: Message, sendMsg?: boolean): ChatBot {
|
||||||
this.db
|
this.db
|
||||||
.get()
|
.all()
|
||||||
.then(rows => {
|
.then(rows => {
|
||||||
const a = msg.content.replace('머핀아', '')
|
const a = msg.content.replace('머핀아', '')
|
||||||
let r = rows[Math.floor(Math.random() * rows.length)].text
|
let r = rows[Math.floor(Math.random() * rows.length)].text
|
||||||
|
|
|
@ -1,29 +1,17 @@
|
||||||
import { ActivityType, Client, GatewayIntentBits, Message } from 'discord.js'
|
import { ActivityType, Client, Collection, GatewayIntentBits } from 'discord.js'
|
||||||
import ChatBot from './ChatBot'
|
import ChatBot from './ChatBot'
|
||||||
import Dokdo from 'dokdo'
|
import Dokdo from 'dokdo'
|
||||||
|
import { readdirSync } from 'node:fs'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
import Command from './Command'
|
||||||
|
import noPerm from './noPerm'
|
||||||
import 'dotenv/config'
|
import 'dotenv/config'
|
||||||
|
|
||||||
function noPerm(msg: Message) {
|
const prefix = '멒힌아 '
|
||||||
msg.reply({
|
|
||||||
content: '당신은 내 남자친구가 아니야!',
|
|
||||||
allowedMentions: {
|
|
||||||
repliedUser: false,
|
|
||||||
parse: [],
|
|
||||||
users: [],
|
|
||||||
roles: [],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function isNotOwner(msg: Message): boolean {
|
|
||||||
if (msg.author.id !== '415135882006495242') {
|
|
||||||
noPerm(msg)
|
|
||||||
return false
|
|
||||||
} else return true
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class MuffinAI extends Client {
|
export default class MuffinAI extends Client {
|
||||||
private chatBot = new ChatBot()
|
public chatBot = new ChatBot()
|
||||||
|
private modules: Collection<string, Command> = new Collection()
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super({
|
super({
|
||||||
intents: [
|
intents: [
|
||||||
|
@ -36,47 +24,40 @@ export default class MuffinAI extends Client {
|
||||||
|
|
||||||
public override login(): Promise<string> {
|
public override login(): Promise<string> {
|
||||||
this.chatBot.train(this)
|
this.chatBot.train(this)
|
||||||
|
|
||||||
|
readdirSync(join(__dirname, 'Commands')).forEach(file => {
|
||||||
|
const a = require(join(__dirname, 'Commands', file))
|
||||||
|
const b: Command = new a.default()
|
||||||
|
this.modules.set(b.name, b)
|
||||||
|
})
|
||||||
|
|
||||||
this.once('ready', client => {
|
this.once('ready', client => {
|
||||||
client.user!.setActivity({
|
client.user!.setActivity({
|
||||||
type: ActivityType.Playing,
|
type: ActivityType.Playing,
|
||||||
name: 'ㅅ살려주세요..!',
|
name: 'ㅅ살려주세요..!',
|
||||||
})
|
})
|
||||||
console.log(`먹힐 준비 완료`)
|
console.log(`먹힐 준비 완료`)
|
||||||
}).on('messageCreate', msg => {
|
}).on('messageCreate', async msg => {
|
||||||
if (msg.author.bot) return
|
if (msg.author.bot) return
|
||||||
new Dokdo(this, {
|
await new Dokdo(this, {
|
||||||
prefix: '멒힌아 ',
|
prefix,
|
||||||
noPerm,
|
noPerm,
|
||||||
aliases: ['테스트'],
|
aliases: ['테스트'],
|
||||||
owners: ['415135882006495242'],
|
owners: ['415135882006495242'],
|
||||||
}).run(msg)
|
}).run(msg)
|
||||||
if (msg.content.startsWith('머핀아 ')) this.chatBot.getResponse(msg, true)
|
if (msg.content.startsWith('머핀아 ')) this.chatBot.getResponse(msg, true)
|
||||||
else if (msg.content.startsWith('멒힌아 봇꺼')) {
|
else if (msg.content.startsWith(prefix)) {
|
||||||
if (!isNotOwner(msg)) return
|
const args: string[] = msg.content
|
||||||
this.destroy()
|
.slice(prefix.length)
|
||||||
} else if (msg.content.startsWith('멒힌아 모드변경')) {
|
.trim()
|
||||||
if (!isNotOwner(msg)) return
|
.split('/ +/g')
|
||||||
switch (this.chatBot.trainType) {
|
|
||||||
case 'muffinOnly':
|
const command = this.modules.get(args.join(' '))
|
||||||
this.chatBot.trainType = 'All'
|
if (!command) return
|
||||||
msg.channel.send('다음 모드로 변경: 전체 학습')
|
if (command.noPerm && msg.author.id !== '415135882006495242')
|
||||||
break
|
return await noPerm(msg)
|
||||||
case 'All':
|
command.execute(msg, args)
|
||||||
this.chatBot.trainType = 'muffinOnly'
|
}
|
||||||
msg.channel.send('다음 모드로 변경: 머핀만 학습')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if (msg.content.startsWith('멒힌아 현재모드')) {
|
|
||||||
if (!isNotOwner(msg)) return
|
|
||||||
switch (this.chatBot.trainType) {
|
|
||||||
case 'muffinOnly':
|
|
||||||
msg.channel.send('현재 모드: 머핀만 학습')
|
|
||||||
break
|
|
||||||
case 'All':
|
|
||||||
msg.channel.send('현재 모드: 전체 학습')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else return
|
|
||||||
})
|
})
|
||||||
return super.login()
|
return super.login()
|
||||||
}
|
}
|
||||||
|
@ -86,3 +67,9 @@ export default class MuffinAI extends Client {
|
||||||
super.destroy()
|
super.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module 'discord.js' {
|
||||||
|
interface Client {
|
||||||
|
chatBot: ChatBot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
6
src/Command.ts
Normal file
6
src/Command.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { Message } from 'discord.js'
|
||||||
|
|
||||||
|
export default abstract class Command {
|
||||||
|
protected constructor(public name: string, public noPerm: boolean = false) {}
|
||||||
|
public abstract execute(msg: Message, args: string[]): any
|
||||||
|
}
|
20
src/Commands/모드변경.ts
Normal file
20
src/Commands/모드변경.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import Command from '../Command'
|
||||||
|
import { type Message } from 'discord.js'
|
||||||
|
|
||||||
|
export default class extends Command {
|
||||||
|
public constructor() {
|
||||||
|
super('모드변경', true)
|
||||||
|
}
|
||||||
|
public async execute(msg: Message, args: string[]) {
|
||||||
|
switch (msg.client.chatBot.trainType) {
|
||||||
|
case 'muffinOnly':
|
||||||
|
msg.client.chatBot.trainType = 'All'
|
||||||
|
msg.channel.send('다음 모드로 변경: 전체 학습')
|
||||||
|
break
|
||||||
|
case 'All':
|
||||||
|
msg.client.chatBot.trainType = 'muffinOnly'
|
||||||
|
msg.channel.send('다음 모드로 변경: 머핀만 학습')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
src/Commands/봇꺼.ts
Normal file
13
src/Commands/봇꺼.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import Command from '../Command'
|
||||||
|
import { type Message } from 'discord.js'
|
||||||
|
|
||||||
|
export default class extends Command {
|
||||||
|
public constructor() {
|
||||||
|
super('봇꺼', true)
|
||||||
|
}
|
||||||
|
public execute(msg: Message, args: string[]) {
|
||||||
|
msg.channel.send('ㅇㅇ').finally(() => {
|
||||||
|
msg.client.destroy()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
21
src/Commands/학습데이터량.ts
Normal file
21
src/Commands/학습데이터량.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import Command from '../Command'
|
||||||
|
import { type Message } from 'discord.js'
|
||||||
|
|
||||||
|
export default class extends Command {
|
||||||
|
public constructor() {
|
||||||
|
super('학습데이터량')
|
||||||
|
}
|
||||||
|
public execute(msg: Message, args: string[]) {
|
||||||
|
msg.client.chatBot.db.all().then(rows => {
|
||||||
|
const user: any[] = []
|
||||||
|
const muffin: any[] = []
|
||||||
|
rows.forEach(row => {
|
||||||
|
if (row.persona === 'muffin') muffin.push(row)
|
||||||
|
else user.push(row)
|
||||||
|
})
|
||||||
|
msg.channel.send(
|
||||||
|
`머핀 데이터: ${muffin.length}개\n유저 데이터: ${user.length}개`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
18
src/Commands/현재모드.ts
Normal file
18
src/Commands/현재모드.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { type Message } from 'discord.js'
|
||||||
|
import Command from '../Command'
|
||||||
|
|
||||||
|
export default class extends Command {
|
||||||
|
public constructor() {
|
||||||
|
super('현재모드')
|
||||||
|
}
|
||||||
|
public execute(msg: Message, args: string[]) {
|
||||||
|
switch (msg.client.chatBot.trainType) {
|
||||||
|
case 'muffinOnly':
|
||||||
|
msg.channel.send('현재 모드: 머핀만 학습')
|
||||||
|
break
|
||||||
|
case 'All':
|
||||||
|
msg.channel.send('현재 모드: 전체 학습')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,15 +12,15 @@ interface ResponseData {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Database {
|
export default class Database {
|
||||||
private db: sqlite3.Database
|
private sqliteDB: sqlite3.Database
|
||||||
public constructor(dbPath: string) {
|
public constructor(dbPath: string) {
|
||||||
this.db = new sqlite3.Database(dbPath)
|
this.sqliteDB = new sqlite3.Database(dbPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
public get(): Promise<ResponseData[]> {
|
public all(): Promise<ResponseData[]> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.serialize(() => {
|
this.sqliteDB.serialize(() => {
|
||||||
this.db.all('SELECT * FROM statement;', (err, rows) => {
|
this.sqliteDB.all('SELECT * FROM statement;', (err, rows) => {
|
||||||
if (err) reject(err)
|
if (err) reject(err)
|
||||||
resolve([...rows])
|
resolve([...rows])
|
||||||
})
|
})
|
||||||
|
@ -33,10 +33,10 @@ export default class Database {
|
||||||
params: any[],
|
params: any[],
|
||||||
callBack: (err: Error | null) => void
|
callBack: (err: Error | null) => void
|
||||||
) {
|
) {
|
||||||
this.db.run(sql, params, callBack)
|
this.sqliteDB.run(sql, params, callBack)
|
||||||
}
|
}
|
||||||
|
|
||||||
public close() {
|
public close() {
|
||||||
this.db.close()
|
this.sqliteDB.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/noPerm.ts
Normal file
13
src/noPerm.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { type Message } from 'discord.js'
|
||||||
|
|
||||||
|
export default async function noPerm(msg: Message) {
|
||||||
|
await msg.reply({
|
||||||
|
content: '당신은 내 남자친구가 아니야!',
|
||||||
|
allowedMentions: {
|
||||||
|
repliedUser: false,
|
||||||
|
parse: [],
|
||||||
|
users: [],
|
||||||
|
roles: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
|
@ -15,28 +15,32 @@ describe('Test Database', () => {
|
||||||
|
|
||||||
test('Get rows', () => {
|
test('Get rows', () => {
|
||||||
getData().then(async rows =>
|
getData().then(async rows =>
|
||||||
expect(await new Database(DBPATH).get()).toEqual(rows)
|
expect(await new Database(DBPATH).all()).toEqual(rows)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Insert row', () => {
|
test('Insert row', () => {
|
||||||
const db = new Database(DBPATH)
|
const db = new Database(DBPATH)
|
||||||
return db.get().then(async data1 => {
|
return db.all().then(async data1 => {
|
||||||
db.run('INSERT INTO statement(text) VALUES(?)', ['TEST'], err => {
|
db.run(
|
||||||
if (err) throw err
|
'INSERT INTO statement(id, text) VALUES(?, ?)',
|
||||||
})
|
[++data1[data1.length - 1].id, 'TEST'],
|
||||||
const data2 = await db.get()
|
err => {
|
||||||
|
if (err) throw err
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const data2 = await db.all()
|
||||||
expect(data1[data1.length - 1]).not.toEqual(data2[data2.length - 1])
|
expect(data1[data1.length - 1]).not.toEqual(data2[data2.length - 1])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Delete row', () => {
|
test('Delete row', () => {
|
||||||
const db = new Database(DBPATH)
|
const db = new Database(DBPATH)
|
||||||
return db.get().then(async data1 => {
|
return db.all().then(async data1 => {
|
||||||
db.run('DELETE FROM statement WHERE text=?;', ['TEST'], err => {
|
db.run('DELETE FROM statement WHERE text=?;', ['TEST'], err => {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
})
|
})
|
||||||
const data2 = await db.get()
|
const data2 = await db.all()
|
||||||
expect(data1[data1.length - 1]).not.toEqual(data2[data2.length - 1])
|
expect(data1[data1.length - 1]).not.toEqual(data2[data2.length - 1])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue