feat(commands): add CommandCategory and fix messageUpdate
This commit is contained in:
parent
b748086ae7
commit
a7336c19e3
28 changed files with 1097 additions and 655 deletions
|
@ -6,10 +6,12 @@ export const channelPinsUpdate: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
d: ChannelPinsUpdatePayload
|
d: ChannelPinsUpdatePayload
|
||||||
) => {
|
) => {
|
||||||
const after: TextChannel | undefined = await gateway.client.channels.get<TextChannel>(d.channel_id)
|
const after:
|
||||||
|
| TextChannel
|
||||||
|
| undefined = await gateway.client.channels.get<TextChannel>(d.channel_id)
|
||||||
if (after !== undefined) {
|
if (after !== undefined) {
|
||||||
const before = after.refreshFromData({
|
const before = after.refreshFromData({
|
||||||
last_pin_timestamp: d.last_pin_timestamp
|
last_pin_timestamp: d.last_pin_timestamp,
|
||||||
})
|
})
|
||||||
const raw = await gateway.client.channels._get(d.channel_id)
|
const raw = await gateway.client.channels._get(d.channel_id)
|
||||||
await gateway.client.channels.set(
|
await gateway.client.channels.set(
|
||||||
|
|
|
@ -8,7 +8,9 @@ export const guildBanAdd: GatewayEventHandler = async (
|
||||||
d: GuildBanAddPayload
|
d: GuildBanAddPayload
|
||||||
) => {
|
) => {
|
||||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||||
const user: User = await gateway.client.users.get(d.user.id) ?? new User(gateway.client, d.user)
|
const user: User =
|
||||||
|
(await gateway.client.users.get(d.user.id)) ??
|
||||||
|
new User(gateway.client, d.user)
|
||||||
|
|
||||||
if (guild !== undefined) {
|
if (guild !== undefined) {
|
||||||
// We don't have to delete member, already done with guildMemberRemove event
|
// We don't have to delete member, already done with guildMemberRemove event
|
||||||
|
|
|
@ -9,7 +9,8 @@ export const guildBanRemove: GatewayEventHandler = async (
|
||||||
) => {
|
) => {
|
||||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||||
const user: User =
|
const user: User =
|
||||||
await gateway.client.users.get(d.user.id) ?? new User(gateway.client, d.user)
|
(await gateway.client.users.get(d.user.id)) ??
|
||||||
|
new User(gateway.client, d.user)
|
||||||
|
|
||||||
if (guild !== undefined) {
|
if (guild !== undefined) {
|
||||||
gateway.client.emit('guildBanRemove', guild, user)
|
gateway.client.emit('guildBanRemove', guild, user)
|
||||||
|
|
|
@ -1,64 +1,32 @@
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
import { Guild } from '../../structures/guild.ts'
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { GuildPayload } from '../../types/guild.ts'
|
import { GuildPayload } from '../../types/guild.ts'
|
||||||
import { MembersManager } from '../../managers/members.ts'
|
|
||||||
import { GuildChannelPayload } from '../../types/channel.ts'
|
import { GuildChannelPayload } from '../../types/channel.ts'
|
||||||
import { RolesManager } from '../../managers/roles.ts'
|
|
||||||
|
|
||||||
export const guildCreate: GatewayEventHandler = async (
|
export const guildCreate: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
d: GuildPayload
|
d: GuildPayload
|
||||||
) => {
|
) => {
|
||||||
let guild: Guild | undefined = await gateway.client.guilds.get(d.id)
|
const hasGuild: Guild | undefined = await gateway.client.guilds.get(d.id)
|
||||||
if (guild !== undefined) {
|
await gateway.client.guilds.set(d.id, d)
|
||||||
// It was just lazy load, so we don't fire the event as its gonna fire for every guild bot is in
|
const guild = ((await gateway.client.guilds.get(d.id)) as unknown) as Guild
|
||||||
await gateway.client.guilds.set(d.id, d)
|
|
||||||
|
|
||||||
if (d.members !== undefined) {
|
if (d.members !== undefined) await guild.members.fromPayload(d.members)
|
||||||
const members = new MembersManager(gateway.client, guild)
|
|
||||||
await members.fromPayload(d.members)
|
if (d.channels !== undefined) {
|
||||||
guild.members = members
|
for (const ch of d.channels as GuildChannelPayload[]) {
|
||||||
|
ch.guild_id = d.id
|
||||||
|
await gateway.client.channels.set(ch.id, ch)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (d.channels !== undefined) {
|
await guild.roles.fromPayload(d.roles)
|
||||||
for (const ch of d.channels as GuildChannelPayload[]) {
|
|
||||||
ch.guild_id = d.id
|
|
||||||
await gateway.client.channels.set(ch.id, ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d.roles !== undefined) {
|
if (d.voice_states !== undefined)
|
||||||
const roles = new RolesManager(gateway.client, guild)
|
await guild.voiceStates.fromPayload(d.voice_states)
|
||||||
await roles.fromPayload(d.roles)
|
|
||||||
guild.roles = roles
|
|
||||||
}
|
|
||||||
|
|
||||||
guild.refreshFromData(d)
|
if (hasGuild === undefined) {
|
||||||
} else {
|
// It wasn't lazy load, so emit event
|
||||||
await gateway.client.guilds.set(d.id, d)
|
|
||||||
guild = new Guild(gateway.client, d)
|
|
||||||
|
|
||||||
if (d.members !== undefined) {
|
|
||||||
const members = new MembersManager(gateway.client, guild)
|
|
||||||
await members.fromPayload(d.members)
|
|
||||||
guild.members = members
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d.channels !== undefined) {
|
|
||||||
for (const ch of d.channels as GuildChannelPayload[]) {
|
|
||||||
ch.guild_id = d.id
|
|
||||||
await gateway.client.channels.set(ch.id, ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d.roles !== undefined) {
|
|
||||||
const roles = new RolesManager(gateway.client, guild)
|
|
||||||
await roles.fromPayload(d.roles)
|
|
||||||
guild.roles = roles
|
|
||||||
}
|
|
||||||
|
|
||||||
await guild.roles.fromPayload(d.roles)
|
|
||||||
guild = new Guild(gateway.client, d)
|
|
||||||
gateway.client.emit('guildCreate', guild)
|
gateway.client.emit('guildCreate', guild)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Emoji } from "../../structures/emoji.ts"
|
import { Emoji } from '../../structures/emoji.ts'
|
||||||
import { Guild } from '../../structures/guild.ts'
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { EmojiPayload } from "../../types/emoji.ts"
|
import { EmojiPayload } from '../../types/emoji.ts'
|
||||||
import { GuildEmojiUpdatePayload } from '../../types/gateway.ts'
|
import { GuildEmojiUpdatePayload } from '../../types/gateway.ts'
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
|
@ -13,27 +13,27 @@ export const guildEmojiUpdate: GatewayEventHandler = async (
|
||||||
const emojis = await guild.emojis.collection()
|
const emojis = await guild.emojis.collection()
|
||||||
const deleted: Emoji[] = []
|
const deleted: Emoji[] = []
|
||||||
const added: Emoji[] = []
|
const added: Emoji[] = []
|
||||||
const updated: Array<{ before: Emoji, after: Emoji }> = []
|
const updated: Array<{ before: Emoji; after: Emoji }> = []
|
||||||
const _updated: EmojiPayload[] = []
|
const _updated: EmojiPayload[] = []
|
||||||
|
|
||||||
for (const raw of d.emojis) {
|
for (const raw of d.emojis) {
|
||||||
const has = emojis.get(raw.id)
|
const has = emojis.get(raw.id)
|
||||||
if (has === undefined) {
|
if (has === undefined) {
|
||||||
await guild.emojis.set(raw.id, raw)
|
await guild.emojis.set(raw.id, raw)
|
||||||
const emoji = await guild.emojis.get(raw.id) as Emoji
|
const emoji = (await guild.emojis.get(raw.id)) as Emoji
|
||||||
added.push(emoji)
|
added.push(emoji)
|
||||||
} else _updated.push(raw)
|
} else _updated.push(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const emoji of emojis.values()) {
|
for (const emoji of emojis.values()) {
|
||||||
const find = _updated.find(e => emoji.id === e.id)
|
const find = _updated.find((e) => emoji.id === e.id)
|
||||||
if (find === undefined) {
|
if (find === undefined) {
|
||||||
await guild.emojis.delete(emoji.id)
|
await guild.emojis.delete(emoji.id)
|
||||||
deleted.push(emoji)
|
deleted.push(emoji)
|
||||||
} else {
|
} else {
|
||||||
const before = await guild.emojis.get(find.id) as Emoji
|
const before = (await guild.emojis.get(find.id)) as Emoji
|
||||||
await guild.emojis.set(find.id, find)
|
await guild.emojis.set(find.id, find)
|
||||||
const after = await guild.emojis.get(find.id) as Emoji
|
const after = (await guild.emojis.get(find.id)) as Emoji
|
||||||
updated.push({ before, after })
|
updated.push({ before, after })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
import { Guild } from '../../structures/guild.ts'
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { GuildIntegrationsUpdatePayload } from "../../types/gateway.ts"
|
import { GuildIntegrationsUpdatePayload } from '../../types/gateway.ts'
|
||||||
|
|
||||||
export const guildIntegrationsUpdate: GatewayEventHandler = async (
|
export const guildIntegrationsUpdate: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
import { Guild } from '../../structures/guild.ts'
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { GuildMemberAddPayload } from "../../types/gateway.ts"
|
import { GuildMemberAddPayload } from '../../types/gateway.ts'
|
||||||
import { Member } from "../../structures/member.ts"
|
import { Member } from '../../structures/member.ts'
|
||||||
|
|
||||||
export const guildMemberAdd: GatewayEventHandler = async (
|
export const guildMemberAdd: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
|
@ -12,6 +12,6 @@ export const guildMemberAdd: GatewayEventHandler = async (
|
||||||
if (guild === undefined) return
|
if (guild === undefined) return
|
||||||
|
|
||||||
await guild.members.set(d.user.id, d)
|
await guild.members.set(d.user.id, d)
|
||||||
const member = await guild.members.get(d.user.id) as Member
|
const member = (await guild.members.get(d.user.id)) as Member
|
||||||
gateway.client.emit('guildMemberAdd', member)
|
gateway.client.emit('guildMemberAdd', member)
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ export const guildMemberUpdate: GatewayEventHandler = async (
|
||||||
nick: d.nick,
|
nick: d.nick,
|
||||||
premium_since: d.premium_since,
|
premium_since: d.premium_since,
|
||||||
deaf: member?.deaf ?? false,
|
deaf: member?.deaf ?? false,
|
||||||
mute: member?.mute ?? false
|
mute: member?.mute ?? false,
|
||||||
}
|
}
|
||||||
await guild.members.set(d.user.id, newMemberPayload)
|
await guild.members.set(d.user.id, newMemberPayload)
|
||||||
const newMember = await guild.members.get(d.user.id)
|
const newMember = await guild.members.get(d.user.id)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
import { Guild } from '../../structures/guild.ts'
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { GuildRoleDeletePayload } from "../../types/gateway.ts"
|
import { GuildRoleDeletePayload } from '../../types/gateway.ts'
|
||||||
|
|
||||||
export const guildRoleDelete: GatewayEventHandler = async (
|
export const guildRoleDelete: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
|
@ -12,7 +12,7 @@ export const guildRoleDelete: GatewayEventHandler = async (
|
||||||
|
|
||||||
const role = await guild.roles.get(d.role_id)
|
const role = await guild.roles.get(d.role_id)
|
||||||
// Shouldn't happen either
|
// Shouldn't happen either
|
||||||
if(role === undefined) return
|
if (role === undefined) return
|
||||||
|
|
||||||
gateway.client.emit('guildRoleDelete', role)
|
gateway.client.emit('guildRoleDelete', role)
|
||||||
}
|
}
|
|
@ -13,32 +13,32 @@ import { guildBanRemove } from './guildBanRemove.ts'
|
||||||
import { messageCreate } from './messageCreate.ts'
|
import { messageCreate } from './messageCreate.ts'
|
||||||
import { resume } from './resume.ts'
|
import { resume } from './resume.ts'
|
||||||
import { reconnect } from './reconnect.ts'
|
import { reconnect } from './reconnect.ts'
|
||||||
import { messageDelete } from "./messageDelete.ts"
|
import { messageDelete } from './messageDelete.ts'
|
||||||
import { messageUpdate } from "./messageUpdate.ts"
|
import { messageUpdate } from './messageUpdate.ts'
|
||||||
import { guildEmojiUpdate } from "./guildEmojiUpdate.ts"
|
import { guildEmojiUpdate } from './guildEmojiUpdate.ts'
|
||||||
import { guildMemberAdd } from "./guildMemberAdd.ts"
|
import { guildMemberAdd } from './guildMemberAdd.ts'
|
||||||
import { guildMemberRemove } from "./guildMemberRemove.ts"
|
import { guildMemberRemove } from './guildMemberRemove.ts'
|
||||||
import { guildMemberUpdate } from "./guildMemberUpdate.ts"
|
import { guildMemberUpdate } from './guildMemberUpdate.ts'
|
||||||
import { guildRoleCreate } from "./guildRoleCreate.ts"
|
import { guildRoleCreate } from './guildRoleCreate.ts'
|
||||||
import { guildRoleDelete } from "./guildRoleDelete.ts"
|
import { guildRoleDelete } from './guildRoleDelete.ts'
|
||||||
import { guildRoleUpdate } from "./guildRoleUpdate.ts"
|
import { guildRoleUpdate } from './guildRoleUpdate.ts'
|
||||||
import { guildIntegrationsUpdate } from "./guildIntegrationsUpdate.ts"
|
import { guildIntegrationsUpdate } from './guildIntegrationsUpdate.ts'
|
||||||
import { webhooksUpdate } from "./webhooksUpdate.ts"
|
import { webhooksUpdate } from './webhooksUpdate.ts'
|
||||||
import { messageDeleteBulk } from "./messageDeleteBulk.ts"
|
import { messageDeleteBulk } from './messageDeleteBulk.ts'
|
||||||
import { userUpdate } from "./userUpdate.ts"
|
import { userUpdate } from './userUpdate.ts'
|
||||||
import { typingStart } from "./typingStart.ts"
|
import { typingStart } from './typingStart.ts'
|
||||||
import { Channel } from "../../structures/channel.ts"
|
import { Channel } from '../../structures/channel.ts'
|
||||||
import { GuildTextChannel, TextChannel } from "../../structures/textChannel.ts"
|
import { GuildTextChannel, TextChannel } from '../../structures/textChannel.ts'
|
||||||
import { Guild } from "../../structures/guild.ts"
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { User } from "../../structures/user.ts"
|
import { User } from '../../structures/user.ts'
|
||||||
import { Emoji } from "../../structures/emoji.ts"
|
import { Emoji } from '../../structures/emoji.ts'
|
||||||
import { Member } from "../../structures/member.ts"
|
import { Member } from '../../structures/member.ts'
|
||||||
import { Role } from "../../structures/role.ts"
|
import { Role } from '../../structures/role.ts'
|
||||||
import { Message } from "../../structures/message.ts"
|
import { Message } from '../../structures/message.ts'
|
||||||
import { Collection } from "../../utils/collection.ts"
|
import { Collection } from '../../utils/collection.ts'
|
||||||
import { voiceServerUpdate } from "./voiceServerUpdate.ts"
|
import { voiceServerUpdate } from './voiceServerUpdate.ts'
|
||||||
import { voiceStateUpdate } from "./voiceStateUpdate.ts"
|
import { voiceStateUpdate } from './voiceStateUpdate.ts'
|
||||||
import { VoiceState } from "../../structures/voiceState.ts"
|
import { VoiceState } from '../../structures/voiceState.ts'
|
||||||
|
|
||||||
export const gatewayHandlers: {
|
export const gatewayHandlers: {
|
||||||
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
||||||
|
@ -79,7 +79,7 @@ export const gatewayHandlers: {
|
||||||
USER_UPDATE: userUpdate,
|
USER_UPDATE: userUpdate,
|
||||||
VOICE_STATE_UPDATE: voiceStateUpdate,
|
VOICE_STATE_UPDATE: voiceStateUpdate,
|
||||||
VOICE_SERVER_UPDATE: voiceServerUpdate,
|
VOICE_SERVER_UPDATE: voiceServerUpdate,
|
||||||
WEBHOOKS_UPDATE: webhooksUpdate
|
WEBHOOKS_UPDATE: webhooksUpdate,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EventTypes {
|
export interface EventTypes {
|
||||||
|
@ -93,37 +93,46 @@ export interface VoiceServerUpdateData {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClientEvents extends EventTypes {
|
export interface ClientEvents extends EventTypes {
|
||||||
'ready': () => void
|
ready: () => void
|
||||||
'reconnect': () => void
|
reconnect: () => void
|
||||||
'resumed': () => void
|
resumed: () => void
|
||||||
'channelCreate': (channel: Channel) => void
|
channelCreate: (channel: Channel) => void
|
||||||
'channelDelete': (channel: Channel) => void
|
channelDelete: (channel: Channel) => void
|
||||||
'channelPinsUpdate': (before: TextChannel, after: TextChannel) => void
|
channelPinsUpdate: (before: TextChannel, after: TextChannel) => void
|
||||||
'channelUpdate': (before: Channel, after: Channel) => void
|
channelUpdate: (before: Channel, after: Channel) => void
|
||||||
'guildBanAdd': (guild: Guild, user: User) => void
|
guildBanAdd: (guild: Guild, user: User) => void
|
||||||
'guildBanRemove': (guild: Guild, user: User) => void
|
guildBanRemove: (guild: Guild, user: User) => void
|
||||||
'guildCreate': (guild: Guild) => void
|
guildCreate: (guild: Guild) => void
|
||||||
'guildDelete': (guild: Guild) => void
|
guildDelete: (guild: Guild) => void
|
||||||
'guildEmojiAdd': (guild: Guild, emoji: Emoji) => void
|
guildEmojiAdd: (guild: Guild, emoji: Emoji) => void
|
||||||
'guildEmojiDelete': (guild: Guild, emoji: Emoji) => void
|
guildEmojiDelete: (guild: Guild, emoji: Emoji) => void
|
||||||
'guildEmojiUpdate': (guild: Guild, before: Emoji, after: Emoji) => void
|
guildEmojiUpdate: (guild: Guild, before: Emoji, after: Emoji) => void
|
||||||
'guildIntegrationsUpdate': (guild: Guild) => void
|
guildIntegrationsUpdate: (guild: Guild) => void
|
||||||
'guildMemberAdd': (member: Member) => void
|
guildMemberAdd: (member: Member) => void
|
||||||
'guildMemberRemove': (member: Member) => void
|
guildMemberRemove: (member: Member) => void
|
||||||
'guildMemberUpdate': (before: Member, after: Member) => void
|
guildMemberUpdate: (before: Member, after: Member) => void
|
||||||
'guildRoleCreate': (role: Role) => void
|
guildRoleCreate: (role: Role) => void
|
||||||
'guildRoleDelete': (role: Role) => void
|
guildRoleDelete: (role: Role) => void
|
||||||
'guildRoleUpdate': (before: Role, after: Role) => void
|
guildRoleUpdate: (before: Role, after: Role) => void
|
||||||
'guildUpdate': (before: Guild, after: Guild) => void
|
guildUpdate: (before: Guild, after: Guild) => void
|
||||||
'messageCreate': (message: Message) => void
|
messageCreate: (message: Message) => void
|
||||||
'messageDelete': (message: Message) => void
|
messageDelete: (message: Message) => void
|
||||||
'messageDeleteBulk': (channel: GuildTextChannel, messages: Collection<string, Message>, uncached: Set<string>) => void
|
messageDeleteBulk: (
|
||||||
'messageUpdate': (before: Message, after: Message) => void
|
channel: GuildTextChannel,
|
||||||
'typingStart': (user: User, channel: TextChannel, at: Date, guildData?: TypingStartGuildData) => void
|
messages: Collection<string, Message>,
|
||||||
'userUpdate': (before: User, after: User) => void
|
uncached: Set<string>
|
||||||
'voiceServerUpdate': (data: VoiceServerUpdateData) => void
|
) => void
|
||||||
'voiceStateAdd': (state: VoiceState) => void
|
messageUpdate: (before: Message, after: Message) => void
|
||||||
'voiceStateRemove': (state: VoiceState) => void
|
typingStart: (
|
||||||
'voiceStateUpdate': (state: VoiceState, after: VoiceState) => void
|
user: User,
|
||||||
'webhooksUpdate': (guild: Guild, channel: GuildTextChannel) => void
|
channel: TextChannel,
|
||||||
|
at: Date,
|
||||||
|
guildData?: TypingStartGuildData
|
||||||
|
) => void
|
||||||
|
userUpdate: (before: User, after: User) => void
|
||||||
|
voiceServerUpdate: (data: VoiceServerUpdateData) => void
|
||||||
|
voiceStateAdd: (state: VoiceState) => void
|
||||||
|
voiceStateRemove: (state: VoiceState) => void
|
||||||
|
voiceStateUpdate: (state: VoiceState, after: VoiceState) => void
|
||||||
|
webhooksUpdate: (guild: Guild, channel: GuildTextChannel) => void
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import { TextChannel } from '../../structures/textChannel.ts'
|
import { TextChannel } from '../../structures/textChannel.ts'
|
||||||
import { MessageDeletePayload } from "../../types/gateway.ts"
|
import { MessageDeletePayload } from '../../types/gateway.ts'
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
export const messageDelete: GatewayEventHandler = async (
|
export const messageDelete: GatewayEventHandler = async (
|
||||||
|
@ -13,7 +13,8 @@ export const messageDelete: GatewayEventHandler = async (
|
||||||
channel = (await gateway.client.channels.fetch(d.channel_id)) as TextChannel
|
channel = (await gateway.client.channels.fetch(d.channel_id)) as TextChannel
|
||||||
|
|
||||||
const message = await channel.messages.get(d.id)
|
const message = await channel.messages.get(d.id)
|
||||||
if (message === undefined) return gateway.client.emit('messageDeleteUncached', d)
|
if (message === undefined)
|
||||||
|
return gateway.client.emit('messageDeleteUncached', d)
|
||||||
await channel.messages.delete(d.id)
|
await channel.messages.delete(d.id)
|
||||||
gateway.client.emit('messageDelete', message)
|
gateway.client.emit('messageDelete', message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
import { Message } from "../../structures/message.ts"
|
import { Message } from '../../structures/message.ts'
|
||||||
import { GuildTextChannel } from '../../structures/textChannel.ts'
|
import { GuildTextChannel } from '../../structures/textChannel.ts'
|
||||||
import { MessageDeleteBulkPayload } from "../../types/gateway.ts"
|
import { MessageDeleteBulkPayload } from '../../types/gateway.ts'
|
||||||
import { Collection } from "../../utils/collection.ts"
|
import { Collection } from '../../utils/collection.ts'
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
export const messageDeleteBulk: GatewayEventHandler = async (
|
export const messageDeleteBulk: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
d: MessageDeleteBulkPayload
|
d: MessageDeleteBulkPayload
|
||||||
) => {
|
) => {
|
||||||
let channel = await gateway.client.channels.get<GuildTextChannel>(d.channel_id)
|
let channel = await gateway.client.channels.get<GuildTextChannel>(
|
||||||
|
d.channel_id
|
||||||
|
)
|
||||||
// Fetch the channel if not cached
|
// Fetch the channel if not cached
|
||||||
if (channel === undefined)
|
if (channel === undefined)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
channel = (await gateway.client.channels.fetch(d.channel_id)) as GuildTextChannel
|
channel = (await gateway.client.channels.fetch(
|
||||||
|
d.channel_id
|
||||||
|
)) as GuildTextChannel
|
||||||
|
|
||||||
const messages = new Collection<string, Message>()
|
const messages = new Collection<string, Message>()
|
||||||
const uncached = new Set<string>()
|
const uncached = new Set<string>()
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Message } from '../../structures/message.ts'
|
import { Message } from '../../structures/message.ts'
|
||||||
import { TextChannel } from '../../structures/textChannel.ts'
|
import { TextChannel } from '../../structures/textChannel.ts'
|
||||||
import { User } from '../../structures/user.ts'
|
|
||||||
import { MessagePayload } from '../../types/channel.ts'
|
import { MessagePayload } from '../../types/channel.ts'
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
|
@ -11,19 +10,19 @@ export const messageUpdate: GatewayEventHandler = async (
|
||||||
let channel = await gateway.client.channels.get<TextChannel>(d.channel_id)
|
let channel = await gateway.client.channels.get<TextChannel>(d.channel_id)
|
||||||
// Fetch the channel if not cached
|
// Fetch the channel if not cached
|
||||||
if (channel === undefined)
|
if (channel === undefined)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
channel = await gateway.client.channels.fetch(d.channel_id)
|
||||||
channel = (await gateway.client.channels.fetch(d.channel_id)) as TextChannel
|
|
||||||
|
if (channel === undefined) return
|
||||||
|
|
||||||
const message = await channel.messages.get(d.id)
|
const message = await channel.messages.get(d.id)
|
||||||
const author =
|
if (message === undefined) return
|
||||||
message?.author !== undefined
|
const raw = await channel.messages._get(d.id)
|
||||||
? message.author
|
if (raw === undefined) return
|
||||||
: new User(gateway.client, d.author)
|
|
||||||
const newMsg = new Message(gateway.client, d, channel, author)
|
const newRaw = raw
|
||||||
if (message === undefined) {
|
Object.assign(newRaw, d)
|
||||||
await channel.messages.set(d.id, d)
|
await channel.messages.set(d.id, newRaw)
|
||||||
return gateway.client.emit('messageUpdateUncached', newMsg)
|
|
||||||
}
|
const newMsg = ((await channel.messages.get(d.id)) as unknown) as Message
|
||||||
await channel.messages.set(d.id, d)
|
|
||||||
gateway.client.emit('messageUpdate', message, newMsg)
|
gateway.client.emit('messageUpdate', message, newMsg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import { User } from '../../structures/user.ts'
|
import { User } from '../../structures/user.ts'
|
||||||
import { Ready } from "../../types/gateway.ts"
|
import { Ready } from '../../types/gateway.ts'
|
||||||
import { GuildPayload } from '../../types/guild.ts'
|
import { GuildPayload } from '../../types/guild.ts'
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
export const ready: GatewayEventHandler = async (gateway: Gateway, d: Ready) => {
|
export const ready: GatewayEventHandler = async (
|
||||||
|
gateway: Gateway,
|
||||||
|
d: Ready
|
||||||
|
) => {
|
||||||
await gateway.client.guilds.flush()
|
await gateway.client.guilds.flush()
|
||||||
|
|
||||||
gateway.client.user = new User(gateway.client, d.user)
|
gateway.client.user = new User(gateway.client, d.user)
|
||||||
gateway.sessionID = d.session_id
|
gateway.sessionID = d.session_id
|
||||||
gateway.debug(`Received READY. Session: ${gateway.sessionID}`)
|
gateway.debug(`Received READY. Session: ${gateway.sessionID}`)
|
||||||
await gateway.cache.set("session_id", gateway.sessionID)
|
await gateway.cache.set('session_id', gateway.sessionID)
|
||||||
|
|
||||||
d.guilds.forEach((guild: GuildPayload) => {
|
d.guilds.forEach((guild: GuildPayload) => {
|
||||||
gateway.client.guilds.set(guild.id, guild)
|
gateway.client.guilds.set(guild.id, guild)
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { Gateway , GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
export const reconnect: GatewayEventHandler = async (gateway: Gateway, d: any) => {
|
export const reconnect: GatewayEventHandler = async (
|
||||||
gateway.reconnect()
|
gateway: Gateway,
|
||||||
|
d: any
|
||||||
|
) => {
|
||||||
|
gateway.reconnect()
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import { Guild } from "../../structures/guild.ts"
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { VoiceServerUpdatePayload } from "../../types/gateway.ts"
|
import { VoiceServerUpdatePayload } from '../../types/gateway.ts'
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
export const voiceServerUpdate: GatewayEventHandler = async (
|
export const voiceServerUpdate: GatewayEventHandler = async (
|
||||||
|
@ -9,6 +9,6 @@ export const voiceServerUpdate: GatewayEventHandler = async (
|
||||||
gateway.client.emit('voiceServerUpdate', {
|
gateway.client.emit('voiceServerUpdate', {
|
||||||
token: d.token,
|
token: d.token,
|
||||||
endpoint: d.endpoint,
|
endpoint: d.endpoint,
|
||||||
guild: (await gateway.client.guilds.get(d.guild_id) as unknown) as Guild
|
guild: ((await gateway.client.guilds.get(d.guild_id)) as unknown) as Guild,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Guild } from "../../structures/guild.ts"
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { VoiceState } from "../../structures/voiceState.ts"
|
import { VoiceState } from '../../structures/voiceState.ts'
|
||||||
import { VoiceStatePayload } from "../../types/voice.ts"
|
import { MemberPayload } from '../../types/guild.ts'
|
||||||
|
import { VoiceStatePayload } from '../../types/voice.ts'
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
export const voiceStateUpdate: GatewayEventHandler = async (
|
export const voiceStateUpdate: GatewayEventHandler = async (
|
||||||
|
@ -9,22 +10,41 @@ export const voiceStateUpdate: GatewayEventHandler = async (
|
||||||
) => {
|
) => {
|
||||||
// TODO(DjDeveloperr): Support self-bot here; they can be in DMs (Call)
|
// TODO(DjDeveloperr): Support self-bot here; they can be in DMs (Call)
|
||||||
if (d.guild_id === undefined) return
|
if (d.guild_id === undefined) return
|
||||||
const guild = (await gateway.client.guilds.get(d.guild_id) as unknown) as Guild
|
const guild = ((await gateway.client.guilds.get(
|
||||||
|
d.guild_id
|
||||||
|
)) as unknown) as Guild
|
||||||
|
|
||||||
const voiceState = await guild.voiceStates.get(d.user_id)
|
const voiceState = await guild.voiceStates.get(d.user_id)
|
||||||
|
|
||||||
if (d.channel_id === null) {
|
if (d.channel_id === null) {
|
||||||
|
if (voiceState === undefined) {
|
||||||
|
await guild.members.set(d.user_id, (d.member as unknown) as MemberPayload)
|
||||||
|
const member = ((await guild.members.get(
|
||||||
|
d.user_id
|
||||||
|
)) as unknown) as MemberPayload
|
||||||
|
return gateway.client.emit('voiceStateRemoveUncached', { guild, member })
|
||||||
|
}
|
||||||
// No longer in the channel, so delete
|
// No longer in the channel, so delete
|
||||||
await guild.voiceStates.delete(d.user_id)
|
await guild.voiceStates.delete(d.user_id)
|
||||||
gateway.client.emit('voiceStateRemove', (voiceState as unknown) as VoiceState)
|
gateway.client.emit(
|
||||||
|
'voiceStateRemove',
|
||||||
|
(voiceState as unknown) as VoiceState
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await guild.voiceStates.set(d.user_id, d)
|
await guild.voiceStates.set(d.user_id, d)
|
||||||
const newVoiceState = await guild.voiceStates.get(d.user_id)
|
const newVoiceState = await guild.voiceStates.get(d.user_id)
|
||||||
if (voiceState === undefined) {
|
if (voiceState === undefined) {
|
||||||
gateway.client.emit('voiceStateAdd', (newVoiceState as unknown) as VoiceState)
|
gateway.client.emit(
|
||||||
|
'voiceStateAdd',
|
||||||
|
(newVoiceState as unknown) as VoiceState
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
gateway.client.emit('voiceStateUpdate', voiceState, (newVoiceState as unknown) as VoiceState)
|
gateway.client.emit(
|
||||||
|
'voiceStateUpdate',
|
||||||
|
voiceState,
|
||||||
|
(newVoiceState as unknown) as VoiceState
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
import { Guild } from '../../structures/guild.ts'
|
import { Guild } from '../../structures/guild.ts'
|
||||||
import { WebhooksUpdatePayload } from "../../types/gateway.ts"
|
import { WebhooksUpdatePayload } from '../../types/gateway.ts'
|
||||||
import { GuildTextChannel } from "../../structures/textChannel.ts"
|
import { GuildTextChannel } from '../../structures/textChannel.ts'
|
||||||
|
|
||||||
export const webhooksUpdate: GatewayEventHandler = async (
|
export const webhooksUpdate: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
|
@ -10,7 +10,10 @@ export const webhooksUpdate: GatewayEventHandler = async (
|
||||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||||
if (guild === undefined) return
|
if (guild === undefined) return
|
||||||
|
|
||||||
const channel: GuildTextChannel | undefined = await guild.channels.get(d.channel_id) as GuildTextChannel
|
const channel: GuildTextChannel | undefined = (await guild.channels.get(
|
||||||
if (channel === undefined) gateway.client.emit('webhooksUpdateUncached', guild, d.channel_id)
|
d.channel_id
|
||||||
|
)) as GuildTextChannel
|
||||||
|
if (channel === undefined)
|
||||||
|
gateway.client.emit('webhooksUpdateUncached', guild, d.channel_id)
|
||||||
else gateway.client.emit('webhooksUpdate', guild, channel)
|
else gateway.client.emit('webhooksUpdate', guild, channel)
|
||||||
}
|
}
|
|
@ -1,30 +1,48 @@
|
||||||
import { Client } from '../models/client.ts'
|
import { Client } from '../models/client.ts'
|
||||||
import { Guild } from "../structures/guild.ts"
|
import { Guild } from '../structures/guild.ts'
|
||||||
import { VoiceChannel } from "../structures/guildVoiceChannel.ts"
|
import { VoiceChannel } from '../structures/guildVoiceChannel.ts'
|
||||||
import { User } from "../structures/user.ts"
|
import { User } from '../structures/user.ts'
|
||||||
import { VoiceState } from "../structures/voiceState.ts"
|
import { VoiceState } from '../structures/voiceState.ts'
|
||||||
import { VoiceStatePayload } from "../types/voice.ts"
|
import { VoiceStatePayload } from '../types/voice.ts'
|
||||||
import { BaseManager } from './base.ts'
|
import { BaseManager } from './base.ts'
|
||||||
|
|
||||||
export class GuildVoiceStatesManager extends BaseManager<VoiceStatePayload, VoiceState> {
|
export class GuildVoiceStatesManager extends BaseManager<
|
||||||
|
VoiceStatePayload,
|
||||||
|
VoiceState
|
||||||
|
> {
|
||||||
guild: Guild
|
guild: Guild
|
||||||
|
|
||||||
async get (key: string): Promise<VoiceState | undefined> {
|
constructor(client: Client, guild: Guild) {
|
||||||
const raw = await this._get(key)
|
|
||||||
if (raw === undefined) return
|
|
||||||
|
|
||||||
const guild = raw.guild_id === undefined ? undefined : await this.client.guilds.get(raw.guild_id)
|
|
||||||
|
|
||||||
return new VoiceState(this.client, raw, {
|
|
||||||
user: (await this.client.users.get(raw.user_id) as unknown) as User,
|
|
||||||
channel: raw.channel_id == null ? null : (await this.client.channels.get<VoiceChannel>(raw.channel_id) as unknown) as VoiceChannel,
|
|
||||||
guild,
|
|
||||||
member: guild === undefined ? undefined : await guild.members.get(raw.user_id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor (client: Client, guild: Guild) {
|
|
||||||
super(client, `vs:${guild.id}`, VoiceState)
|
super(client, `vs:${guild.id}`, VoiceState)
|
||||||
this.guild = guild
|
this.guild = guild
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async get(key: string): Promise<VoiceState | undefined> {
|
||||||
|
const raw = await this._get(key)
|
||||||
|
if (raw === undefined) return
|
||||||
|
|
||||||
|
const guild =
|
||||||
|
raw.guild_id === undefined
|
||||||
|
? undefined
|
||||||
|
: await this.client.guilds.get(raw.guild_id)
|
||||||
|
|
||||||
|
return new VoiceState(this.client, raw, {
|
||||||
|
user: ((await this.client.users.get(raw.user_id)) as unknown) as User,
|
||||||
|
channel:
|
||||||
|
raw.channel_id == null
|
||||||
|
? null
|
||||||
|
: (((await this.client.channels.get<VoiceChannel>(
|
||||||
|
raw.channel_id
|
||||||
|
)) as unknown) as VoiceChannel),
|
||||||
|
guild,
|
||||||
|
member:
|
||||||
|
guild === undefined ? undefined : await guild.members.get(raw.user_id),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fromPayload(d: VoiceStatePayload[]): Promise<void> {
|
||||||
|
for (const data of d) {
|
||||||
|
await this.set(data.user_id, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,35 +9,46 @@ import { BaseManager } from './base.ts'
|
||||||
export class MessagesManager extends BaseManager<MessagePayload, Message> {
|
export class MessagesManager extends BaseManager<MessagePayload, Message> {
|
||||||
channel: TextChannel
|
channel: TextChannel
|
||||||
|
|
||||||
constructor (client: Client, channel: TextChannel) {
|
constructor(client: Client, channel: TextChannel) {
|
||||||
super(client, 'messages', Message)
|
super(client, 'messages', Message)
|
||||||
this.channel = channel
|
this.channel = channel
|
||||||
}
|
}
|
||||||
|
|
||||||
async get (key: string): Promise<Message | undefined> {
|
async get(key: string): Promise<Message | undefined> {
|
||||||
const raw = await this._get(key)
|
const raw = await this._get(key)
|
||||||
if (raw === undefined) return
|
if (raw === undefined) return
|
||||||
|
|
||||||
|
if (raw.author === undefined) return
|
||||||
|
|
||||||
let channel = await this.client.channels.get(raw.channel_id)
|
let channel = await this.client.channels.get(raw.channel_id)
|
||||||
if (channel === undefined)
|
if (channel === undefined)
|
||||||
channel = await this.client.channels.fetch(raw.channel_id)
|
channel = await this.client.channels.fetch(raw.channel_id)
|
||||||
|
|
||||||
const author = new User(this.client, raw.author)
|
let author = ((await this.client.users.get(
|
||||||
|
raw.author.id
|
||||||
|
)) as unknown) as User
|
||||||
|
|
||||||
|
if (author === undefined) author = new User(this.client, raw.author)
|
||||||
|
|
||||||
const res = new this.DataType(this.client, raw, channel, author) as any
|
const res = new this.DataType(this.client, raw, channel, author) as any
|
||||||
await res.mentions.fromPayload(raw)
|
await res.mentions.fromPayload(raw)
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
async set (key: string, value: MessagePayload): Promise<any> {
|
async set(key: string, value: MessagePayload): Promise<any> {
|
||||||
return this.client.cache.set(this.cacheName, key, value, this.client.messageCacheLifetime)
|
return this.client.cache.set(
|
||||||
|
this.cacheName,
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
this.client.messageCacheLifetime
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch (id: string): Promise<Message> {
|
async fetch(id: string): Promise<Message> {
|
||||||
return await new Promise((resolve, reject) => {
|
return await new Promise((resolve, reject) => {
|
||||||
this.client.rest
|
this.client.rest
|
||||||
.get(CHANNEL_MESSAGE(this.channel.id, id))
|
.get(CHANNEL_MESSAGE(this.channel.id, id))
|
||||||
.then(async data => {
|
.then(async (data) => {
|
||||||
await this.set(id, data as MessagePayload)
|
await this.set(id, data as MessagePayload)
|
||||||
|
|
||||||
let channel: any = await this.client.channels.get<TextChannel>(
|
let channel: any = await this.client.channels.get<TextChannel>(
|
||||||
|
@ -63,7 +74,7 @@ export class MessagesManager extends BaseManager<MessagePayload, Message> {
|
||||||
|
|
||||||
resolve(res)
|
resolve(res)
|
||||||
})
|
})
|
||||||
.catch(e => reject(e))
|
.catch((e) => reject(e))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { TextChannel } from '../structures/textChannel.ts'
|
||||||
import { User } from '../structures/user.ts'
|
import { User } from '../structures/user.ts'
|
||||||
import { Collection } from '../utils/collection.ts'
|
import { Collection } from '../utils/collection.ts'
|
||||||
import { CommandClient } from './commandClient.ts'
|
import { CommandClient } from './commandClient.ts'
|
||||||
import { Extension } from "./extensions.ts"
|
import { Extension } from './extensions.ts'
|
||||||
|
|
||||||
export interface CommandContext {
|
export interface CommandContext {
|
||||||
/** The Client object */
|
/** The Client object */
|
||||||
|
@ -34,6 +34,8 @@ export class Command {
|
||||||
name: string = ''
|
name: string = ''
|
||||||
/** Description of the Command */
|
/** Description of the Command */
|
||||||
description?: string
|
description?: string
|
||||||
|
/** Category of the Command */
|
||||||
|
category?: string
|
||||||
/** Array of Aliases of Command, or only string */
|
/** Array of Aliases of Command, or only string */
|
||||||
aliases?: string | string[]
|
aliases?: string | string[]
|
||||||
/** Extension (Parent) of the Command */
|
/** Extension (Parent) of the Command */
|
||||||
|
@ -42,10 +44,12 @@ export class Command {
|
||||||
usage?: string | string[]
|
usage?: string | string[]
|
||||||
/** Usage Example of Command, only Arguments (without Prefix and Name) */
|
/** Usage Example of Command, only Arguments (without Prefix and Name) */
|
||||||
examples?: string | string[]
|
examples?: string | string[]
|
||||||
/** Does the Command take Arguments? Maybe number of required arguments? */
|
/** Does the Command take Arguments? Maybe number of required arguments? Or list of arguments? */
|
||||||
args?: number | boolean
|
args?: number | boolean | string[]
|
||||||
/** Permission(s) required for using Command */
|
/** Permissions(s) required by both User and Bot in order to use Command */
|
||||||
permissions?: string | string[]
|
permissions?: string | string[]
|
||||||
|
/** Permission(s) required for using Command */
|
||||||
|
userPermissions?: string | string[]
|
||||||
/** Permission(s) bot will need in order to execute Command */
|
/** Permission(s) bot will need in order to execute Command */
|
||||||
botPermissions?: string | string[]
|
botPermissions?: string | string[]
|
||||||
/** Role(s) user will require in order to use Command. List or one of ID or name */
|
/** Role(s) user will require in order to use Command. List or one of ID or name */
|
||||||
|
@ -64,14 +68,189 @@ export class Command {
|
||||||
ownerOnly?: boolean
|
ownerOnly?: boolean
|
||||||
|
|
||||||
/** Method executed before executing actual command. Returns bool value - whether to continue or not (optional) */
|
/** Method executed before executing actual command. Returns bool value - whether to continue or not (optional) */
|
||||||
beforeExecute(ctx: CommandContext): boolean | Promise<boolean> { return true }
|
beforeExecute(ctx: CommandContext): boolean | Promise<boolean> {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/** Actual command code, which is executed when all checks have passed. */
|
/** Actual command code, which is executed when all checks have passed. */
|
||||||
execute(ctx: CommandContext): any { }
|
execute(ctx: CommandContext): any {}
|
||||||
/** Method executed after executing command, passes on CommandContext and the value returned by execute too. (optional) */
|
/** Method executed after executing command, passes on CommandContext and the value returned by execute too. (optional) */
|
||||||
afterExecute(ctx: CommandContext, executeResult: any): any { }
|
afterExecute(ctx: CommandContext, executeResult: any): any {}
|
||||||
|
|
||||||
toString(): string {
|
toString(): string {
|
||||||
return `Command: ${this.name}${this.extension !== undefined ? ` [${this.extension.name}]` : ''}`
|
return `Command: ${this.name}${
|
||||||
|
this.extension !== undefined
|
||||||
|
? ` [${this.extension.name}]`
|
||||||
|
: this.category !== undefined
|
||||||
|
? ` [${this.category}]`
|
||||||
|
: ''
|
||||||
|
}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandCategory {
|
||||||
|
/** Name of the Category. */
|
||||||
|
name: string = ''
|
||||||
|
/** Permissions(s) required by both User and Bot in order to use Category Commands */
|
||||||
|
permissions?: string | string[]
|
||||||
|
/** Permission(s) required for using Category Commands */
|
||||||
|
userPermissions?: string | string[]
|
||||||
|
/** Permission(s) bot will need in order to execute Category Commands */
|
||||||
|
botPermissions?: string | string[]
|
||||||
|
/** Role(s) user will require in order to use Category Commands. List or one of ID or name */
|
||||||
|
roles?: string | string[]
|
||||||
|
/** Whitelisted Guilds. Only these Guild(s) can execute Category Commands. (List or one of IDs) */
|
||||||
|
whitelistedGuilds?: string | string[]
|
||||||
|
/** Whitelisted Channels. Category Commands can be executed only in these channels. (List or one of IDs) */
|
||||||
|
whitelistedChannels?: string | string[]
|
||||||
|
/** Whitelisted Users. Category Commands can be executed only by these Users (List or one of IDs) */
|
||||||
|
whitelistedUsers?: string | string[]
|
||||||
|
/** Whether the Category Commands can only be used in Guild (if allowed in DMs) */
|
||||||
|
guildOnly?: boolean
|
||||||
|
/** Whether the Category Commands can only be used in Bot's DMs (if allowed) */
|
||||||
|
dmOnly?: boolean
|
||||||
|
/** Whether the Category Commands can only be used by Bot Owners */
|
||||||
|
ownerOnly?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandBuilder extends Command {
|
||||||
|
setName(name: string): CommandBuilder {
|
||||||
|
this.name = name
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setDescription(description?: string): CommandBuilder {
|
||||||
|
this.description = description
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setCategory(category?: string): CommandBuilder {
|
||||||
|
this.category = category
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setAlias(alias: string | string[]): CommandBuilder {
|
||||||
|
this.aliases = alias
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
addAlias(alias: string | string[]): CommandBuilder {
|
||||||
|
if (this.aliases === undefined) this.aliases = []
|
||||||
|
if (typeof this.aliases === 'string') this.aliases = [this.aliases]
|
||||||
|
|
||||||
|
this.aliases = [
|
||||||
|
...new Set(
|
||||||
|
...this.aliases,
|
||||||
|
...(typeof alias === 'string' ? [alias] : alias)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setExtension(extension?: Extension): CommandBuilder {
|
||||||
|
this.extension = extension
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setUsage(usage: string | string[]): CommandBuilder {
|
||||||
|
this.usage = usage
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
addUsage(usage: string | string[]): CommandBuilder {
|
||||||
|
if (this.usage === undefined) this.usage = []
|
||||||
|
if (typeof this.usage === 'string') this.usage = [this.usage]
|
||||||
|
|
||||||
|
this.aliases = [
|
||||||
|
...new Set(
|
||||||
|
...this.usage,
|
||||||
|
...(typeof usage === 'string' ? [usage] : usage)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setExample(examples: string | string[]): CommandBuilder {
|
||||||
|
this.examples = examples
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
addExample(examples: string | string[]): CommandBuilder {
|
||||||
|
if (this.examples === undefined) this.examples = []
|
||||||
|
if (typeof this.examples === 'string') this.examples = [this.examples]
|
||||||
|
|
||||||
|
this.examples = [
|
||||||
|
...new Set(
|
||||||
|
...this.examples,
|
||||||
|
...(typeof examples === 'string' ? [examples] : examples)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setPermissions(perms?: string | string[]): CommandBuilder {
|
||||||
|
this.permissions = perms
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setUserPermissions(perms?: string | string[]): CommandBuilder {
|
||||||
|
this.userPermissions = perms
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setBotPermissions(perms?: string | string[]): CommandBuilder {
|
||||||
|
this.botPermissions = perms
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setRoles(roles: string | string[]): CommandBuilder {
|
||||||
|
this.roles = roles
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setWhitelistedGuilds(list: string | string[]): CommandBuilder {
|
||||||
|
this.whitelistedGuilds = list
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setWhitelistedUsers(list: string | string[]): CommandBuilder {
|
||||||
|
this.whitelistedUsers = list
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setWhitelistedChannels(list: string | string[]): CommandBuilder {
|
||||||
|
this.whitelistedChannels = list
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setGuildOnly(value: boolean = true): CommandBuilder {
|
||||||
|
this.guildOnly = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setOwnerOnly(value: boolean = true): CommandBuilder {
|
||||||
|
this.ownerOnly = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeExecute(fn: (ctx: CommandContext) => boolean | any): CommandBuilder {
|
||||||
|
this.beforeExecute = fn
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
onExecute(fn: (ctx: CommandContext) => any): CommandBuilder {
|
||||||
|
this.execute = fn
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
onAfterExecute(
|
||||||
|
fn: (ctx: CommandContext, executeResult?: any) => any
|
||||||
|
): CommandBuilder {
|
||||||
|
this.afterExecute = fn
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +264,9 @@ export class CommandsManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Number of loaded Commands */
|
/** Number of loaded Commands */
|
||||||
get count(): number { return this.list.size }
|
get count(): number {
|
||||||
|
return this.list.size
|
||||||
|
}
|
||||||
|
|
||||||
/** Find a Command by name/alias */
|
/** Find a Command by name/alias */
|
||||||
find(search: string): Command | undefined {
|
find(search: string): Command | undefined {
|
||||||
|
@ -99,7 +280,7 @@ export class CommandsManager {
|
||||||
if (typeof cmd.aliases === 'string') aliases = [cmd.aliases]
|
if (typeof cmd.aliases === 'string') aliases = [cmd.aliases]
|
||||||
else aliases = cmd.aliases
|
else aliases = cmd.aliases
|
||||||
if (this.client.caseSensitive === false)
|
if (this.client.caseSensitive === false)
|
||||||
aliases = aliases.map(e => e.toLowerCase())
|
aliases = aliases.map((e) => e.toLowerCase())
|
||||||
return aliases.includes(search)
|
return aliases.includes(search)
|
||||||
} else return false
|
} else return false
|
||||||
})
|
})
|
||||||
|
@ -123,8 +304,9 @@ export class CommandsManager {
|
||||||
const aliases: string[] =
|
const aliases: string[] =
|
||||||
typeof search.aliases === 'string' ? [search.aliases] : search.aliases
|
typeof search.aliases === 'string' ? [search.aliases] : search.aliases
|
||||||
exists =
|
exists =
|
||||||
aliases.map(alias => this.find(alias) !== undefined).find(e => e) ??
|
aliases
|
||||||
false
|
.map((alias) => this.find(alias) !== undefined)
|
||||||
|
.find((e) => e) ?? false
|
||||||
}
|
}
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
|
@ -134,7 +316,10 @@ export class CommandsManager {
|
||||||
add(cmd: Command | typeof Command): boolean {
|
add(cmd: Command | typeof Command): boolean {
|
||||||
// eslint-disable-next-line new-cap
|
// eslint-disable-next-line new-cap
|
||||||
if (!(cmd instanceof Command)) cmd = new cmd()
|
if (!(cmd instanceof Command)) cmd = new cmd()
|
||||||
if (this.exists(cmd)) throw new Error(`Failed to add Command '${cmd.toString()}' with name/alias already exists.`)
|
if (this.exists(cmd))
|
||||||
|
throw new Error(
|
||||||
|
`Failed to add Command '${cmd.toString()}' with name/alias already exists.`
|
||||||
|
)
|
||||||
this.list.set(cmd.name, cmd)
|
this.list.set(cmd.name, cmd)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -148,7 +333,7 @@ export class CommandsManager {
|
||||||
|
|
||||||
/** Check whether a Command is disabled or not */
|
/** Check whether a Command is disabled or not */
|
||||||
isDisabled(name: string | Command): boolean {
|
isDisabled(name: string | Command): boolean {
|
||||||
const cmd = typeof name === "string" ? this.find(name) : name
|
const cmd = typeof name === 'string' ? this.find(name) : name
|
||||||
if (cmd === undefined) return false
|
if (cmd === undefined) return false
|
||||||
const exists = this.exists(name)
|
const exists = this.exists(name)
|
||||||
if (!exists) return false
|
if (!exists) return false
|
||||||
|
@ -157,12 +342,65 @@ export class CommandsManager {
|
||||||
|
|
||||||
/** Disable a Command */
|
/** Disable a Command */
|
||||||
disable(name: string | Command): boolean {
|
disable(name: string | Command): boolean {
|
||||||
const cmd = typeof name === "string" ? this.find(name) : name
|
const cmd = typeof name === 'string' ? this.find(name) : name
|
||||||
if (cmd === undefined) return false
|
if (cmd === undefined) return false
|
||||||
if (this.isDisabled(cmd)) return false
|
if (this.isDisabled(cmd)) return false
|
||||||
this.disabled.add(cmd.name)
|
this.disabled.add(cmd.name)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get all commands of a Category */
|
||||||
|
category(category: string): Collection<string, Command> {
|
||||||
|
return this.list.filter(
|
||||||
|
(cmd) => cmd.category !== undefined && cmd.category === category
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CategoriesManager {
|
||||||
|
client: CommandClient
|
||||||
|
list: Collection<string, CommandCategory> = new Collection()
|
||||||
|
|
||||||
|
constructor(client: CommandClient) {
|
||||||
|
this.client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get a Collection of Categories */
|
||||||
|
all(): Collection<string, CommandCategory> {
|
||||||
|
return this.list
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get a list of names of Categories added */
|
||||||
|
names(): string[] {
|
||||||
|
return [...this.list.keys()]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if a Category exists or not */
|
||||||
|
has(category: string | CommandCategory): boolean {
|
||||||
|
return this.list.has(
|
||||||
|
typeof category === 'string' ? category : category.name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get a Category by name */
|
||||||
|
get(name: string): CommandCategory | undefined {
|
||||||
|
return this.list.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add a Category to the Manager */
|
||||||
|
add(category: CommandCategory): CategoriesManager {
|
||||||
|
if (this.has(category))
|
||||||
|
throw new Error(`Category ${category.name} already exists`)
|
||||||
|
this.list.set(category.name, category)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove a Category from the Manager */
|
||||||
|
remove(category: string | CommandCategory): boolean {
|
||||||
|
if (!this.has(category)) return false
|
||||||
|
this.list.delete(typeof category === 'string' ? category : category.name)
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ParsedCommand {
|
export interface ParsedCommand {
|
||||||
|
@ -185,6 +423,6 @@ export const parseCommand = (
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
argString
|
argString,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
import { Message } from "../../mod.ts"
|
import { Message } from '../../mod.ts'
|
||||||
import { awaitSync } from "../utils/mixedPromise.ts"
|
import { awaitSync } from '../utils/mixedPromise.ts'
|
||||||
import { Client, ClientOptions } from './client.ts'
|
import { Client, ClientOptions } from './client.ts'
|
||||||
import { CommandContext, CommandsManager, parseCommand } from './command.ts'
|
import {
|
||||||
import { ExtensionsManager } from "./extensions.ts"
|
CategoriesManager,
|
||||||
|
CommandContext,
|
||||||
|
CommandsManager,
|
||||||
|
parseCommand,
|
||||||
|
} from './command.ts'
|
||||||
|
import { ExtensionsManager } from './extensions.ts'
|
||||||
|
|
||||||
type PrefixReturnType = string | string[] | Promise<string | string[]>
|
type PrefixReturnType = string | string[] | Promise<string | string[]>
|
||||||
|
|
||||||
|
@ -38,6 +43,7 @@ export class CommandClient extends Client implements CommandClientOptions {
|
||||||
caseSensitive: boolean
|
caseSensitive: boolean
|
||||||
extensions: ExtensionsManager = new ExtensionsManager(this)
|
extensions: ExtensionsManager = new ExtensionsManager(this)
|
||||||
commands: CommandsManager = new CommandsManager(this)
|
commands: CommandsManager = new CommandsManager(this)
|
||||||
|
categories: CategoriesManager = new CategoriesManager(this)
|
||||||
|
|
||||||
constructor(options: CommandClientOptions) {
|
constructor(options: CommandClientOptions) {
|
||||||
super(options)
|
super(options)
|
||||||
|
@ -85,14 +91,20 @@ export class CommandClient extends Client implements CommandClientOptions {
|
||||||
async processMessage(msg: Message): Promise<any> {
|
async processMessage(msg: Message): Promise<any> {
|
||||||
if (!this.allowBots && msg.author.bot === true) return
|
if (!this.allowBots && msg.author.bot === true) return
|
||||||
|
|
||||||
const isUserBlacklisted = await awaitSync(this.isUserBlacklisted(msg.author.id))
|
const isUserBlacklisted = await awaitSync(
|
||||||
|
this.isUserBlacklisted(msg.author.id)
|
||||||
|
)
|
||||||
if (isUserBlacklisted === true) return
|
if (isUserBlacklisted === true) return
|
||||||
|
|
||||||
const isChannelBlacklisted = await awaitSync(this.isChannelBlacklisted(msg.channel.id))
|
const isChannelBlacklisted = await awaitSync(
|
||||||
|
this.isChannelBlacklisted(msg.channel.id)
|
||||||
|
)
|
||||||
if (isChannelBlacklisted === true) return
|
if (isChannelBlacklisted === true) return
|
||||||
|
|
||||||
if (msg.guild !== undefined) {
|
if (msg.guild !== undefined) {
|
||||||
const isGuildBlacklisted = await awaitSync(this.isGuildBlacklisted(msg.guild.id))
|
const isGuildBlacklisted = await awaitSync(
|
||||||
|
this.isGuildBlacklisted(msg.guild.id)
|
||||||
|
)
|
||||||
if (isGuildBlacklisted === true) return
|
if (isGuildBlacklisted === true) return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,17 +124,20 @@ export class CommandClient extends Client implements CommandClientOptions {
|
||||||
else return
|
else return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const usedPrefix = prefix.find(v => msg.content.startsWith(v))
|
const usedPrefix = prefix.find((v) => msg.content.startsWith(v))
|
||||||
if (usedPrefix === undefined) {
|
if (usedPrefix === undefined) {
|
||||||
if (this.mentionPrefix) mentionPrefix = true
|
if (this.mentionPrefix) mentionPrefix = true
|
||||||
else return
|
else return
|
||||||
}
|
} else prefix = usedPrefix
|
||||||
else prefix = usedPrefix
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mentionPrefix) {
|
if (mentionPrefix) {
|
||||||
if (msg.content.startsWith(this.user?.mention as string) === true) prefix = this.user?.mention as string
|
if (msg.content.startsWith(this.user?.mention as string) === true)
|
||||||
else if (msg.content.startsWith(this.user?.nickMention as string) === true) prefix = this.user?.nickMention as string
|
prefix = this.user?.mention as string
|
||||||
|
else if (
|
||||||
|
msg.content.startsWith(this.user?.nickMention as string) === true
|
||||||
|
)
|
||||||
|
prefix = this.user?.nickMention as string
|
||||||
else return
|
else return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,10 +147,52 @@ export class CommandClient extends Client implements CommandClientOptions {
|
||||||
const command = this.commands.find(parsed.name)
|
const command = this.commands.find(parsed.name)
|
||||||
|
|
||||||
if (command === undefined) return
|
if (command === undefined) return
|
||||||
|
const category =
|
||||||
|
command.category !== undefined
|
||||||
|
? this.categories.get(command.category)
|
||||||
|
: undefined
|
||||||
|
|
||||||
if (command.whitelistedGuilds !== undefined && msg.guild !== undefined && command.whitelistedGuilds.includes(msg.guild.id) === false) return;
|
// Guild whitelist exists, and if does and Command used in a Guild, is this Guild allowed?
|
||||||
if (command.whitelistedChannels !== undefined && command.whitelistedChannels.includes(msg.channel.id) === false) return;
|
// This is a bit confusing here, if these settings on a Command exist, and also do on Category, Command overrides them
|
||||||
if (command.whitelistedUsers !== undefined && command.whitelistedUsers.includes(msg.author.id) === false) return;
|
if (
|
||||||
|
command.whitelistedGuilds === undefined &&
|
||||||
|
category?.whitelistedGuilds !== undefined &&
|
||||||
|
msg.guild !== undefined &&
|
||||||
|
category.whitelistedGuilds.includes(msg.guild.id) === false
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if (
|
||||||
|
command.whitelistedGuilds !== undefined &&
|
||||||
|
msg.guild !== undefined &&
|
||||||
|
command.whitelistedGuilds.includes(msg.guild.id) === false
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
// Checks for Channel Whitelist
|
||||||
|
if (
|
||||||
|
command.whitelistedChannels === undefined &&
|
||||||
|
category?.whitelistedChannels !== undefined &&
|
||||||
|
category.whitelistedChannels.includes(msg.channel.id) === false
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if (
|
||||||
|
command.whitelistedChannels !== undefined &&
|
||||||
|
command.whitelistedChannels.includes(msg.channel.id) === false
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
// Checks for Users Whitelist
|
||||||
|
if (
|
||||||
|
command.whitelistedUsers === undefined &&
|
||||||
|
category?.whitelistedUsers !== undefined &&
|
||||||
|
category.whitelistedUsers.includes(msg.author.id) === false
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if (
|
||||||
|
command.whitelistedUsers !== undefined &&
|
||||||
|
command.whitelistedUsers.includes(msg.author.id) === false
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
const ctx: CommandContext = {
|
const ctx: CommandContext = {
|
||||||
client: this,
|
client: this,
|
||||||
|
@ -147,40 +204,117 @@ export class CommandClient extends Client implements CommandClientOptions {
|
||||||
author: msg.author,
|
author: msg.author,
|
||||||
command,
|
command,
|
||||||
channel: msg.channel,
|
channel: msg.channel,
|
||||||
guild: msg.guild
|
guild: msg.guild,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.ownerOnly === true && !this.owners.includes(msg.author.id)) return this.emit('commandOwnerOnly', ctx, command)
|
// In these checks too, Command overrides Category if present
|
||||||
if (command.guildOnly === true && msg.guild === undefined) return this.emit('commandGuildOnly', ctx, command)
|
// Check if Command is only for Owners
|
||||||
if (command.dmOnly === true && msg.guild !== undefined) return this.emit('commandDmOnly', ctx, command)
|
if (
|
||||||
|
(command.ownerOnly !== undefined || category === undefined
|
||||||
|
? command.ownerOnly
|
||||||
|
: category.ownerOnly) === true &&
|
||||||
|
!this.owners.includes(msg.author.id)
|
||||||
|
)
|
||||||
|
return this.emit('commandOwnerOnly', ctx, command)
|
||||||
|
|
||||||
if (command.botPermissions !== undefined && msg.guild !== undefined) {
|
// Check if Command is only for Guild
|
||||||
|
if (
|
||||||
|
(command.guildOnly !== undefined || category === undefined
|
||||||
|
? command.guildOnly
|
||||||
|
: category.guildOnly) === true &&
|
||||||
|
msg.guild === undefined
|
||||||
|
)
|
||||||
|
return this.emit('commandGuildOnly', ctx, command)
|
||||||
|
|
||||||
|
// Check if Command is only for DMs
|
||||||
|
if (
|
||||||
|
(command.dmOnly !== undefined || category === undefined
|
||||||
|
? command.dmOnly
|
||||||
|
: category.dmOnly) === true &&
|
||||||
|
msg.guild !== undefined
|
||||||
|
)
|
||||||
|
return this.emit('commandDmOnly', ctx, command)
|
||||||
|
|
||||||
|
const allPermissions =
|
||||||
|
command.permissions !== undefined
|
||||||
|
? command.permissions
|
||||||
|
: category?.permissions
|
||||||
|
|
||||||
|
if (
|
||||||
|
(command.botPermissions !== undefined ||
|
||||||
|
category?.permissions !== undefined) &&
|
||||||
|
msg.guild !== undefined
|
||||||
|
) {
|
||||||
// TODO: Check Overwrites too
|
// TODO: Check Overwrites too
|
||||||
const me = await msg.guild.me()
|
const me = await msg.guild.me()
|
||||||
const missing: string[] = []
|
const missing: string[] = []
|
||||||
|
|
||||||
for (const perm of command.botPermissions) {
|
let permissions =
|
||||||
if (me.permissions.has(perm) === false) missing.push(perm)
|
command.botPermissions === undefined
|
||||||
}
|
? category?.permissions
|
||||||
|
: command.botPermissions
|
||||||
|
|
||||||
if (missing.length !== 0) return this.emit('commandBotMissingPermissions', ctx, command, missing)
|
if (permissions !== undefined) {
|
||||||
|
if (typeof permissions === 'string') permissions = [permissions]
|
||||||
|
|
||||||
|
if (allPermissions !== undefined)
|
||||||
|
permissions = [...new Set(...permissions, ...allPermissions)]
|
||||||
|
|
||||||
|
for (const perm of permissions) {
|
||||||
|
if (me.permissions.has(perm) === false) missing.push(perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missing.length !== 0)
|
||||||
|
return this.emit(
|
||||||
|
'commandBotMissingPermissions',
|
||||||
|
ctx,
|
||||||
|
command,
|
||||||
|
missing
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.permissions !== undefined && msg.guild !== undefined) {
|
if (
|
||||||
const missing: string[] = []
|
(command.userPermissions !== undefined ||
|
||||||
let perms: string[] = []
|
category?.userPermissions !== undefined) &&
|
||||||
if (typeof command.permissions === 'string') perms = [command.permissions]
|
msg.guild !== undefined
|
||||||
else perms = command.permissions
|
) {
|
||||||
for (const perm of perms) {
|
let permissions =
|
||||||
const has = msg.member?.permissions.has(perm)
|
command.userPermissions !== undefined
|
||||||
if (has !== true) missing.push(perm)
|
? command.userPermissions
|
||||||
|
: category?.userPermissions
|
||||||
|
|
||||||
|
if (permissions !== undefined) {
|
||||||
|
if (typeof permissions === 'string') permissions = [permissions]
|
||||||
|
|
||||||
|
if (allPermissions !== undefined)
|
||||||
|
permissions = [...new Set(...permissions, ...allPermissions)]
|
||||||
|
|
||||||
|
const missing: string[] = []
|
||||||
|
|
||||||
|
for (const perm of permissions) {
|
||||||
|
const has = msg.member?.permissions.has(perm)
|
||||||
|
if (has !== true) missing.push(perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missing.length !== 0)
|
||||||
|
return this.emit(
|
||||||
|
'commandUserMissingPermissions',
|
||||||
|
command,
|
||||||
|
missing,
|
||||||
|
ctx
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (missing.length !== 0) return this.emit('commandMissingPermissions', command, missing, ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.args !== undefined) {
|
if (command.args !== undefined) {
|
||||||
if (typeof command.args === 'boolean' && parsed.args.length === 0) return this.emit('commandMissingArgs', ctx, command)
|
if (typeof command.args === 'boolean' && parsed.args.length === 0)
|
||||||
else if (typeof command.args === 'number' && parsed.args.length < command.args) this.emit('commandMissingArgs', ctx, command)
|
return this.emit('commandMissingArgs', ctx, command)
|
||||||
|
else if (
|
||||||
|
typeof command.args === 'number' &&
|
||||||
|
parsed.args.length < command.args
|
||||||
|
)
|
||||||
|
this.emit('commandMissingArgs', ctx, command)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Client } from "../models/client.ts";
|
import { Client } from '../models/client.ts'
|
||||||
import { MessagePayload } from "../types/channel.ts";
|
import { MessagePayload } from '../types/channel.ts'
|
||||||
import { Collection } from "../utils/collection.ts";
|
import { Collection } from '../utils/collection.ts'
|
||||||
import { GuildTextChannel } from "./textChannel.ts";
|
import { GuildTextChannel } from './textChannel.ts'
|
||||||
import { Message } from "./message.ts";
|
import { Message } from './message.ts'
|
||||||
import { Role } from "./role.ts";
|
import { Role } from './role.ts'
|
||||||
import { User } from "./user.ts";
|
import { User } from './user.ts'
|
||||||
|
|
||||||
export class MessageMentions {
|
export class MessageMentions {
|
||||||
client: Client
|
client: Client
|
||||||
|
@ -25,27 +25,35 @@ export class MessageMentions {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fromPayload(payload: MessagePayload): Promise<MessageMentions> {
|
async fromPayload(payload: MessagePayload): Promise<MessageMentions> {
|
||||||
payload.mentions.forEach(rawUser => {
|
if (this.message === undefined) return this
|
||||||
this.users.set(rawUser.id, new User(this.client, rawUser))
|
if (payload.mentions !== undefined)
|
||||||
})
|
payload.mentions.forEach((rawUser) => {
|
||||||
|
this.users.set(rawUser.id, new User(this.client, rawUser))
|
||||||
|
})
|
||||||
|
|
||||||
if (this.message.guild !== undefined) {
|
if (this.message.guild !== undefined) {
|
||||||
for (const id of payload.mention_roles) {
|
for (const id of payload.mention_roles) {
|
||||||
const role = await this.message.guild.roles.get(id)
|
const role = await this.message.guild.roles.get(id)
|
||||||
if(role !== undefined) this.roles.set(role.id, role)
|
if (role !== undefined) this.roles.set(role.id, role)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (payload.mention_channels !== undefined) {
|
if (payload.mention_channels !== undefined) {
|
||||||
for (const mentionChannel of payload.mention_channels) {
|
for (const mentionChannel of payload.mention_channels) {
|
||||||
const channel = await this.client.channels.get<GuildTextChannel>(mentionChannel.id)
|
const channel = await this.client.channels.get<GuildTextChannel>(
|
||||||
|
mentionChannel.id
|
||||||
|
)
|
||||||
if (channel !== undefined) this.channels.set(channel.id, channel)
|
if (channel !== undefined) this.channels.set(channel.id, channel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const matchChannels = this.message.content.match(MessageMentions.CHANNEL_MENTION)
|
const matchChannels = this.message.content.match(
|
||||||
|
MessageMentions.CHANNEL_MENTION
|
||||||
|
)
|
||||||
if (matchChannels !== null) {
|
if (matchChannels !== null) {
|
||||||
for (const id of matchChannels) {
|
for (const id of matchChannels) {
|
||||||
const parsedID = id.substr(2, id.length - 3)
|
const parsedID = id.substr(2, id.length - 3)
|
||||||
const channel = await this.client.channels.get<GuildTextChannel>(parsedID)
|
const channel = await this.client.channels.get<GuildTextChannel>(
|
||||||
|
parsedID
|
||||||
|
)
|
||||||
if (channel !== undefined) this.channels.set(channel.id, channel)
|
if (channel !== undefined) this.channels.set(channel.id, channel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
import { Command, CommandClient, Intents, GuildChannel, CommandContext, Extension } from '../../mod.ts'
|
import {
|
||||||
|
Command,
|
||||||
|
CommandClient,
|
||||||
|
Intents,
|
||||||
|
GuildChannel,
|
||||||
|
CommandContext,
|
||||||
|
Extension,
|
||||||
|
} from '../../mod.ts'
|
||||||
import { TOKEN } from './config.ts'
|
import { TOKEN } from './config.ts'
|
||||||
|
|
||||||
const client = new CommandClient({
|
const client = new CommandClient({
|
||||||
prefix: ["pls", "!"],
|
prefix: ['pls', '!'],
|
||||||
spacesAfterPrefix: true,
|
spacesAfterPrefix: true,
|
||||||
mentionPrefix: true
|
mentionPrefix: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('debug', console.log)
|
client.on('debug', console.log)
|
||||||
|
@ -55,10 +62,9 @@ client.on('webhooksUpdate', (guild, channel) => {
|
||||||
console.log(`Webhooks Updated in #${channel.name} from ${guild.name}`)
|
console.log(`Webhooks Updated in #${channel.name} from ${guild.name}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on("commandError", console.error)
|
client.on('commandError', console.error)
|
||||||
|
|
||||||
class ChannelLog extends Extension {
|
class ChannelLog extends Extension {
|
||||||
|
|
||||||
onChannelCreate(ext: Extension, channel: GuildChannel): void {
|
onChannelCreate(ext: Extension, channel: GuildChannel): void {
|
||||||
console.log(`Channel Created: ${channel.name}`)
|
console.log(`Channel Created: ${channel.name}`)
|
||||||
}
|
}
|
||||||
|
@ -81,15 +87,27 @@ class ChannelLog extends Extension {
|
||||||
client.extensions.load(ChannelLog)
|
client.extensions.load(ChannelLog)
|
||||||
|
|
||||||
client.on('messageDeleteBulk', (channel, messages, uncached) => {
|
client.on('messageDeleteBulk', (channel, messages, uncached) => {
|
||||||
console.log(`=== Message Delete Bulk ===\nMessages: ${messages.map(m => m.id).join(', ')}\nUncached: ${[...uncached.values()].join(', ')}`)
|
console.log(
|
||||||
|
`=== Message Delete Bulk ===\nMessages: ${messages
|
||||||
|
.map((m) => m.id)
|
||||||
|
.join(', ')}\nUncached: ${[...uncached.values()].join(', ')}`
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('channelUpdate', (before, after) => {
|
client.on('channelUpdate', (before, after) => {
|
||||||
console.log(`Channel Update: ${(before as GuildChannel).name}, ${(after as GuildChannel).name}`)
|
console.log(
|
||||||
|
`Channel Update: ${(before as GuildChannel).name}, ${
|
||||||
|
(after as GuildChannel).name
|
||||||
|
}`
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('typingStart', (user, channel, at, guildData) => {
|
client.on('typingStart', (user, channel, at, guildData) => {
|
||||||
console.log(`${user.tag} started typing in ${channel.id} at ${at}${guildData !== undefined ? `\nGuild: ${guildData.guild.name}` : ''}`)
|
console.log(
|
||||||
|
`${user.tag} started typing in ${channel.id} at ${at}${
|
||||||
|
guildData !== undefined ? `\nGuild: ${guildData.guild.name}` : ''
|
||||||
|
}`
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('voiceStateAdd', (state) => {
|
client.on('voiceStateAdd', (state) => {
|
||||||
|
|
Loading…
Reference in a new issue