diff --git a/structures/client/client.js b/structures/client/client.js index 4e1a6b0..ecadae7 100644 --- a/structures/client/client.js +++ b/structures/client/client.js @@ -7,6 +7,7 @@ const handleResponses = require('./handleEvents.js'); const { EventEmitter } = require('events'); const axios = require('axios'); const { exit } = require('process'); +const Guild = require('../guilds/guild.js'); @@ -35,6 +36,9 @@ class Client extends EventEmitter { /** @type {Object} */ user_profile; + /** @type {Map} */ + guilds; + /** * @param {opts} input @@ -42,6 +46,7 @@ class Client extends EventEmitter { constructor(input) { super(); this.gwintents = input.intents; + this.guilds = new Map(); } async #heartbeat(hbInt, hbSequence) { @@ -85,6 +90,7 @@ class Client extends EventEmitter { } + //#region Event Emitters messageRecieved(msg) { this.emit("messageRecieved", msg); } @@ -101,6 +107,26 @@ class Client extends EventEmitter { this.emit('interactionRecieved', interaction); } + /** + * @param {Guild} guild + */ + guildCreate(guild) { + if (!this.guilds.has(guild.id)) { + this.guilds.set(guild.id, guild); + this.emit('guildCreate', guild); + } + } + + guildDelete(guild) { + this.emit('guildDelete', guild); + } + + guildMemberAdd(member) { + this.emit('guildMemberAdd', member); + } + //#endregion + + /** * @param {String} token */ @@ -114,7 +140,6 @@ class Client extends EventEmitter { this.ws.on('connect', async (connection) => { connection.on('message', async (msg) => { const data = JSON.parse(msg.utf8Data); - const response = await handleResponses(data, token, this.id); if (response.op == 10) { this.#startHeartBeat(response.heartBeat, token); } @@ -123,6 +148,7 @@ class Client extends EventEmitter { this.user_profile = response.profile; this.user_settings = response.config; this.id = response.profile.id; + console.log(response.guilds); this.ready(); } else if (response.t == gateWayEvents.MessageCreate) { @@ -135,6 +161,9 @@ class Client extends EventEmitter { this.interactionRecieved(response.interaction); } } + else if (response.t == gateWayEvents.GuildCreate) this.guildCreate(response.guild); + else if (response.t == gateWayEvents.GuildDelete) this.guildDelete(response.guild); + else if (response.t == gateWayEvents.GuildMemberAdd) this.guildMemberAdd(response.member); else console.log(response.t); } else { console.log(response.t); diff --git a/structures/client/handleEvents.js b/structures/client/handleEvents.js index bf3bc60..4c0a970 100644 --- a/structures/client/handleEvents.js +++ b/structures/client/handleEvents.js @@ -2,6 +2,7 @@ const { exit } = require('process'); const gateWayEvents = require('../gateway/dispatch.js'); const { message } = require('../messages/message.js'); const Interaction = require('../interactions/interaction.js'); +const Guild = require('../guilds/guild.js'); /** @@ -16,8 +17,10 @@ module.exports = async function handleEvents(msgObj, token, id) { if (op == 10) return resolve({op: op, heartBeat: msgObj["d"]["heartbeat_interval"]}); - if (op == 0 && t == gateWayEvents.Ready) { - resolve({op: op, t: t, config: msgObj["d"]["user_settings"], profile: msgObj["d"]["user"] }); + else if (op != 0) { resolve(false); } + + else if (t == gateWayEvents.Ready) { + resolve({op: op, t: t, config: msgObj["d"]["user_settings"], profile: msgObj["d"]["user"]}); //, guilds: msgObj["d"]["guilds"] } else if (t == gateWayEvents.MessageCreate) { const msg = new message(msgObj["d"], token); @@ -26,6 +29,9 @@ module.exports = async function handleEvents(msgObj, token, id) { else if (t == gateWayEvents.InteractionCreate) { resolve({op: op, t: t, interaction: new Interaction(msgObj["d"], token, id)}); } + else if (t == gateWayEvents.GuildCreate) { + resolve({op: op, t: t, guild: new Guild(msgObj["d"], token)}); + } else { // console.log(t); diff --git a/structures/guilds/guild.js b/structures/guilds/guild.js new file mode 100644 index 0000000..691d554 --- /dev/null +++ b/structures/guilds/guild.js @@ -0,0 +1,145 @@ +const axios = require('axios'); +const member = require('./member.js'); +const guildRole = require('./guildRoles.js'); +const GuildEmoji = require('./guildEmoji.js'); +const { Channel } = require('../messages/message.js'); + +//See https://discord.com/developers/docs/resources/guild + +class Guild { + + /** @type {String[]} */ + embeded_activities; + + /** @type {String} */ + description; + + /** @type {String} */ + id; + + /** @type {String} */ + name; + + /** @type {String} */ + icon; + + /** @type {Boolean} */ + nsfw; + + /** @type {member[]} */ + members; + + /** @type {String} */ + hub_type; + + /** @type {Number} */ + max_video_channel_users; + + /** @type {String[]} */ + stickers; + + /** @type {String} */ + hub_type; + + /** @type {Map} */ + members; + + /** @type {guildRole[]} */ + roles; + + /** @type {String} */ + banner; + + /** @type {String} */ + application_id; + + /** @type {String} */ + owner_id; + + /** @type {Map} */ + channels; + + /** @type {String} */ + home_header; + + /** @type {Number} */ + premium_tier; + + /** @type {Number} */ + nsfw_level; + + /** @type {Number} */ + verification_level; + + /** @type {Number} */ + mfa_level; + + // /** @type {String} */ //FIXME + // threads; + + /** @type {Number} */ + system_channel_flags; + + /** @type {String} */ + safety_alerts_channel_id; + + /** @type {object[]} */ + presences; + + /** @type {GuildEmoji[]} */ + emojis; + + /** @type {String} */ + public_updates_channel_id; + + /** @type {Object[]} */ + stage_instances + + + async #getChannels(token) { + const config = { + headers: { + Authorization: token + } + } + + const response = await axios.get(`https://discord.com/api/guilds/${this.id}/channels`, config); + + for (const channel of response.data) { + if (channel.type == 4) continue; + this.channels.set(channel.id, new Channel(token, channel.id)); + } + } + + constructor(o, token) { + this.members = new Map(); + this.channels = new Map(); + this.roles = []; + this.stickers = []; + + for (const field in this) { + if (o[field] == undefined || field == "channels") continue; + + if (field == 'members') { + for (const m of o[field]) { + const mem = new member(m); + this.members.set(mem.user.id); + } + } + else if (field == 'roles') { + for (const r of o[field]) { + this.roles.push(new guildRole(r)); + } + } + else { + this[field] = o[field]; + } + } + + this.#getChannels(token); + } +} + + + +module.exports = Guild; \ No newline at end of file diff --git a/structures/guilds/guildEmoji.js b/structures/guilds/guildEmoji.js new file mode 100644 index 0000000..8b6ed96 --- /dev/null +++ b/structures/guilds/guildEmoji.js @@ -0,0 +1,28 @@ +class GuildEmoji { + /** @type {Number} */ + version; + + /** @type {Object[]} */ + roles; + + /** @type {Boolean} */ + require_colons; + + /** @type {String} */ + name; + + /** @type {Boolean} */ + managed; + + /** @type {String} */ + id; + + /** @type {Boolean} */ + available; + + /** @type {Boolean} */ + animated; +} + + +module.exports = GuildEmoji; \ No newline at end of file diff --git a/structures/guilds/guildRoles.js b/structures/guilds/guildRoles.js new file mode 100644 index 0000000..6accfc0 --- /dev/null +++ b/structures/guilds/guildRoles.js @@ -0,0 +1,51 @@ +class guildRole { + /** @type {Number} */ + version; + + /** @type {String} */ + unicode_emoji; + + /** @type {Object} */ + tags; + + /** @type {Number} */ + position; + + /** @type {String} */ + permissions; + + /** @type {String} */ + name; + + /** @type {Boolean} */ + mentionable; + + /** @type {Boolean} */ + managed; + + /** @type {String} */ + id; + + /** @type {String} */ + icon; + + /** @type {Boolean} */ + hoist; + + /** @type {Number} */ + flags; + + /** @type {Number} */ + color; + + constructor(o) { + for (const k in this) { + if (o[k]) { + this[k] = o[k]; + } + } + } +} + + +module.exports = guildRole; \ No newline at end of file diff --git a/structures/guilds/member.js b/structures/guilds/member.js new file mode 100644 index 0000000..03d4249 --- /dev/null +++ b/structures/guilds/member.js @@ -0,0 +1,45 @@ +class member { + /** @type {Object} */ + user; + + /** @type {Object[]} */ + roles; + + /** @type {String} */ + premium_since; + + /** @type {Boolean} */ + pending; + + /** @type {String} */ + nick; + + /** @type {Boolean} */ + mute; + + /** @type {Strnig} */ + joined_at; + + /** @type {Number} */ + flags; + + /** @type {Boolean} */ + deaf; + + /** @type {String} */ + communication_disabled_until; + + /** @type {String} */ + avatar; + + constructor(o) { + for (const k in this) { + if (o[k]) { + this[k] = o[k]; + } + } + } +} + + +module.exports = member; \ No newline at end of file diff --git a/tests/guildTests.js b/tests/guildTests.js new file mode 100644 index 0000000..1f20ef7 --- /dev/null +++ b/tests/guildTests.js @@ -0,0 +1,9 @@ +const Guild = require("../structures/guilds/guild"); +const { Client } = require("../structures/types"); +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); + +module.exports = /** @param {Client} c */ async (c) => { + c.guilds.forEach(/** @param {Guild} guild */ (guild) => { + console.log(guild); + }); +} \ No newline at end of file diff --git a/tests/test.js b/tests/test.js index 9cf09fc..448f09b 100644 --- a/tests/test.js +++ b/tests/test.js @@ -32,6 +32,11 @@ c.on('interactionRecieved', /** @param {Interaction} interaction*/ async (intera }); +c.on('guildCreate', async (guild) => { + require('./guildTests.js')(c); +}); + + c.on('ready', () => { console.log("BOT ONLINE!"); }); \ No newline at end of file