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