Fixed Member Caching, Message#member, Member#roles
This commit is contained in:
parent
71c1499c1d
commit
70824135a7
13 changed files with 103 additions and 85 deletions
|
@ -1,16 +1,15 @@
|
|||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import cache from '../../models/cache.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { User } from '../../structures/user.ts'
|
||||
import { GuildBanRemovePayload } from '../../types/gateway.ts'
|
||||
|
||||
export const guildBanRemove: GatewayEventHandler = (
|
||||
export const guildBanRemove: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: GuildBanRemovePayload
|
||||
) => {
|
||||
const guild: Guild = cache.get('guild', d.guild_id)
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
const user: User =
|
||||
cache.get('user', d.user.id) ?? new User(gateway.client, d.user)
|
||||
await gateway.client.users.get(d.user.id) ?? new User(gateway.client, d.user)
|
||||
|
||||
if (guild !== undefined) {
|
||||
gateway.client.emit('guildBanRemove', guild, user)
|
||||
|
|
|
@ -17,11 +17,26 @@ export const messageCreate: GatewayEventHandler = async (
|
|||
const user = new User(gateway.client, d.author)
|
||||
await gateway.client.users.set(d.author.id, d.author)
|
||||
let guild
|
||||
let member
|
||||
if (d.guild_id !== undefined) {
|
||||
guild = await gateway.client.guilds.get(d.guild_id)
|
||||
}
|
||||
if (guild !== undefined && d.member !== undefined) {
|
||||
d.member.user = d.author
|
||||
await guild.members.set(d.author.id, d.member)
|
||||
member = await guild.members.get(d.author.id)
|
||||
}
|
||||
const mentions = new MessageMentions()
|
||||
const message = new Message(gateway.client, d, channel as any, user, mentions)
|
||||
message.member = member
|
||||
if (guild !== undefined) message.guild = guild
|
||||
if (message.member !== undefined) {
|
||||
if(message.member.user === undefined) {
|
||||
const user = await gateway.client.users.get(message.member.id)
|
||||
if(user !== undefined) {
|
||||
message.member.user = user
|
||||
}
|
||||
}
|
||||
}
|
||||
gateway.client.emit('messageCreate', message)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ import { Collection } from "../utils/collection.ts";
|
|||
|
||||
export class BaseManager<T, T2> {
|
||||
client: Client
|
||||
/** Cache Name or Key used to differentiate caches */
|
||||
cacheName: string
|
||||
/** Which data type does this cache have */
|
||||
DataType: any
|
||||
|
||||
constructor (client: Client, cacheName: string, DataType: any) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { User } from "../structures/user.ts";
|
||||
import { Client } from "../models/client.ts";
|
||||
import { Guild } from "../structures/guild.ts";
|
||||
import { Member } from "../structures/member.ts";
|
||||
|
@ -13,11 +14,29 @@ export class MembersManager extends BaseManager<MemberPayload, Member> {
|
|||
this.guild = guild
|
||||
}
|
||||
|
||||
async get (key: string): Promise<Member | undefined> {
|
||||
const raw = await this._get(key)
|
||||
if (raw === undefined) return
|
||||
const user = new User(this.client, raw.user)
|
||||
const res = new this.DataType(this.client, raw, user)
|
||||
for (const roleid of res.roleIDs as string[]) {
|
||||
const role = await this.guild.roles.get(roleid)
|
||||
if(role !== undefined) res.roles.push(role)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
async fetch(id: string): Promise<Member> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
this.client.rest.get(GUILD_MEMBER(this.guild.id, id)).then(data => {
|
||||
this.set(id, data as MemberPayload)
|
||||
resolve(new Member(this.client, data as MemberPayload))
|
||||
this.client.rest.get(GUILD_MEMBER(this.guild.id, id)).then(async data => {
|
||||
await this.set(id, data as MemberPayload)
|
||||
const user: User = new User(this.client, data.user)
|
||||
const res = new Member(this.client, data as MemberPayload, user)
|
||||
for (const roleid of res.roleIDs as string[]) {
|
||||
const role = await this.guild.roles.get(roleid)
|
||||
if(role !== undefined) res.roles.push(role)
|
||||
}
|
||||
resolve(res)
|
||||
}).catch(e => reject(e))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
let caches: any = {}
|
||||
|
||||
const get = (cacheName: string, key: string): any => {
|
||||
const gotCache: Map<string, any> = caches[cacheName]
|
||||
if (gotCache === undefined || !(gotCache instanceof Map)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const gotMap = gotCache.get(key)
|
||||
return gotMap
|
||||
}
|
||||
|
||||
const set = (cacheName: string, key: string, value: any): any => {
|
||||
let gotCache: Map<string, any> = caches[cacheName]
|
||||
if (gotCache === undefined || !(gotCache instanceof Map)) {
|
||||
gotCache = caches[cacheName] = new Map<string, any>()
|
||||
}
|
||||
|
||||
gotCache.set(key, value)
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
const del = (cacheName: string, key: string): boolean | undefined => {
|
||||
const gotCache: Map<string, any> = caches[cacheName]
|
||||
if (gotCache === undefined || !(gotCache instanceof Map)) {
|
||||
return
|
||||
}
|
||||
|
||||
return gotCache.delete(key)
|
||||
}
|
||||
|
||||
const deleteCache = (cacheName: string): void => {
|
||||
const gotCache = caches[cacheName]
|
||||
if (gotCache === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete caches[cacheName]
|
||||
}
|
||||
|
||||
const resetCaches = (): void => {
|
||||
caches = {}
|
||||
}
|
||||
|
||||
export default { get, set, del, deleteCache, resetCaches }
|
||||
export { get, set, del, deleteCache, resetCaches }
|
|
@ -13,12 +13,19 @@ import { ActivityGame, ClientActivity, ClientPresence } from "../structures/pres
|
|||
|
||||
/** Some Client Options to modify behaviour */
|
||||
export interface ClientOptions {
|
||||
/** Token of the Bot/User */
|
||||
token?: string
|
||||
/** Gateway Intents */
|
||||
intents?: GatewayIntents[]
|
||||
/** Cache Adapter to use, defaults to Collections one */
|
||||
cache?: ICacheAdapter,
|
||||
/** Force New Session and don't use cached Session (by persistent caching) */
|
||||
forceNewSession?: boolean,
|
||||
/** Startup presence of client */
|
||||
presence?: ClientPresence | ClientActivity | ActivityGame
|
||||
/** Whether it's a bot user or not? Use this if selfbot! */
|
||||
bot?: boolean
|
||||
/** Force all requests to Canary API */
|
||||
canary?: boolean
|
||||
}
|
||||
|
||||
|
@ -26,22 +33,34 @@ export interface ClientOptions {
|
|||
* Discord Client.
|
||||
*/
|
||||
export class Client extends EventEmitter {
|
||||
/** Gateway object */
|
||||
gateway?: Gateway
|
||||
/** REST Manager - used to make all requests */
|
||||
rest: RESTManager = new RESTManager(this)
|
||||
/** User which Client logs in to, undefined until logs in */
|
||||
user?: User
|
||||
/** WebSocket ping of Client */
|
||||
ping = 0
|
||||
/** Token of the Bot/User */
|
||||
token?: string
|
||||
/** Cache Adapter */
|
||||
cache: ICacheAdapter = new DefaultCacheAdapter()
|
||||
/** Gateway Intents */
|
||||
intents?: GatewayIntents[]
|
||||
/** Whether to force new session or not */
|
||||
forceNewSession?: boolean
|
||||
|
||||
users: UserManager = new UserManager(this)
|
||||
guilds: GuildManager = new GuildManager(this)
|
||||
channels: ChannelsManager = new ChannelsManager(this)
|
||||
messages: MessagesManager = new MessagesManager(this)
|
||||
emojis: EmojisManager = new EmojisManager(this)
|
||||
|
||||
/** Whether this client will login as bot user or not */
|
||||
bot: boolean = true
|
||||
/** Whether the REST Manager will use Canary API or not */
|
||||
canary: boolean = false
|
||||
|
||||
/** Client's presence. Startup one if set before connecting */
|
||||
presence: ClientPresence = new ClientPresence()
|
||||
|
||||
constructor (options: ClientOptions = {}) {
|
||||
|
@ -55,11 +74,13 @@ export class Client extends EventEmitter {
|
|||
if (options.canary === true) this.canary = true
|
||||
}
|
||||
|
||||
/** Set Cache Adapter */
|
||||
setAdapter (adapter: ICacheAdapter): Client {
|
||||
this.cache = adapter
|
||||
return this
|
||||
}
|
||||
|
||||
/** Change Presence of Client */
|
||||
setPresence (presence: ClientPresence | ClientActivity | ActivityGame): void {
|
||||
if (presence instanceof ClientPresence) {
|
||||
this.presence = presence
|
||||
|
@ -67,6 +88,7 @@ export class Client extends EventEmitter {
|
|||
this.gateway?.sendPresence(this.presence.create())
|
||||
}
|
||||
|
||||
/** Emit debug event */
|
||||
debug (tag: string, msg: string): void {
|
||||
this.emit("debug", `[${tag}] ${msg}`)
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ export class CommandClient extends Client {
|
|||
this.emit('commandUsed', { context: ctx })
|
||||
command.execute(ctx)
|
||||
} catch (e) {
|
||||
if (this.texts.ERROR !== undefined) return this.sendProcessedText(msg, this.texts.ERROR, Object.assign(baseReplaces, { error: e.message }))
|
||||
if (this.texts.ERROR !== undefined) this.sendProcessedText(msg, this.texts.ERROR, Object.assign(baseReplaces, { error: e.message }))
|
||||
this.emit('commandError', { command, parsed, error: e })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
import * as cache from '../models/cache.ts'
|
||||
|
||||
interface IInit {
|
||||
useCache?: boolean
|
||||
|
@ -25,18 +24,13 @@ export class Base {
|
|||
this.useCache = useCache
|
||||
const cacheID = restURLfuncArgs.join(':')
|
||||
if (this.useCache !== undefined) {
|
||||
const cached = cache.get(this.cacheName ?? this.name, cacheID)
|
||||
const cached = await client.cache.get(this.cacheName ?? this.name, cacheID)
|
||||
if (cached !== undefined) {
|
||||
return cached
|
||||
}
|
||||
}
|
||||
|
||||
const resp = await fetch(endpoint(...restURLfuncArgs), {
|
||||
headers: {
|
||||
Authorization: `Bot ${client.token}`
|
||||
}
|
||||
})
|
||||
const jsonParsed = await resp.json()
|
||||
const jsonParsed = await client.rest.get(endpoint(...restURLfuncArgs))
|
||||
|
||||
return new this(client, jsonParsed)
|
||||
}
|
||||
|
@ -47,12 +41,7 @@ export class Base {
|
|||
): Promise<this> {
|
||||
const oldOne = Object.assign(Object.create(this), this)
|
||||
|
||||
const resp = await fetch(endpoint(...restURLfuncArgs), {
|
||||
headers: {
|
||||
Authorization: `Bot ${client.token}`
|
||||
}
|
||||
})
|
||||
const jsonParsed = await resp.json()
|
||||
const jsonParsed = await client.rest.get(endpoint(...restURLfuncArgs))
|
||||
|
||||
this.readFromData(jsonParsed)
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import { PresenceUpdatePayload } from '../types/gateway.ts'
|
|||
import { Base } from './base.ts'
|
||||
import { Emoji } from './emoji.ts'
|
||||
import { VoiceState } from './voiceState.ts'
|
||||
import cache from '../models/cache.ts'
|
||||
import { RolesManager } from "../managers/roles.ts"
|
||||
import { GuildChannelsManager } from "../managers/guildChannels.ts"
|
||||
import { MembersManager } from "../managers/members.ts"
|
||||
|
@ -156,10 +155,10 @@ export class Guild extends Base {
|
|||
// data.roles.map(
|
||||
// v => cache.get('role', v.id) ?? new Role(this.client, v)
|
||||
// ) ?? this.roles
|
||||
this.emojis =
|
||||
data.emojis.map(
|
||||
v => cache.get('emoji', v.id) ?? new Emoji(this.client, v)
|
||||
) ?? this.emojis
|
||||
// this.emojis =
|
||||
// data.emojis.map(
|
||||
// v => cache.get('emoji', v.id) ?? new Emoji(this.client, v)
|
||||
// ) ?? this.emojis
|
||||
this.features = data.features ?? this.features
|
||||
this.mfaLevel = data.mfa_level ?? this.mfaLevel
|
||||
this.systemChannelID = data.system_channel_id ?? this.systemChannelID
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
import cache from '../models/cache.ts'
|
||||
import { Client } from '../models/client.ts'
|
||||
import { MemberPayload } from '../types/guild.ts'
|
||||
import { Base } from './base.ts'
|
||||
import { Role } from "./role.ts"
|
||||
import { User } from './user.ts'
|
||||
|
||||
export class Member extends Base {
|
||||
id: string
|
||||
user: User
|
||||
nick?: string
|
||||
roles: string[]
|
||||
roleIDs: string[]
|
||||
roles: Role[] = []
|
||||
joinedAt: string
|
||||
premiumSince?: string
|
||||
deaf: boolean
|
||||
mute: boolean
|
||||
|
||||
constructor (client: Client, data: MemberPayload) {
|
||||
constructor (client: Client, data: MemberPayload, user: User) {
|
||||
super(client)
|
||||
this.id = data.user.id
|
||||
this.user =
|
||||
cache.get('user', data.user.id) ?? new User(this.client, data.user)
|
||||
this.user = user
|
||||
// this.user =
|
||||
// cache.get('user', data.user.id) ?? new User(this.client, data.user)
|
||||
this.nick = data.nick
|
||||
this.roles = data.roles
|
||||
this.roleIDs = data.roles
|
||||
this.joinedAt = data.joined_at
|
||||
this.premiumSince = data.premium_since
|
||||
this.deaf = data.deaf
|
||||
|
@ -32,7 +34,7 @@ export class Member extends Base {
|
|||
protected readFromData (data: MemberPayload): void {
|
||||
super.readFromData(data.user)
|
||||
this.nick = data.nick ?? this.nick
|
||||
this.roles = data.roles ?? this.roles
|
||||
this.roleIDs = data.roles ?? this.roles
|
||||
this.joinedAt = data.joined_at ?? this.joinedAt
|
||||
this.premiumSince = data.premium_since ?? this.premiumSince
|
||||
this.deaf = data.deaf ?? this.deaf
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { CommandClient, Intents } from '../../mod.ts';
|
||||
import PingCommand from "./cmds/ping.ts";
|
||||
import UserinfoCommand from "./cmds/userinfo.ts";
|
||||
import { TOKEN } from './config.ts'
|
||||
|
||||
const client = new CommandClient({
|
||||
|
@ -13,6 +14,9 @@ client.on('ready', () => {
|
|||
console.log(`[Login] Logged in as ${client.user?.tag}!`)
|
||||
})
|
||||
|
||||
client.on("commandError", console.log)
|
||||
|
||||
client.commands.add(PingCommand)
|
||||
client.commands.add(UserinfoCommand)
|
||||
|
||||
client.connect(TOKEN, Intents.All)
|
|
@ -3,9 +3,8 @@ import { CommandContext } from "../../models/command.ts";
|
|||
|
||||
export default class PingCommand extends Command {
|
||||
name = "ping"
|
||||
dmOnly = true
|
||||
|
||||
execute(ctx: CommandContext): void {
|
||||
ctx.message.reply(`pong! Latency: ${ctx.client.ping}ms`)
|
||||
ctx.message.reply(`Pong! Latency: ${ctx.client.ping}ms`)
|
||||
}
|
||||
}
|
16
src/test/cmds/userinfo.ts
Normal file
16
src/test/cmds/userinfo.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Command, Member, CommandContext, Embed } from "../../../mod.ts";
|
||||
|
||||
export default class UserinfoCommand extends Command {
|
||||
name = "userinfo"
|
||||
guildOnly = true
|
||||
|
||||
execute(ctx: CommandContext): void {
|
||||
const member: Member = ctx.message.member as any
|
||||
const embed = new Embed()
|
||||
.setTitle(`User Info`)
|
||||
.setAuthor({ name: member.user.tag })
|
||||
.addField("ID", member.id)
|
||||
.addField("Roles", member.roles.map(r => r.name).join(", "))
|
||||
ctx.channel.send(embed)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue