diff --git a/.eslintrc.json b/.eslintrc.json index a7e220d..97ed3a7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -22,6 +22,7 @@ ], "rules": { "@typescript-eslint/class-name-casing": "off", - "@typescript-eslint/interface-name-prefix": "off" + "@typescript-eslint/interface-name-prefix": "off", + "space-before-function-paren": "error" } } \ No newline at end of file diff --git a/src/Handlers/LeaveChatHandler.ts b/src/Handlers/LeaveChatHandler.ts index 8599b9e..1381c11 100644 --- a/src/Handlers/LeaveChatHandler.ts +++ b/src/Handlers/LeaveChatHandler.ts @@ -1,5 +1,5 @@ import { PrivmsgMessage } from '@kararty/dank-twitch-irc' -import { LEAVECHAT, MessageType } from 'befriendlier-shared' +import { LEAVECHAT, MessageType, NameAndId } from 'befriendlier-shared' import DefaultHandler from './DefaultHandler' export default class LeaveChannelHandler extends DefaultHandler { @@ -9,7 +9,6 @@ export default class LeaveChannelHandler extends DefaultHandler { public adminOnly = true public async onCommand (msg: PrivmsgMessage, words: string[]): Promise { - // When the bot gets banned, the userTwitch's variables are empty. const responseMessage = this.getNameAndIds(msg) as LEAVECHAT // if (words[0] === undefined) { @@ -18,8 +17,8 @@ export default class LeaveChannelHandler extends DefaultHandler { // return // } - // // Letters, numbers, underscore. - // words[0] = encodeURIComponent(words[0].replace(/[^\w]/g, '')) + // Letters, numbers, underscore. + words[0] = encodeURIComponent(words[0].replace(/[^\w]/g, '')) // Get user details for provided user. const res = await this.twitch.api.getUser(this.twitch.token.superSecret, [words[0]]) @@ -37,16 +36,28 @@ export default class LeaveChannelHandler extends DefaultHandler { this.ws.sendMessage(this.messageType, JSON.stringify(responseMessage)) } - public async onServerResponse ({ channelTwitch, userTwitch, leaveUserTwitch }: LEAVECHAT): Promise { - // When the bot gets banned, it doesn't need to announce that it's leaving, so userTwitch's variables are empty. - if (userTwitch.name.length > 0 && userTwitch.id.length > 0) { - void this.twitch.sendMessage( - leaveUserTwitch, - userTwitch, - `from channel @${channelTwitch.name}, has issued me to leave this channel. FeelsBadMan Good bye!` - ) + public async onBanned ({ id, name }: NameAndId): Promise { + const responseMessage = { + userTwitch: { name: '', id: '' }, + leaveUserTwitch: { + name, + id + } } + this.ws.sendMessage(this.messageType, JSON.stringify(responseMessage)) + } + + public async onServerResponse ({ /* channelTwitch, userTwitch, */ leaveUserTwitch }: LEAVECHAT): Promise { + // When the bot gets banned, it doesn't need to announce that it's leaving, so userTwitch's variables are empty. + // if (userTwitch.name.length > 0 && userTwitch.id.length > 0) { + // void this.twitch.sendMessage( + // leaveUserTwitch, + // userTwitch, + // `from channel @${channelTwitch.name}, has issued me to leave this channel. FeelsBadMan Good bye!` + // ) + // } + this.twitch.leaveChannel(leaveUserTwitch) } } diff --git a/src/Twitch.ts b/src/Twitch.ts index 3ba7c64..6c1f4e8 100644 --- a/src/Twitch.ts +++ b/src/Twitch.ts @@ -4,6 +4,7 @@ import { ChatClient, ClearchatMessage, ClearmsgMessage, + NoticeMessage, PrivmsgMessage, PrivmsgMessageRateLimiter, SlowModeRateLimiter, @@ -13,6 +14,7 @@ import { BASE, Emote, MessageType, More, NameAndId, PajbotAPI, TwitchAuth } from import PQueue from 'p-queue' import TwitchConfig from '../config/Twitch' import DefaultHandler from './Handlers/DefaultHandler' +import LeaveChannelHandler from './Handlers/LeaveChatHandler' import Ws, { WsRes } from './Ws' interface Token { @@ -234,6 +236,8 @@ export default class Client { this.ircClient.on('CLEARCHAT', (msg) => this.deleteMessage(msg)) this.ircClient.on('CLEARMSG', (msg) => this.deleteMessage(msg)) + this.ircClient.on('NOTICE', (msg) => void this.noticeMsg(msg)) + // Finally, connect to Twitch IRC. return await this.ircClient.connect() } @@ -323,7 +327,7 @@ export default class Client { return } - const words = m.msg.messageText.substring(this.commandPrefix.length).split(' ') + const words = m.msg.messageText.substring(this.commandPrefix.length).split(/ +/gm) const foundCommand = this.handlers.filter(command => command.prefix.length !== 0) .find(command => command.prefix.includes(words[0].toLowerCase())) @@ -434,6 +438,23 @@ export default class Client { } else return false } + public async noticeMsg (msg: NoticeMessage): Promise { + let { name, id } = + [...this.channels].find(([_id, channel]) => channel.name === msg.channelName)?.[1] as Channel + + // Might not always exist in cache, like when we initially join. + name = name ?? msg.channelName + + switch (msg.messageID) { + case 'msg_banned': + case 'tos_banned': + case 'msg_channel_banned': + // Unhost channel. + void (this.handlers.find(command => command.messageType === MessageType.LEAVECHAT) as LeaveChannelHandler).onBanned({ name, id }) + break + } + } + private onServerResponse (res: WsRes): void { const command = this.handlers.find(command => command.messageType === res.type) @@ -467,26 +488,19 @@ export default class Client { private deleteMessage (msg: ClearchatMessage | ClearmsgMessage): void { if (msg instanceof ClearchatMessage) { if (typeof msg.targetUsername === 'string' && msg.targetUsername === this.name) { - const channelFound = + let { name, id } = [...this.channels].find(([_id, channel]) => channel.name === msg.channelName)?.[1] as Channel + name = name ?? msg.channelName + if (msg.banDuration === undefined) { - // We've been banned, leave chat. - // When the bot gets banned, the senderUsername & senderUserID variables must be empty. - const leaveChat = { - senderUsername: '', // These will make userTwitch's variables empty strings. - senderUserID: '', // =/= Same as above. - channelName: msg.channelName, - channelID: channelFound.id - } - - void this.handlers - .find(command => command.messageType === MessageType.LEAVECHAT)?.onCommand(leaveChat as PrivmsgMessage) + void (this.handlers + .find(command => command.messageType === MessageType.LEAVECHAT) as LeaveChannelHandler).onBanned({ name, id }) return } - this.channels.get(channelFound.id)?.cooldown.setTime(Date.now() + msg.banDuration) + this.channels.get(id)?.cooldown.setTime(Date.now() + msg.banDuration) return } }