const { Collection, Emoji, Role } = require('discord.js');
const Command = require('./Command');
/** Custom guild class extention, addes the needed thingies
* @interface
*/
class GuildExtention {
setup(data) {
/**
* The name of the guild
* @type {string}
*/
this.name = data.name;
/**
* The hash of the guild icon, or null if there is no icon.
* @type {?string}
*/
this.icon = data.icon;
/**
* The hash of the guild splash image, or null if no splash (VIP only)
* @type {?string}
*/
this.splash = data.splash;
/**
* The region the guild is located in
* @type {string}
*/
this.region = data.region;
/**
* The full amount of members in this Guild as of `READY`
* @type {number}
*/
this.memberCount = data.member_count || this.memberCount;
/**
* Whether the guild is "large" (has more than 250 members)
* @type {boolean}
*/
this.large = data.large || this.large;
/**
* A collection of presences in this Guild
* @type {Collection<string, Presence>}
*/
this.presences = new Collection();
/**
* An array of guild features.
* @type {Object[]}
*/
this.features = data.features;
/**
* A Collection of emojis that are in this Guild. The key is the emoji's ID, the value is the emoji.
* @type {Collection<string, Emoji>}
*/
this.emojis = new Collection();
for (const emoji of data.emojis) this.emojis.set(emoji.id, new Emoji(this, emoji));
/**
* The time in seconds before a user is counted as "away from keyboard".
* @type {?number}
*/
this.afkTimeout = data.afk_timeout;
/**
* The ID of the voice channel where AFK members are moved.
* @type {?string}
*/
this.afkChannelID = data.afk_channel_id;
/**
* Whether embedded images are enabled on this guild.
* @type {boolean}
*/
this.embedEnabled = data.embed_enabled;
/**
* The verification level of the guild.
* @type {number}
*/
this.verificationLevel = data.verification_level;
/**
* The timestamp the client user joined the guild at
* @type {number}
*/
this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp;
this.id = data.id;
this.available = !data.unavailable;
this.features = data.features || this.features || [];
if (data.members) {
this.members.clear();
for (const guildUser of data.members) this._addMember(guildUser, false);
}
if (data.owner_id) {
/**
* The user ID of this guild's owner.
* @type {string}
*/
this.ownerID = data.owner_id;
}
if (data.channels) {
this.channels.clear();
for (const channel of data.channels) this.client.dataManager.newChannel(channel, this);
}
if (data.roles) {
this.roles.clear();
for (const role of data.roles) {
const newRole = new Role(this, role);
this.roles.set(newRole.id, newRole);
}
}
if (data.presences) {
for (const presence of data.presences) {
this._setPresence(presence.user.id, presence);
}
}
this._rawVoiceStates = new Collection();
if (data.voice_states) {
for (const voiceState of data.voice_states) {
this._rawVoiceStates.set(voiceState.user_id, voiceState);
const member = this.members.get(voiceState.user_id);
if (member) {
member.serverMute = voiceState.mute;
member.serverDeaf = voiceState.deaf;
member.selfMute = voiceState.self_mute;
member.selfDeaf = voiceState.self_deaf;
member.voiceSessionID = voiceState.session_id;
member.voiceChannelID = voiceState.channel_id;
this.channels.get(voiceState.channel_id).members.set(member.user.id, member);
}
}
}
this._commands = new Collection();
this._enabledPlugins = [];
if (this.client.options.guildConfigs === true) {
this.client.getConfigOption(this, 'prefix').then(prefix => {
this._prefix = prefix || this.client.options.prefix;
}).catch(e => this.client.emit('warn', e));
this.client.getConfigOption(this, 'commands').then(commands => {
commands.forEach(command => {
this.registerCommand(new GuildCommand(this.client, command.id, command.message, this));
});
}).catch(e => this.client.emit('warn', e));
this.client.getConfigOption(this, 'enabledPlugins').then(plugins => {
this._enabledPlugins = plugins;
}).catch(e => this.client.emit('warn', e));
} else {
this._prefix = this.client.options.prefix;
}
}
/**
* Registers a command to the guild
* @param {Command} command The command to register
*/
registerCommand(command) {
if (command instanceof Command && !this._commands.has(command.id)) {
this._commands.set(command.id, command);
}
}
/**
* Removes a command from the guild
* @param {Command} command The command to remove
*/
removeCommand(command) {
if ((command instanceof Command) && this._commands.has(command.id)) {
this._commands.delete(command.id);
}
}
/**
* Enables a plugin
* @param {string} plugin the id of the plugin to disable
*/
enablePlugin(plugin) {
if (plugin !== undefined && typeof plugin === 'string' && this._enabledPlugins.indexOf(plugin) === -1) {
this.client.emit('enablePlugin', this, this.client.registry.plugins.get(plugin));
this._enabledPlugins.push(plugin);
}
}
/**
* Disables a plugin
* @param {string} plugin the id of the plugin to disable
*/
disablePlugin(plugin) {
if (plugin !== undefined && typeof plugin === 'string' && this._enabledPlugins.indexOf(plugin) !== -1) {
this.client.emit('disablePlugin', this, this.client.registry.plugins.get(plugin));
const pos = this._enabledPlugins.indexOf(plugin);
this._enabledPlugins.splice(pos, 1);
}
}
_setPrefix(Prefix) {
this._prefix = Prefix;
this.client.setConfigOption(this, 'prefix', Prefix);
}
/**
* Changes the guild's prefix
* @param {string} Prefix the new prefix for the guild
*/
changePrefix(Prefix) {
if (Prefix !== null && typeof Prefix === 'string') {
this._setPrefix(Prefix);
}
}
get prefix() {
return this._prefix || this.client.options.prefix;
}
get commands() {
return this._commands;
}
get enabledPlugins() {
return this._enabledPlugins || this.client.options.enabledPlugins;
}
static applyToClass(target) {
for (const prop of ['prefix', 'commands', '_setPrefix', 'changePrefix', 'enabledPlugins', 'disablePlugin', 'enablePlugin', 'registerCommand', 'removeCommand', 'setup']) {
Object.defineProperty(target.prototype, prop, Object.getOwnPropertyDescriptor(this.prototype, prop));
}
}
}
class GuildCommand extends Command {
constructor(id, message, guild) {
super(id, message, guild);
this.description = message;
}
}
module.exports = GuildExtention;