Guild#roles, Guild#members, Guild#channels now work. All these are now cached in guildCreate, and deleted in guildDelete. And some new methods to be implemented by CacheAdapter, plus BaseManager#flush was added to flush cache.
This commit is contained in:
parent
04056a7f9c
commit
1abd6f2138
22 changed files with 243 additions and 106 deletions
|
@ -5,7 +5,7 @@ export const channelDelete: GatewayEventHandler = async(
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
d: any
|
d: any
|
||||||
) => {
|
) => {
|
||||||
const channel: Channel = await gateway.client.channels.get(d.id)
|
const channel: Channel | void = await gateway.client.channels.get(d.id)
|
||||||
if (channel !== undefined) {
|
if (channel !== undefined) {
|
||||||
await gateway.client.channels.delete(d.id)
|
await gateway.client.channels.delete(d.id)
|
||||||
gateway.client.emit('channelDelete', channel)
|
gateway.client.emit('channelDelete', channel)
|
||||||
|
|
|
@ -7,7 +7,7 @@ export const channelPinsUpdate: GatewayEventHandler = async(
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
d: any
|
d: any
|
||||||
) => {
|
) => {
|
||||||
const after: TextChannel = await gateway.client.channels.get(d.channel_id)
|
const after: TextChannel | void = 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
|
||||||
|
|
|
@ -7,7 +7,7 @@ export const channelUpdate: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
d: any
|
d: any
|
||||||
) => {
|
) => {
|
||||||
const oldChannel: Channel = await gateway.client.channels.get(d.id)
|
const oldChannel: Channel | void = await gateway.client.channels.get(d.id)
|
||||||
|
|
||||||
if (oldChannel !== undefined) {
|
if (oldChannel !== undefined) {
|
||||||
await gateway.client.channels.set(d.id, d)
|
await gateway.client.channels.set(d.id, d)
|
||||||
|
|
|
@ -1,16 +1,51 @@
|
||||||
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, MemberPayload } from "../../types/guild.ts"
|
||||||
|
import { MembersManager } from "../../managers/MembersManager.ts"
|
||||||
|
import { ChannelPayload } from "../../types/channel.ts"
|
||||||
|
import { RolePayload } from "../../types/role.ts"
|
||||||
|
import { RolesManager } from "../../managers/RolesManager.ts"
|
||||||
|
|
||||||
export const guildCreate: GatewayEventHandler = async(gateway: Gateway, d: GuildPayload) => {
|
export const guildCreate: GatewayEventHandler = async(gateway: Gateway, d: GuildPayload) => {
|
||||||
let guild: Guild | void = await gateway.client.guilds.get(d.id)
|
let guild: Guild | void = await gateway.client.guilds.get(d.id)
|
||||||
if (guild !== undefined) {
|
if (guild !== undefined) {
|
||||||
// It was just lazy load, so we don't fire the event as its gonna fire for every guild bot is in
|
// It was just lazy load, so we don't fire the event as its gonna fire for every guild bot is in
|
||||||
await gateway.client.guilds.set(d.id, d)
|
await gateway.client.guilds.set(d.id, d)
|
||||||
|
if((d as GuildPayload).members) {
|
||||||
|
let members = new MembersManager(gateway.client, guild)
|
||||||
|
await members.fromPayload((d as GuildPayload).members as MemberPayload[])
|
||||||
|
guild.members = members
|
||||||
|
}
|
||||||
|
if((d as GuildPayload).channels) {
|
||||||
|
for (let ch of (d as GuildPayload).channels as ChannelPayload[]) {
|
||||||
|
(ch as any).guild_id = d.id
|
||||||
|
await gateway.client.channels.set(ch.id, ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((d as GuildPayload).roles) {
|
||||||
|
let roles = new RolesManager(gateway.client, guild)
|
||||||
|
await roles.fromPayload((d as GuildPayload).roles as RolePayload[])
|
||||||
|
guild.roles = roles
|
||||||
|
}
|
||||||
guild.refreshFromData(d)
|
guild.refreshFromData(d)
|
||||||
} else {
|
} else {
|
||||||
await gateway.client.guilds.set(d.id, d)
|
await gateway.client.guilds.set(d.id, d)
|
||||||
guild = new Guild(gateway.client, d as GuildPayload)
|
guild = new Guild(gateway.client, d as GuildPayload)
|
||||||
|
if((d as GuildPayload).members) {
|
||||||
|
let members = new MembersManager(gateway.client, guild)
|
||||||
|
await members.fromPayload((d as GuildPayload).members as MemberPayload[])
|
||||||
|
guild.members = members
|
||||||
|
}
|
||||||
|
if((d as GuildPayload).channels) {
|
||||||
|
for (let ch of (d as GuildPayload).channels as ChannelPayload[]) {
|
||||||
|
await gateway.client.channels.set(ch.id, ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((d as GuildPayload).roles) {
|
||||||
|
let roles = new RolesManager(gateway.client, guild)
|
||||||
|
await roles.fromPayload((d as GuildPayload).roles as RolePayload[])
|
||||||
|
guild.roles = roles
|
||||||
|
}
|
||||||
await guild.roles.fromPayload(d.roles)
|
await guild.roles.fromPayload(d.roles)
|
||||||
gateway.client.emit('guildCreate', guild)
|
gateway.client.emit('guildCreate', guild)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@ export const guildDelte: GatewayEventHandler = async (gateway: Gateway, d: any)
|
||||||
|
|
||||||
if (guild !== undefined) {
|
if (guild !== undefined) {
|
||||||
guild.refreshFromData(d)
|
guild.refreshFromData(d)
|
||||||
|
await guild.members.flush()
|
||||||
|
await guild.channels.flush()
|
||||||
|
await guild.roles.flush()
|
||||||
await gateway.client.guilds.delete(d.id)
|
await gateway.client.guilds.delete(d.id)
|
||||||
gateway.client.emit('guildDelete', guild)
|
gateway.client.emit('guildDelete', guild)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,17 @@ export const messageCreate: GatewayEventHandler = async(
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
d: MessagePayload
|
d: MessagePayload
|
||||||
) => {
|
) => {
|
||||||
let channel = await gateway.client.channels.get(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) channel = (await gateway.client.channels.fetch(d.channel_id) as any) as TextChannel
|
if(!channel) channel = (await gateway.client.channels.fetch(d.channel_id) as any) as TextChannel
|
||||||
let user = new User(gateway.client, d.author)
|
let user = new User(gateway.client, d.author)
|
||||||
await gateway.client.users.set(d.author.id, d.author)
|
await gateway.client.users.set(d.author.id, d.author)
|
||||||
|
let guild
|
||||||
|
if(d.guild_id) {
|
||||||
|
guild = await gateway.client.guilds.get(d.guild_id)
|
||||||
|
}
|
||||||
let mentions = new MessageMentions()
|
let mentions = new MessageMentions()
|
||||||
let message = new Message(gateway.client, d, channel, user, mentions)
|
let message = new Message(gateway.client, d, channel, user, mentions)
|
||||||
|
if(guild) message.guild = guild
|
||||||
gateway.client.emit('messageCreate', message)
|
gateway.client.emit('messageCreate', message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Client } from "../models/client.ts";
|
import { Client } from "../models/client.ts";
|
||||||
|
import { Collection } from "../utils/collection.ts";
|
||||||
import { BaseManager } from "./BaseManager.ts";
|
import { BaseManager } from "./BaseManager.ts";
|
||||||
|
|
||||||
export class BaseChildManager<T, T2> {
|
export class BaseChildManager<T, T2> {
|
||||||
|
@ -21,4 +22,19 @@ export class BaseChildManager<T, T2> {
|
||||||
async delete(key: string): Promise<any> {
|
async delete(key: string): Promise<any> {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async array(): Promise<any> {
|
||||||
|
return await this.parent.array()
|
||||||
|
}
|
||||||
|
|
||||||
|
async collection(): Promise<Collection<string, T2>> {
|
||||||
|
const arr = await this.array() as void | T2[]
|
||||||
|
if(arr === undefined) return new Collection()
|
||||||
|
let collection = new Collection()
|
||||||
|
for (const elem of arr) {
|
||||||
|
// @ts-ignore
|
||||||
|
collection.set(elem.id, elem)
|
||||||
|
}
|
||||||
|
return collection
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -30,8 +30,9 @@ export class BaseManager<T, T2> {
|
||||||
return this.client.cache.delete(this.cacheName, key)
|
return this.client.cache.delete(this.cacheName, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
array(): Promise<void | T2[]> {
|
async array(): Promise<void | T2[]> {
|
||||||
return (this.client.cache.array(this.cacheName) as T[]).map(e => new this.dataType(this.client, e)) as any
|
let arr = await (this.client.cache.array(this.cacheName) as T[])
|
||||||
|
return arr.map(e => new this.dataType(this.client, e)) as any
|
||||||
}
|
}
|
||||||
|
|
||||||
async collection(): Promise<Collection<string, T2>> {
|
async collection(): Promise<Collection<string, T2>> {
|
||||||
|
@ -44,4 +45,8 @@ export class BaseManager<T, T2> {
|
||||||
}
|
}
|
||||||
return collection
|
return collection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush() {
|
||||||
|
return this.client.cache.deleteCache(this.cacheName)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,23 +3,48 @@ import { Channel } from "../structures/channel.ts";
|
||||||
import { User } from "../structures/user.ts";
|
import { User } from "../structures/user.ts";
|
||||||
import { ChannelPayload } from "../types/channel.ts";
|
import { ChannelPayload } from "../types/channel.ts";
|
||||||
import { CHANNEL } from "../types/endpoint.ts";
|
import { CHANNEL } from "../types/endpoint.ts";
|
||||||
|
import getChannelByType from "../utils/getChannelByType.ts";
|
||||||
import { BaseManager } from "./BaseManager.ts";
|
import { BaseManager } from "./BaseManager.ts";
|
||||||
|
|
||||||
export class ChannelsManager extends BaseManager<ChannelPayload, Channel> {
|
export class ChannelsManager extends BaseManager<ChannelPayload, Channel> {
|
||||||
constructor(client: Client) {
|
constructor(client: Client) {
|
||||||
super(client, "channels", User)
|
super(client, "channels", Channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override get method as Generic
|
// Override get method as Generic
|
||||||
async get<T = Channel>(key: string): Promise<T> {
|
async get<T = Channel>(key: string): Promise<T | void> {
|
||||||
return new this.dataType(this.client, this._get(key)) as any
|
let data = await this._get(key) as any
|
||||||
|
if(!data) return
|
||||||
|
let guild
|
||||||
|
if(data.guild_id) {
|
||||||
|
guild = await this.client.guilds.get(data.guild_id)
|
||||||
|
}
|
||||||
|
let res = getChannelByType(this.client, data as ChannelPayload, guild || undefined)
|
||||||
|
return res as any
|
||||||
|
}
|
||||||
|
|
||||||
|
async array(): Promise<void | Channel[]> {
|
||||||
|
let arr = await (this.client.cache.array(this.cacheName) as ChannelPayload[])
|
||||||
|
let result: any[] = []
|
||||||
|
for(let elem of arr) {
|
||||||
|
let guild
|
||||||
|
if((elem as any).guild_id) {
|
||||||
|
guild = await this.client.guilds.get((elem as any).guild_id)
|
||||||
|
}
|
||||||
|
result.push(getChannelByType(this.client, elem as ChannelPayload, guild || undefined))
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch(id: string): Promise<Channel> {
|
fetch(id: string): Promise<Channel> {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
this.client.rest.get(CHANNEL(id)).then(data => {
|
this.client.rest.get(CHANNEL(id)).then(async data => {
|
||||||
this.set(id, data as ChannelPayload)
|
this.set(id, data as ChannelPayload)
|
||||||
res(new Channel(this.client, data as ChannelPayload))
|
let guild
|
||||||
|
if((data as any).guild_id) {
|
||||||
|
guild = await this.client.guilds.get((data as any).guild_id)
|
||||||
|
}
|
||||||
|
res(getChannelByType(this.client, data as ChannelPayload, guild || undefined))
|
||||||
}).catch(e => rej(e))
|
}).catch(e => rej(e))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ export class GatewayCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(key: string) {
|
delete(key: string) {
|
||||||
console.log(`[GatewayCache] DEL ${key}`)
|
|
||||||
return this.client.cache.delete(this.cacheName, key)
|
return this.client.cache.delete(this.cacheName, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { Client } from "../models/client.ts";
|
import { Client } from "../models/client.ts";
|
||||||
|
import { Channel } from "../structures/channel.ts";
|
||||||
import { Guild } from "../structures/guild.ts";
|
import { Guild } from "../structures/guild.ts";
|
||||||
import { CategoryChannel } from "../structures/guildCategoryChannel.ts";
|
import { CategoryChannel } from "../structures/guildCategoryChannel.ts";
|
||||||
import { GuildTextChannel } from "../structures/guildTextChannel.ts";
|
import { GuildTextChannel } from "../structures/guildTextChannel.ts";
|
||||||
|
@ -7,6 +8,7 @@ import { GuildChannelCategoryPayload, GuildTextChannelPayload, GuildVoiceChannel
|
||||||
import { CHANNEL } from "../types/endpoint.ts";
|
import { CHANNEL } from "../types/endpoint.ts";
|
||||||
import { BaseChildManager } from "./BaseChildManager.ts";
|
import { BaseChildManager } from "./BaseChildManager.ts";
|
||||||
import { BaseManager } from "./BaseManager.ts";
|
import { BaseManager } from "./BaseManager.ts";
|
||||||
|
import { ChannelsManager } from "./ChannelsManager.ts";
|
||||||
|
|
||||||
export type GuildChannelPayload = GuildTextChannelPayload | GuildVoiceChannelPayload | GuildChannelCategoryPayload
|
export type GuildChannelPayload = GuildTextChannelPayload | GuildVoiceChannelPayload | GuildChannelCategoryPayload
|
||||||
export type GuildChannel = GuildTextChannel | VoiceChannel | CategoryChannel
|
export type GuildChannel = GuildTextChannel | VoiceChannel | CategoryChannel
|
||||||
|
@ -14,8 +16,8 @@ export type GuildChannel = GuildTextChannel | VoiceChannel | CategoryChannel
|
||||||
export class GuildChannelsManager extends BaseChildManager<GuildChannelPayload, GuildChannel> {
|
export class GuildChannelsManager extends BaseChildManager<GuildChannelPayload, GuildChannel> {
|
||||||
guild: Guild
|
guild: Guild
|
||||||
|
|
||||||
constructor(client: Client, parent: BaseManager<GuildChannelPayload, GuildChannel>, guild: Guild) {
|
constructor(client: Client, parent: ChannelsManager, guild: Guild) {
|
||||||
super(client, parent)
|
super(client, parent as any)
|
||||||
this.guild = guild
|
this.guild = guild
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,4 +30,17 @@ export class GuildChannelsManager extends BaseChildManager<GuildChannelPayload,
|
||||||
delete(id: string) {
|
delete(id: string) {
|
||||||
return this.client.rest.delete(CHANNEL(id))
|
return this.client.rest.delete(CHANNEL(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async array(): Promise<GuildChannel[]> {
|
||||||
|
let arr = await this.parent.array() as Channel[]
|
||||||
|
return arr as any//.filter((c: any) => c.guild && c.guild.id == this.guild.id) as any
|
||||||
|
}
|
||||||
|
|
||||||
|
async flush() {
|
||||||
|
let arr = await this.array()
|
||||||
|
for (let elem of arr) {
|
||||||
|
this.parent.delete(elem.id)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
|
import { guildBanAdd } from "../gateway/handlers/guildBanAdd.ts";
|
||||||
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 { GUILD } from "../types/endpoint.ts";
|
import { GUILD } from "../types/endpoint.ts";
|
||||||
import { GuildPayload } from "../types/guild.ts";
|
import { GuildPayload, MemberPayload } from "../types/guild.ts";
|
||||||
import { BaseManager } from "./BaseManager.ts";
|
import { BaseManager } from "./BaseManager.ts";
|
||||||
|
import { MembersManager } from "./MembersManager.ts";
|
||||||
|
|
||||||
export class GuildManager extends BaseManager<GuildPayload, Guild> {
|
export class GuildManager extends BaseManager<GuildPayload, Guild> {
|
||||||
constructor(client: Client) {
|
constructor(client: Client) {
|
||||||
|
@ -11,9 +13,15 @@ export class GuildManager extends BaseManager<GuildPayload, Guild> {
|
||||||
|
|
||||||
fetch(id: string) {
|
fetch(id: string) {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
this.client.rest.get(GUILD(id)).then(data => {
|
this.client.rest.get(GUILD(id)).then(async (data: any) => {
|
||||||
this.set(id, data as GuildPayload)
|
this.set(id, data)
|
||||||
res(new Guild(this.client, data as GuildPayload))
|
let guild = new Guild(this.client, data)
|
||||||
|
if((data as GuildPayload).members) {
|
||||||
|
let members = new MembersManager(this.client, guild)
|
||||||
|
await members.fromPayload((data as GuildPayload).members as MemberPayload[])
|
||||||
|
guild.members = members
|
||||||
|
}
|
||||||
|
res(guild)
|
||||||
}).catch(e => rej(e))
|
}).catch(e => rej(e))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
32
src/managers/MembersManager.ts
Normal file
32
src/managers/MembersManager.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { Client } from "../models/client.ts";
|
||||||
|
import { Guild } from "../structures/guild.ts";
|
||||||
|
import { Member } from "../structures/member.ts";
|
||||||
|
import { Role } from "../structures/role.ts";
|
||||||
|
import { GUILD_MEMBER, GUILD_ROLE } from "../types/endpoint.ts";
|
||||||
|
import { MemberPayload } from "../types/guild.ts";
|
||||||
|
import { RolePayload } from "../types/role.ts";
|
||||||
|
import { BaseManager } from "./BaseManager.ts";
|
||||||
|
|
||||||
|
export class MembersManager extends BaseManager<MemberPayload, Member> {
|
||||||
|
guild: Guild
|
||||||
|
|
||||||
|
constructor(client: Client, guild: Guild) {
|
||||||
|
super(client, `g${guild.id}m`, Member)
|
||||||
|
this.guild = guild
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(id: string) {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
this.client.rest.get(GUILD_MEMBER(this.guild.id, id)).then(data => {
|
||||||
|
this.set(id, data as MemberPayload)
|
||||||
|
res(new Member(this.client, data as MemberPayload))
|
||||||
|
}).catch(e => rej(e))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fromPayload(members: MemberPayload[]) {
|
||||||
|
for(const member of members) {
|
||||||
|
await this.set(member.user.id, member)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { Client } from "../models/client.ts";
|
import { Client } from "../models/client.ts";
|
||||||
import { Message } from "../structures/message.ts";
|
import { Message } from "../structures/message.ts";
|
||||||
import { MessageMentions } from "../structures/MessageMentions.ts";
|
import { MessageMentions } from "../structures/MessageMentions.ts";
|
||||||
|
import { TextChannel } from "../structures/textChannel.ts";
|
||||||
import { User } from "../structures/user.ts";
|
import { User } from "../structures/user.ts";
|
||||||
import { MessagePayload } from "../types/channel.ts";
|
import { MessagePayload } from "../types/channel.ts";
|
||||||
import { CHANNEL_MESSAGE } from "../types/endpoint.ts";
|
import { CHANNEL_MESSAGE } from "../types/endpoint.ts";
|
||||||
|
@ -27,8 +28,8 @@ export class MessagesManager extends BaseManager<MessagePayload, Message> {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
this.client.rest.get(CHANNEL_MESSAGE(channelID, id)).then(async data => {
|
this.client.rest.get(CHANNEL_MESSAGE(channelID, id)).then(async data => {
|
||||||
this.set(id, data as MessagePayload)
|
this.set(id, data as MessagePayload)
|
||||||
let channel = await this.client.channels.get(channelID)
|
let channel = await this.client.channels.get<TextChannel>(channelID)
|
||||||
if(!channel) channel = await this.client.channels.fetch(channelID)
|
if(!channel) channel = await this.client.channels.fetch(channelID) as TextChannel
|
||||||
let author = new User(this.client, (data as MessagePayload).author as UserPayload)
|
let author = new User(this.client, (data as MessagePayload).author as UserPayload)
|
||||||
await this.client.users.set(author.id, (data as MessagePayload).author)
|
await this.client.users.set(author.id, (data as MessagePayload).author)
|
||||||
// TODO: Make this thing work (MessageMentions)
|
// TODO: Make this thing work (MessageMentions)
|
||||||
|
|
|
@ -24,7 +24,8 @@ export class RolesManager extends BaseManager<RolePayload, Role> {
|
||||||
|
|
||||||
async fromPayload(roles: RolePayload[]) {
|
async fromPayload(roles: RolePayload[]) {
|
||||||
for(const role of roles) {
|
for(const role of roles) {
|
||||||
await this.guild.roles.set(role.id, role)
|
await this.set(role.id, role)
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,6 +8,7 @@ export interface ICacheAdapter {
|
||||||
set: (cacheName: string, key: string, value: any) => Promise<any> | any
|
set: (cacheName: string, key: string, value: any) => Promise<any> | any
|
||||||
delete: (cacheName: string, key: string) => Promise<boolean> | boolean
|
delete: (cacheName: string, key: string) => Promise<boolean> | boolean
|
||||||
array: (cacheName: string) => void | any[] | Promise<any[] | void>
|
array: (cacheName: string) => void | any[] | Promise<any[] | void>
|
||||||
|
deleteCache: (cacheName: string) => any
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DefaultCacheAdapter implements ICacheAdapter {
|
export class DefaultCacheAdapter implements ICacheAdapter {
|
||||||
|
@ -43,9 +44,13 @@ export class DefaultCacheAdapter implements ICacheAdapter {
|
||||||
|
|
||||||
async array(cacheName: string) {
|
async array(cacheName: string) {
|
||||||
const cache = this.data[cacheName]
|
const cache = this.data[cacheName]
|
||||||
if (!cache) return
|
if (!cache) return []
|
||||||
return cache.array()
|
return cache.array()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteCache(cacheName: string) {
|
||||||
|
return delete this.data[cacheName]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RedisCacheAdapter implements ICacheAdapter {
|
export class RedisCacheAdapter implements ICacheAdapter {
|
||||||
|
@ -95,4 +100,9 @@ export class RedisCacheAdapter implements ICacheAdapter {
|
||||||
let data = await this.redis?.hvals(cacheName)
|
let data = await this.redis?.hvals(cacheName)
|
||||||
return data?.map((e: string) => JSON.parse(e))
|
return data?.map((e: string) => JSON.parse(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteCache(cacheName: string) {
|
||||||
|
await this._checkReady()
|
||||||
|
return await this.redis?.del(cacheName)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -196,7 +196,6 @@ export class RESTManager {
|
||||||
retryCount = 0,
|
retryCount = 0,
|
||||||
bucketID?: string | null,
|
bucketID?: string | null,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
const errorStack = new Error("Location In Your Files:");
|
const errorStack = new Error("Location In Your Files:");
|
||||||
Error.captureStackTrace(errorStack);
|
Error.captureStackTrace(errorStack);
|
||||||
|
|
||||||
|
@ -217,11 +216,12 @@ export class RESTManager {
|
||||||
const urlToUse = method === "get" && query ? `${url}?${query}` : url;
|
const urlToUse = method === "get" && query ? `${url}?${query}` : url;
|
||||||
|
|
||||||
const response = await fetch(urlToUse, this.createRequestBody(body, method));
|
const response = await fetch(urlToUse, this.createRequestBody(body, method));
|
||||||
const bucketIDFromHeaders = this.processHeaders(url, response.headers);
|
const bucketIDFromHeaders = this.processHeaders(url, response.headers);
|
||||||
this.handleStatusCode(response, errorStack);
|
|
||||||
|
// Sometimes Discord returns an empty 204 response that can't be made to JSON.
|
||||||
// Sometimes Discord returns an empty 204 response that can't be made to JSON.
|
|
||||||
if (response.status === 204) return resolve();
|
if (response.status === 204) return resolve();
|
||||||
|
|
||||||
|
this.handleStatusCode(response, errorStack);
|
||||||
|
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
if (
|
if (
|
||||||
|
@ -265,8 +265,8 @@ export class RESTManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleStatusCode(response: Response, errorStack?: unknown) {
|
async handleStatusCode(response: Response, errorStack?: unknown) {
|
||||||
const status = response.status;
|
const status = response.status
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(status >= 200 && status < 400) ||
|
(status >= 200 && status < 400) ||
|
||||||
|
@ -283,9 +283,9 @@ export class RESTManager {
|
||||||
case HttpResponseCode.Forbidden:
|
case HttpResponseCode.Forbidden:
|
||||||
case HttpResponseCode.NotFound:
|
case HttpResponseCode.NotFound:
|
||||||
case HttpResponseCode.MethodNotAllowed:
|
case HttpResponseCode.MethodNotAllowed:
|
||||||
throw new Error("Request Client Error");
|
throw new Error("Request Client Error. Code: " + status);
|
||||||
case HttpResponseCode.GatewayUnavailable:
|
case HttpResponseCode.GatewayUnavailable:
|
||||||
throw new Error("Request Server Error");
|
throw new Error("Request Server Error. Code: " + status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// left are all unknown
|
// left are all unknown
|
||||||
|
@ -321,7 +321,6 @@ export class RESTManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no remaining global limit, we save it in cache
|
|
||||||
if (global) {
|
if (global) {
|
||||||
const reset = Date.now() + Number(retryAfter);
|
const reset = Date.now() + Number(retryAfter);
|
||||||
this.globallyRateLimited = true;
|
this.globallyRateLimited = true;
|
||||||
|
|
|
@ -10,7 +10,6 @@ export class DMChannel extends TextChannel {
|
||||||
constructor (client: Client, data: DMChannelPayload) {
|
constructor (client: Client, data: DMChannelPayload) {
|
||||||
super(client, data)
|
super(client, data)
|
||||||
this.recipients = data.recipients
|
this.recipients = data.recipients
|
||||||
// cache.set('dmchannel', this.id, this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readFromData (data: DMChannelPayload): void {
|
protected readFromData (data: DMChannelPayload): void {
|
||||||
|
|
|
@ -10,6 +10,9 @@ import cache from '../models/cache.ts'
|
||||||
import getChannelByType from '../utils/getChannelByType.ts'
|
import getChannelByType from '../utils/getChannelByType.ts'
|
||||||
import { RolesManager } from "../managers/RolesManager.ts"
|
import { RolesManager } from "../managers/RolesManager.ts"
|
||||||
import { Role } from "./role.ts"
|
import { Role } from "./role.ts"
|
||||||
|
import { GuildChannelsManager } from "../managers/GuildChannelsManager.ts"
|
||||||
|
import { MembersManager } from "../managers/MembersManager.ts"
|
||||||
|
import { ChannelsManager } from "../managers/ChannelsManager.ts"
|
||||||
|
|
||||||
export class Guild extends Base {
|
export class Guild extends Base {
|
||||||
id: string
|
id: string
|
||||||
|
@ -29,7 +32,7 @@ export class Guild extends Base {
|
||||||
verificationLevel?: string
|
verificationLevel?: string
|
||||||
defaultMessageNotifications?: string
|
defaultMessageNotifications?: string
|
||||||
explicitContentFilter?: string
|
explicitContentFilter?: string
|
||||||
roles: RolesManager = new RolesManager(this.client, this)
|
roles: RolesManager
|
||||||
emojis?: Emoji[]
|
emojis?: Emoji[]
|
||||||
features?: GuildFeatures[]
|
features?: GuildFeatures[]
|
||||||
mfaLevel?: string
|
mfaLevel?: string
|
||||||
|
@ -42,8 +45,8 @@ export class Guild extends Base {
|
||||||
unavailable: boolean
|
unavailable: boolean
|
||||||
memberCount?: number
|
memberCount?: number
|
||||||
voiceStates?: VoiceState[]
|
voiceStates?: VoiceState[]
|
||||||
members?: Member[]
|
members: MembersManager
|
||||||
channels?: Channel[]
|
channels: GuildChannelsManager
|
||||||
presences?: PresenceUpdatePayload[]
|
presences?: PresenceUpdatePayload[]
|
||||||
maxPresences?: number
|
maxPresences?: number
|
||||||
maxMembers?: number
|
maxMembers?: number
|
||||||
|
@ -62,6 +65,9 @@ export class Guild extends Base {
|
||||||
super(client, data)
|
super(client, data)
|
||||||
this.id = data.id
|
this.id = data.id
|
||||||
this.unavailable = data.unavailable
|
this.unavailable = data.unavailable
|
||||||
|
this.members = new MembersManager(this.client, this)
|
||||||
|
this.channels = new GuildChannelsManager(this.client, this.client.channels, this)
|
||||||
|
this.roles = new RolesManager(this.client, this)
|
||||||
|
|
||||||
if (!this.unavailable) {
|
if (!this.unavailable) {
|
||||||
this.name = data.name
|
this.name = data.name
|
||||||
|
|
|
@ -18,14 +18,17 @@ import cache from '../models/cache.ts'
|
||||||
import { Channel } from "./channel.ts"
|
import { Channel } from "./channel.ts"
|
||||||
import { MessageMentions } from "./MessageMentions.ts"
|
import { MessageMentions } from "./MessageMentions.ts"
|
||||||
import { TextChannel } from "./textChannel.ts"
|
import { TextChannel } from "./textChannel.ts"
|
||||||
|
import { DMChannel } from "./dmChannel.ts"
|
||||||
|
import { Guild } from "./guild.ts"
|
||||||
|
|
||||||
export class Message extends Base {
|
export class Message extends Base {
|
||||||
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
||||||
private data: MessagePayload
|
private data: MessagePayload
|
||||||
id: string
|
id: string
|
||||||
channelID: string
|
channelID: string
|
||||||
channel: Channel
|
channel: TextChannel
|
||||||
guildID?: string
|
guildID?: string
|
||||||
|
guild?: Guild
|
||||||
author: User
|
author: User
|
||||||
member?: Member
|
member?: Member
|
||||||
content: string
|
content: string
|
||||||
|
@ -48,7 +51,7 @@ export class Message extends Base {
|
||||||
messageReference?: MessageReference
|
messageReference?: MessageReference
|
||||||
flags?: number
|
flags?: number
|
||||||
|
|
||||||
constructor (client: Client, data: MessagePayload, channel: Channel, author: User, mentions: MessageMentions) {
|
constructor (client: Client, data: MessagePayload, channel: TextChannel, author: User, mentions: MessageMentions) {
|
||||||
super(client)
|
super(client)
|
||||||
this.data = data
|
this.data = data
|
||||||
this.id = data.id
|
this.id = data.id
|
||||||
|
@ -117,7 +120,13 @@ export class Message extends Base {
|
||||||
}
|
}
|
||||||
|
|
||||||
edit (text?: string, option?: MessageOption): Promise<Message> {
|
edit (text?: string, option?: MessageOption): Promise<Message> {
|
||||||
return (this.channel as TextChannel).editMessage(this.id, text, option)
|
return (this.channel as TextChannel).edit(this.id, text, option)
|
||||||
|
}
|
||||||
|
|
||||||
|
reply(text: string, options?: MessageOption) {
|
||||||
|
// TODO: Use inline replies once they're out
|
||||||
|
if(this.channel instanceof DMChannel) return this.channel.send(text, options)
|
||||||
|
return this.channel.send(`${this.author.mention}, ${text}`, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete (): Promise<void> {
|
delete (): Promise<void> {
|
||||||
|
|
|
@ -29,25 +29,18 @@ export class TextChannel extends Channel {
|
||||||
if (text !== undefined && option !== undefined) {
|
if (text !== undefined && option !== undefined) {
|
||||||
throw new Error('Either text or option is necessary.')
|
throw new Error('Either text or option is necessary.')
|
||||||
}
|
}
|
||||||
const resp = await fetch(CHANNEL_MESSAGES(this.id), {
|
const resp = await this.client.rest.post(CHANNEL_MESSAGES(this.id), {
|
||||||
headers: {
|
|
||||||
Authorization: `Bot ${this.client.token}`,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
content: text,
|
content: text,
|
||||||
embed: option?.embed,
|
embed: option?.embed,
|
||||||
file: option?.file,
|
file: option?.file,
|
||||||
tts: option?.tts,
|
tts: option?.tts,
|
||||||
allowed_mentions: option?.allowedMention
|
allowed_mentions: option?.allowedMention
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return new Message(this.client, await resp.json(), this, this.client.user as User, new MessageMentions())
|
return new Message(this.client, resp as any, this, this.client.user as User, new MessageMentions())
|
||||||
}
|
}
|
||||||
|
|
||||||
async editMessage (
|
async edit (
|
||||||
message: Message | string,
|
message: Message | string,
|
||||||
text?: string,
|
text?: string,
|
||||||
option?: MessageOption
|
option?: MessageOption
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
import { Client } from '../models/client.ts'
|
import { Client } from '../models/client.ts'
|
||||||
import { GatewayIntents } from '../types/gateway.ts'
|
import { GatewayIntents } from '../types/gateway.ts'
|
||||||
import { TOKEN } from './config.ts'
|
import { TOKEN } from './config.ts'
|
||||||
import { Channel } from '../structures/channel.ts'
|
|
||||||
import { GuildTextChannel } from '../structures/guildTextChannel.ts'
|
|
||||||
import { TextChannel } from '../structures/textChannel.ts'
|
|
||||||
import { Guild } from '../structures/guild.ts'
|
|
||||||
import { User } from '../structures/user.ts'
|
|
||||||
import { Message } from "../structures/message.ts"
|
import { Message } from "../structures/message.ts"
|
||||||
import { RedisCacheAdapter } from "../models/CacheAdapter.ts"
|
import { RedisCacheAdapter } from "../models/CacheAdapter.ts"
|
||||||
import { ClientPresence } from "../structures/presence.ts"
|
import { ClientPresence } from "../structures/presence.ts"
|
||||||
|
@ -20,10 +15,10 @@ const bot = new Client({
|
||||||
forceNewSession: true
|
forceNewSession: true
|
||||||
})
|
})
|
||||||
|
|
||||||
bot.setAdapter(new RedisCacheAdapter(bot, {
|
// bot.setAdapter(new RedisCacheAdapter(bot, {
|
||||||
hostname: "127.0.0.1",
|
// hostname: "127.0.0.1",
|
||||||
port: 6379
|
// port: 6379
|
||||||
}))
|
// }))
|
||||||
|
|
||||||
bot.on('ready', () => {
|
bot.on('ready', () => {
|
||||||
console.log(`[Login] Logged in as ${bot.user?.tag}!`)
|
console.log(`[Login] Logged in as ${bot.user?.tag}!`)
|
||||||
|
@ -35,56 +30,37 @@ bot.on('ready', () => {
|
||||||
|
|
||||||
bot.on('debug', console.log)
|
bot.on('debug', console.log)
|
||||||
|
|
||||||
bot.on('channelDelete', (channel: Channel) => {
|
bot.on('messageCreate', async (msg: Message) => {
|
||||||
console.log('channelDelete', channel.id)
|
if (msg.author.bot) return
|
||||||
})
|
console.log(`${msg.author.tag} (${msg.channel + ""}): ${msg.content}`)
|
||||||
|
if (msg.content == "!ping") {
|
||||||
bot.on('channelUpdate', (before: Channel, after: Channel) => {
|
msg.reply("Pong! API Ping: " + bot.ping + "ms")
|
||||||
if (before instanceof GuildTextChannel && after instanceof GuildTextChannel) {
|
} else if (msg.content == "!members") {
|
||||||
console.log('channelUpdate', before.name)
|
let col = await msg.guild?.members.collection()
|
||||||
console.log('channelUpdate', after.name)
|
let data = col?.array().map((c, i) => {
|
||||||
} else {
|
return `${i + 1}. ${c.user.tag}`
|
||||||
console.log('channelUpdate', before.id)
|
}).join("\n")
|
||||||
console.log('channelUpdate', after.id)
|
msg.channel.send("Member List:\n" + data)
|
||||||
|
} else if (msg.content == "!guilds") {
|
||||||
|
let guilds = await msg.client.guilds.collection()
|
||||||
|
msg.channel.send("Guild List:\n" + guilds.array().map((c, i) => {
|
||||||
|
return `${i + 1}. ${c.name} - ${c.memberCount} members`
|
||||||
|
}).join("\n"))
|
||||||
|
} else if (msg.content == "!roles") {
|
||||||
|
let col = await msg.guild?.roles.collection()
|
||||||
|
let data = col?.array().map((c, i) => {
|
||||||
|
return `${i + 1}. ${c.name}`
|
||||||
|
}).join("\n")
|
||||||
|
msg.channel.send("Roles List:\n" + data)
|
||||||
|
} else if (msg.content == "!channels") {
|
||||||
|
let col = await msg.guild?.channels.array()
|
||||||
|
let data = col?.map((c, i) => {
|
||||||
|
return `${i + 1}. ${c.name}`
|
||||||
|
}).join("\n")
|
||||||
|
msg.channel.send("Channels List:\n" + data)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
bot.on('channelCreate', (channel: Channel) => {
|
|
||||||
console.log('channelCreate', channel.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('channelPinsUpdate', (before: TextChannel, after: TextChannel) => {
|
|
||||||
console.log(
|
|
||||||
'channelPinsUpdate',
|
|
||||||
before.lastPinTimestamp,
|
|
||||||
after.lastPinTimestamp
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('guildBanAdd', (guild: Guild, user: User) => {
|
|
||||||
console.log('guildBanAdd', guild.id, user.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('guildBanRemove', (guild: Guild, user: User) => {
|
|
||||||
console.log('guildBanRemove', guild.id, user.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('guildCreate', (guild: Guild) => {
|
|
||||||
console.log('guildCreate', guild.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('guildDelete', (guild: Guild) => {
|
|
||||||
console.log('guildDelete', guild.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('guildUpdate', (before: Guild, after: Guild) => {
|
|
||||||
console.log('guildUpdate', before.name, after.name)
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('messageCreate', (msg: Message) => {
|
|
||||||
console.log(`${msg.author.tag}: ${msg.content}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.connect(TOKEN, [
|
bot.connect(TOKEN, [
|
||||||
GatewayIntents.GUILD_MEMBERS,
|
GatewayIntents.GUILD_MEMBERS,
|
||||||
GatewayIntents.GUILD_PRESENCES,
|
GatewayIntents.GUILD_PRESENCES,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue