timotejroiko / discord.js-light

All the power of discord.js, zero caching. This library modifies discord.js's internal classes and functions in order to give you full control over its caching behaviour.
Apache License 2.0
292 stars 29 forks source link

`guildCreate` doesn't get triggered on init #78

Closed tyuop077 closed 3 years ago

tyuop077 commented 3 years ago

Currently there's no way to get guilds on launch with ChannelManager and GuildManager being LimitedCollection with size = 0 without fetching them with client.guilds.forge(exampleGuildId).channels.fetch() (ChannelManager) and client.guilds.forge(exampleGuildId).fetch() (GuildManager) as example.

client.on("raw",console.log) shows, that we receive GUILD_CREATE events (with channels and threads) without getting them on guildCreate or guildUpdate (shardConnect works for this option, but will do it only on sharding).

I was collecting parentId's of guild channels and thread parentIds, so there's no way to get them at launch without fetching.

Code:

...

const categories = new Collection<Snowflake, Snowflake>() // { channel => category }
const threads = new Collection<Snowflake, Snowflake>() // { thread => channel }

// categories and threads are always synced:
client.on("channelCreate",this._onChannelCreate);
client.on("channelUpdate",this._onChannelUpdate);
client.on("channelDelete",this._onChannelDelete);
client.on("threadCreate",this._onThreadCreate);
client.on("threadDelete",this._onThreadDelete);
client.on("threadUpdate",this._onThreadUpdate);
client.on("threadListSync",this._onThreadSync);

const channels = await this.client.guilds.forge(config().constants.trustedGuild).channels.fetch(); // can't receive on guildUpdate or guildCreate
// same with threads

channels.forEach(channel => {
   if (!channel.parentId || !channel.isText()) return;
   this.categories.set(channel.id, channel.parentId)
})

...

messageCreate: (leveling.channelMultipliers contains { Snowflake: number } with channel/category ids and multiplier values)

const channelId = message.channel.isThread() ? this.threads.get(message.channelId) : message.channelId;
const categoryId = channelId ? this.categories.get(channelId) : null;

const channelMultiplier = leveling.channelMultipliers[channelId!] ?? leveling.channelMultipliers[categoryId!] ?? 0;

console.log(`${channelId}'s multiplier is ${channelMultiplier}`);
timotejroiko commented 3 years ago

guildCreate and guildUpdate should work correctly after the client is ready. The initial GUILD_CREATE events that are sent to fill up the cache at login are not emitted by the discord.js guildCreate event, they are handled internally to decide when the client should become ready.

If you're looking for the initial GUILD_CREATE events, you have to use shardConnect and raw.

other than that, im not sure im understanding the issue very well.

tyuop077 commented 3 years ago

@timotejroiko Yeah, I thought of maybe implementing a new before-ready guild create event, because with shardConnect I still won't get thread objects (nevermind, it will work if i'll make thread manager sweep by interval instead of size = 0), only guilds. So raw is only way to go with there :(

other than that, im not sure im understanding the issue very well

I was just trying to find a way to get guild and thread objects without using fetch, requests and raw (because bot still receives them), thank you

timotejroiko commented 3 years ago

you can do something like this:

client.on("raw", raw => {
  if(raw.t === "GUILD_CREATE" && !client.readyAt) {
    const guild = client.guilds._add(raw.d, false)
  }
})

that should create a discord.js guild object from the raw data without caching it (although it will cache channels and users if their respective caches are enabled)

tyuop077 commented 3 years ago

thank you!