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, | ||||
|   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) { | ||||
|     await gateway.client.channels.delete(d.id) | ||||
|     gateway.client.emit('channelDelete', channel) | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ export const channelPinsUpdate: GatewayEventHandler = async( | |||
|   gateway: Gateway, | ||||
|   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) { | ||||
|     const before = after.refreshFromData({ | ||||
|       last_pin_timestamp: d.last_pin_timestamp | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ export const channelUpdate: GatewayEventHandler = async ( | |||
|   gateway: Gateway, | ||||
|   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) { | ||||
|     await gateway.client.channels.set(d.id, d) | ||||
|  |  | |||
|  | @ -1,16 +1,51 @@ | |||
| import { Gateway, GatewayEventHandler } from '../index.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) => { | ||||
|   let guild: Guild | void = await gateway.client.guilds.get(d.id) | ||||
|   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
 | ||||
|     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) | ||||
|   } else { | ||||
|     await gateway.client.guilds.set(d.id, d) | ||||
|     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) | ||||
|     gateway.client.emit('guildCreate', guild) | ||||
|   } | ||||
|  |  | |||
|  | @ -6,6 +6,9 @@ export const guildDelte: GatewayEventHandler = async (gateway: Gateway, d: any) | |||
| 
 | ||||
|   if (guild !== undefined) { | ||||
|     guild.refreshFromData(d) | ||||
|     await guild.members.flush() | ||||
|     await guild.channels.flush() | ||||
|     await guild.roles.flush() | ||||
|     await gateway.client.guilds.delete(d.id) | ||||
|     gateway.client.emit('guildDelete', guild) | ||||
|   } | ||||
|  |  | |||
|  | @ -10,12 +10,17 @@ export const messageCreate: GatewayEventHandler = async( | |||
|   gateway: Gateway, | ||||
|   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
 | ||||
|   if(!channel) channel = (await gateway.client.channels.fetch(d.channel_id) as any) as TextChannel | ||||
|   let user = new User(gateway.client, 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 message = new Message(gateway.client, d, channel, user, mentions) | ||||
|   if(guild) message.guild = guild | ||||
|   gateway.client.emit('messageCreate', message) | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| import { Client } from "../models/client.ts"; | ||||
| import { Collection } from "../utils/collection.ts"; | ||||
| import { BaseManager } from "./BaseManager.ts"; | ||||
| 
 | ||||
| export class BaseChildManager<T, T2> { | ||||
|  | @ -21,4 +22,19 @@ export class BaseChildManager<T, T2> { | |||
|   async delete(key: string): Promise<any> { | ||||
|     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) | ||||
|   } | ||||
| 
 | ||||
|   array(): Promise<void | T2[]> { | ||||
|     return (this.client.cache.array(this.cacheName) as T[]).map(e => new this.dataType(this.client, e)) as any | ||||
|   async array(): Promise<void | T2[]> { | ||||
|     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>> { | ||||
|  | @ -44,4 +45,8 @@ export class BaseManager<T, T2> { | |||
|     } | ||||
|     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 { ChannelPayload } from "../types/channel.ts"; | ||||
| import { CHANNEL } from "../types/endpoint.ts"; | ||||
| import getChannelByType from "../utils/getChannelByType.ts"; | ||||
| import { BaseManager } from "./BaseManager.ts"; | ||||
| 
 | ||||
| export class ChannelsManager extends BaseManager<ChannelPayload, Channel> { | ||||
|   constructor(client: Client) { | ||||
|     super(client, "channels", User) | ||||
|     super(client, "channels", Channel) | ||||
|   } | ||||
| 
 | ||||
|   // Override get method as Generic
 | ||||
|   async get<T = Channel>(key: string): Promise<T> { | ||||
|     return new this.dataType(this.client, this._get(key)) as any | ||||
|   async get<T = Channel>(key: string): Promise<T | void> { | ||||
|     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> { | ||||
|     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) | ||||
|         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)) | ||||
|     }) | ||||
|   } | ||||
|  |  | |||
|  | @ -18,7 +18,6 @@ export class GatewayCache { | |||
|     } | ||||
| 
 | ||||
|     delete(key: string) { | ||||
|         console.log(`[GatewayCache] DEL ${key}`) | ||||
|         return this.client.cache.delete(this.cacheName, key) | ||||
|     } | ||||
| } | ||||
|  | @ -1,4 +1,5 @@ | |||
| import { Client } from "../models/client.ts"; | ||||
| import { Channel } from "../structures/channel.ts"; | ||||
| import { Guild } from "../structures/guild.ts"; | ||||
| import { CategoryChannel } from "../structures/guildCategoryChannel.ts"; | ||||
| import { GuildTextChannel } from "../structures/guildTextChannel.ts"; | ||||
|  | @ -7,6 +8,7 @@ import { GuildChannelCategoryPayload, GuildTextChannelPayload, GuildVoiceChannel | |||
| import { CHANNEL } from "../types/endpoint.ts"; | ||||
| import { BaseChildManager } from "./BaseChildManager.ts"; | ||||
| import { BaseManager } from "./BaseManager.ts"; | ||||
| import { ChannelsManager } from "./ChannelsManager.ts"; | ||||
| 
 | ||||
| export type GuildChannelPayload = GuildTextChannelPayload | GuildVoiceChannelPayload | GuildChannelCategoryPayload | ||||
| export type GuildChannel = GuildTextChannel | VoiceChannel | CategoryChannel | ||||
|  | @ -14,8 +16,8 @@ export type GuildChannel = GuildTextChannel | VoiceChannel | CategoryChannel | |||
| export class GuildChannelsManager extends BaseChildManager<GuildChannelPayload, GuildChannel> { | ||||
|   guild: Guild | ||||
| 
 | ||||
|   constructor(client: Client, parent: BaseManager<GuildChannelPayload, GuildChannel>, guild: Guild) { | ||||
|     super(client, parent) | ||||
|   constructor(client: Client, parent: ChannelsManager, guild: Guild) { | ||||
|     super(client, parent as any) | ||||
|     this.guild = guild | ||||
|   } | ||||
| 
 | ||||
|  | @ -28,4 +30,17 @@ export class GuildChannelsManager extends BaseChildManager<GuildChannelPayload, | |||
|   delete(id: string) { | ||||
|     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 { Guild } from "../structures/guild.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 { MembersManager } from "./MembersManager.ts"; | ||||
| 
 | ||||
| export class GuildManager extends BaseManager<GuildPayload, Guild> { | ||||
|   constructor(client: Client) { | ||||
|  | @ -11,9 +13,15 @@ export class GuildManager extends BaseManager<GuildPayload, Guild> { | |||
| 
 | ||||
|   fetch(id: string) { | ||||
|     return new Promise((res, rej) => { | ||||
|       this.client.rest.get(GUILD(id)).then(data => { | ||||
|         this.set(id, data as GuildPayload) | ||||
|         res(new Guild(this.client, data as GuildPayload)) | ||||
|       this.client.rest.get(GUILD(id)).then(async (data: any) => { | ||||
|         this.set(id, data) | ||||
|         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)) | ||||
|     }) | ||||
|   } | ||||
|  |  | |||
							
								
								
									
										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 { Message } from "../structures/message.ts"; | ||||
| import { MessageMentions } from "../structures/MessageMentions.ts"; | ||||
| import { TextChannel } from "../structures/textChannel.ts"; | ||||
| import { User } from "../structures/user.ts"; | ||||
| import { MessagePayload } from "../types/channel.ts"; | ||||
| import { CHANNEL_MESSAGE } from "../types/endpoint.ts"; | ||||
|  | @ -27,8 +28,8 @@ export class MessagesManager extends BaseManager<MessagePayload, Message> { | |||
|     return new Promise((res, rej) => { | ||||
|       this.client.rest.get(CHANNEL_MESSAGE(channelID, id)).then(async data => { | ||||
|         this.set(id, data as MessagePayload) | ||||
|         let channel = await this.client.channels.get(channelID) | ||||
|         if(!channel) channel = await this.client.channels.fetch(channelID) | ||||
|         let channel = await this.client.channels.get<TextChannel>(channelID) | ||||
|         if(!channel) channel = await this.client.channels.fetch(channelID) as TextChannel | ||||
|         let author = new User(this.client, (data as MessagePayload).author as UserPayload) | ||||
|         await this.client.users.set(author.id, (data as MessagePayload).author) | ||||
|         // TODO: Make this thing work (MessageMentions)
 | ||||
|  |  | |||
|  | @ -24,7 +24,8 @@ export class RolesManager extends BaseManager<RolePayload, Role> { | |||
| 
 | ||||
|   async fromPayload(roles: RolePayload[]) { | ||||
|     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 | ||||
|   delete: (cacheName: string, key: string) => Promise<boolean> | boolean | ||||
|   array: (cacheName: string) => void | any[] | Promise<any[] | void> | ||||
|   deleteCache: (cacheName: string) => any | ||||
| } | ||||
| 
 | ||||
| export class DefaultCacheAdapter implements ICacheAdapter { | ||||
|  | @ -43,9 +44,13 @@ export class DefaultCacheAdapter implements ICacheAdapter { | |||
| 
 | ||||
|   async array(cacheName: string) { | ||||
|     const cache = this.data[cacheName] | ||||
|     if (!cache) return | ||||
|     if (!cache) return [] | ||||
|     return cache.array() | ||||
|   } | ||||
| 
 | ||||
|   async deleteCache(cacheName: string) { | ||||
|     return delete this.data[cacheName] | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class RedisCacheAdapter implements ICacheAdapter { | ||||
|  | @ -95,4 +100,9 @@ export class RedisCacheAdapter implements ICacheAdapter { | |||
|     let data = await this.redis?.hvals(cacheName) | ||||
|     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, | ||||
| 		bucketID?: string | null, | ||||
| 	) { | ||||
| 	 | ||||
| 		const errorStack = new Error("Location In Your Files:"); | ||||
| 		Error.captureStackTrace(errorStack); | ||||
| 	 | ||||
|  | @ -218,11 +217,12 @@ export class RESTManager { | |||
| 
 | ||||
| 					const response = await fetch(urlToUse, this.createRequestBody(body, method)); | ||||
|           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.
 | ||||
| 					if (response.status === 204) return resolve(); | ||||
| 
 | ||||
| 					this.handleStatusCode(response, errorStack); | ||||
| 	 | ||||
| 					const json = await response.json(); | ||||
| 					if ( | ||||
| 						json.retry_after || | ||||
|  | @ -265,8 +265,8 @@ export class RESTManager { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	handleStatusCode(response: Response, errorStack?: unknown) { | ||||
| 		const status = response.status; | ||||
| 	async handleStatusCode(response: Response, errorStack?: unknown) { | ||||
|     const status = response.status | ||||
| 	 | ||||
| 		if ( | ||||
| 			(status >= 200 && status < 400) || | ||||
|  | @ -283,9 +283,9 @@ export class RESTManager { | |||
| 			case HttpResponseCode.Forbidden: | ||||
| 			case HttpResponseCode.NotFound: | ||||
| 			case HttpResponseCode.MethodNotAllowed: | ||||
| 				throw new Error("Request Client Error"); | ||||
| 				throw new Error("Request Client Error. Code: " + status); | ||||
| 			case HttpResponseCode.GatewayUnavailable: | ||||
| 				throw new Error("Request Server Error"); | ||||
| 				throw new Error("Request Server Error. Code: " + status); | ||||
| 		} | ||||
| 	 | ||||
| 		// 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) { | ||||
| 			const reset = Date.now() + Number(retryAfter); | ||||
| 			this.globallyRateLimited = true; | ||||
|  |  | |||
|  | @ -10,7 +10,6 @@ export class DMChannel extends TextChannel { | |||
|   constructor (client: Client, data: DMChannelPayload) { | ||||
|     super(client, data) | ||||
|     this.recipients = data.recipients | ||||
|     // cache.set('dmchannel', this.id, this)
 | ||||
|   } | ||||
| 
 | ||||
|   protected readFromData (data: DMChannelPayload): void { | ||||
|  |  | |||
|  | @ -10,6 +10,9 @@ import cache from '../models/cache.ts' | |||
| import getChannelByType from '../utils/getChannelByType.ts' | ||||
| import { RolesManager } from "../managers/RolesManager.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 { | ||||
|   id: string | ||||
|  | @ -29,7 +32,7 @@ export class Guild extends Base { | |||
|   verificationLevel?: string | ||||
|   defaultMessageNotifications?: string | ||||
|   explicitContentFilter?: string | ||||
|   roles: RolesManager = new RolesManager(this.client, this) | ||||
|   roles: RolesManager | ||||
|   emojis?: Emoji[] | ||||
|   features?: GuildFeatures[] | ||||
|   mfaLevel?: string | ||||
|  | @ -42,8 +45,8 @@ export class Guild extends Base { | |||
|   unavailable: boolean | ||||
|   memberCount?: number | ||||
|   voiceStates?: VoiceState[] | ||||
|   members?: Member[] | ||||
|   channels?: Channel[] | ||||
|   members: MembersManager  | ||||
|   channels: GuildChannelsManager | ||||
|   presences?: PresenceUpdatePayload[] | ||||
|   maxPresences?: number | ||||
|   maxMembers?: number | ||||
|  | @ -62,6 +65,9 @@ export class Guild extends Base { | |||
|     super(client, data) | ||||
|     this.id = data.id | ||||
|     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) { | ||||
|       this.name = data.name | ||||
|  |  | |||
|  | @ -18,14 +18,17 @@ import cache from '../models/cache.ts' | |||
| import { Channel } from "./channel.ts" | ||||
| import { MessageMentions } from "./MessageMentions.ts" | ||||
| import { TextChannel } from "./textChannel.ts" | ||||
| import { DMChannel } from "./dmChannel.ts" | ||||
| import { Guild } from "./guild.ts" | ||||
| 
 | ||||
| export class Message extends Base { | ||||
|   // eslint-disable-next-line @typescript-eslint/prefer-readonly
 | ||||
|   private data: MessagePayload | ||||
|   id: string | ||||
|   channelID: string | ||||
|   channel: Channel | ||||
|   channel: TextChannel | ||||
|   guildID?: string | ||||
|   guild?: Guild | ||||
|   author: User | ||||
|   member?: Member | ||||
|   content: string | ||||
|  | @ -48,7 +51,7 @@ export class Message extends Base { | |||
|   messageReference?: MessageReference | ||||
|   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) | ||||
|     this.data = data | ||||
|     this.id = data.id | ||||
|  | @ -117,7 +120,13 @@ export class Message extends Base { | |||
|   } | ||||
| 
 | ||||
|   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> { | ||||
|  |  | |||
|  | @ -29,25 +29,18 @@ export class TextChannel extends Channel { | |||
|     if (text !== undefined && option !== undefined) { | ||||
|       throw new Error('Either text or option is necessary.') | ||||
|     } | ||||
|     const resp = await fetch(CHANNEL_MESSAGES(this.id), { | ||||
|       headers: { | ||||
|         Authorization: `Bot ${this.client.token}`, | ||||
|         'Content-Type': 'application/json' | ||||
|       }, | ||||
|       method: 'POST', | ||||
|       body: JSON.stringify({ | ||||
|     const resp = await this.client.rest.post(CHANNEL_MESSAGES(this.id), { | ||||
|         content: text, | ||||
|         embed: option?.embed, | ||||
|         file: option?.file, | ||||
|         tts: option?.tts, | ||||
|         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, | ||||
|     text?: string, | ||||
|     option?: MessageOption | ||||
|  |  | |||
|  | @ -1,11 +1,6 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { GatewayIntents } from '../types/gateway.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 { RedisCacheAdapter } from "../models/CacheAdapter.ts" | ||||
| import { ClientPresence } from "../structures/presence.ts" | ||||
|  | @ -20,10 +15,10 @@ const bot = new Client({ | |||
|   forceNewSession: true | ||||
| }) | ||||
| 
 | ||||
| bot.setAdapter(new RedisCacheAdapter(bot, { | ||||
|   hostname: "127.0.0.1", | ||||
|   port: 6379 | ||||
| })) | ||||
| // bot.setAdapter(new RedisCacheAdapter(bot, {
 | ||||
| //   hostname: "127.0.0.1",
 | ||||
| //   port: 6379
 | ||||
| // }))
 | ||||
| 
 | ||||
| bot.on('ready', () => { | ||||
|   console.log(`[Login] Logged in as ${bot.user?.tag}!`) | ||||
|  | @ -35,56 +30,37 @@ bot.on('ready', () => { | |||
| 
 | ||||
| bot.on('debug', console.log) | ||||
| 
 | ||||
| bot.on('channelDelete', (channel: Channel) => { | ||||
|   console.log('channelDelete', channel.id) | ||||
| }) | ||||
| 
 | ||||
| bot.on('channelUpdate', (before: Channel, after: Channel) => { | ||||
|   if (before instanceof GuildTextChannel && after instanceof GuildTextChannel) { | ||||
|     console.log('channelUpdate', before.name) | ||||
|     console.log('channelUpdate', after.name) | ||||
|   } else { | ||||
|     console.log('channelUpdate', before.id) | ||||
|     console.log('channelUpdate', after.id) | ||||
| bot.on('messageCreate', async (msg: Message) => { | ||||
|   if (msg.author.bot) return | ||||
|   console.log(`${msg.author.tag} (${msg.channel + ""}): ${msg.content}`) | ||||
|   if (msg.content == "!ping") { | ||||
|     msg.reply("Pong! API Ping: " + bot.ping + "ms") | ||||
|   } else if (msg.content == "!members") { | ||||
|     let col = await msg.guild?.members.collection() | ||||
|     let data = col?.array().map((c, i) => { | ||||
|       return `${i + 1}. ${c.user.tag}` | ||||
|     }).join("\n") | ||||
|     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, [ | ||||
|   GatewayIntents.GUILD_MEMBERS, | ||||
|   GatewayIntents.GUILD_PRESENCES, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue