galactic-bot/structure/client/components/settings/moderation/Mute.js
2020-08-17 13:26:57 -07:00

544 lines
20 KiB
JavaScript

const { Setting } = require('../../../../interfaces/');
const { Emojis } = require('../../../../../util/');
const { PermissionNames, EmbedLimits } = require('../../../../../util/Constants.js');
const Constants = {
Types: {
role: [
'muteRole',
'mutedRole'
],
create: [
'createMute',
'createMuted',
'createMuteRole',
'createMutedRole'
],
type: [
'muteType',
'mutedType'
],
permanent: [
'permaMute',
'permanentMute'
],
duration: [
'defaultMuteDuration',
'muteDuration'
]
},
MuteTypes: [0, 1, 2],
MaxCharacters: 98,
MaxIssues: 6
};
const { stripIndents } = require('common-tags');
class MuteSetting extends Setting {
constructor(client) {
super(client, {
name: 'mute',
module: 'moderation',
aliases: [
'muted',
'muteType',
'mutedType',
'muteRole',
'mutedRole',
'createMute',
'createMuteRole',
'createMuted',
'createMutedRole',
'permaMute',
'permanentMute',
'defaultMuteDuration'
],
// arguments: [
// {
// name: 'text',
// type: 'BOOLEAN',
// types: ['FLAG'],
// default: true
// },
// {
// name: 'voice',
// type: 'BOOLEAN',
// types: ['FLAG'],
// default: true
// }
// ],
usage: "<'create'|'type'|'permanent'|'default'|role> <value..>",
examples: [
"mute muted-role",
"mute create Muted",
"mute type 1",
"mute permanent true",
"mute default 1 day"
],
resolve: 'GUILD',
default: {
mute: {
role: null,
type: 0,
defaultDuration: 3600,
permanent: false
}
}
});
}
async handle(message, args) {
const { params, parsedArguments } = await this._parseArguments(args, message.guild);
if(params.length === 0) {
return {
msg: message.format('S_MUTE_MISSINGARGUMENTS'),
error: true
};
}
let type = 'role';
let parameters = params.join(' ');
if(!['mute', 'muted'].includes(message._settingCaller)) {
for(const [ key, values ] of Object.entries(Constants.Types)) {
if(values.map((v) => v.toLowerCase()).includes(message._settingCaller.toLowerCase())) {
type = key;
break;
}
}
} else {
const key = params[0].toLowerCase();
if(['create', 'createrole'].includes(key)) type = 'create', parameters = params.splice(1).join(' '); //eslint-disable-line no-unused-expressions, no-sequences
if(['type'].includes(key)) type = 'type', parameters = params.splice(1).join(' '); //eslint-disable-line no-unused-expressions, no-sequences
if(['duration', 'defaultduration'].includes(key)) type = 'duration', parameters = params.splice(1).join(' '); //eslint-disable-line no-unused-expressions, no-sequences
if(['perma', 'permamute', 'permanent'].includes(key)) type = 'permanent', parameters = params.splice(1).join(' '); //eslint-disable-line no-unused-expressions, no-sequences
}
if(type === 'role') {
const role = await this.client.resolver.resolveRole(parameters, true, message.guild);
if(!role) return {
msg: message.format('S_MUTE_ROLEMISSING'),
error: true
};
await message.guild._updateSettings({
[this.index]: {
...message.guild._settings[this.index],
role: role.id
}
});
message.respond(message.format('S_MUTE_ROLESUCCESS'), {
emoji: 'success'
});
} else if(type === 'create') {
const response = await this._createRole(message, parameters, parsedArguments);
if(response.error) return response;
const { role, issues, created, updatedPermissions } = response;
await message.guild._updateSettings({
[this.index]: {
...message.guild._settings[this.index],
role: role.id
}
});
const sorted = issues ? issues.sort((a, b) => a.position - b.position) : [];
const embed = {
author: {
name: `${Emojis.warning} Warning`
},
color: 0xffe15c,
description: message.format('S_MUTE_CREATESUCCESSWARNING'),
fields: []
};
const addField = (array, type) => {
const field = {
name: type === 'text' ? 'Text Channels' : 'Voice Channels',
value: ''
};
const sorted = array.sort((a, b) => a.position - b.position) || [];
for(const i of sorted) {
const text = `${Emojis.role} **${i.role}** has ${i.permissions.map((p) => `\`${PermissionNames[p]}\``).join(', ')} in ${Emojis[i.type === 'text' ? 'text-channel' : 'voice-channel']} **${i.channel}**\n`;
if(field.value.length+text.length <= EmbedLimits.fieldValue) field.value += text;
}
return field;
};
const textIssues = issues.filter((i) => i.type === 'text');
if(textIssues.length > 0) embed.fields.push(addField(textIssues, 'text'));
const voiceIssues = issues.filter((i) => i.type === 'voice');
if(voiceIssues.length > 0) embed.fields.push(addField(voiceIssues, 'voice'));
message.respond(message.format('S_MUTE_CREATESUCCESS', {
created: created ? message.format('S_MUTE_CREATESUCCESSALT') : ' ',
permissions: message.format(updatedPermissions ? 'S_MUTE_GENERATEDPERMISSIONS' : 'S_MUTE_UNGENERATEDPERMISSIONS'),
role: role.name
}), {
emoji: 'success',
embed: issues.length > 0 ? embed : null
});
} else if(type === 'type') {
const number = parseInt(num);
if(Number.isNaN(number)) return {
msg: message.format('S_MUTE_TYPENAN'),
error: true
};
if(!Constants.MuteTypes.includes(number)) return {
msg: message.format('S_MUTE_TYPEINVALID'),
error: true
};
await message.guild._updateSettings({
[this.index]: {
...message.guild._settings[this.index],
type: number
}
});
return {
msg: `${message.format('S_MUTE_TYPESUCCESS', { type: number })} ${message.format('S_MUTE_TYPESWITCH', { type: number }, true)}`,
error: false
};
} else if(type === 'duration') {
} else if(type === 'permanent') {
}
return {
error: false,
ignore: true
};
}
async _createRole(message, name = 'Muted', args) {
const createRole = async (name) => {
let role = null;
if(name.length > Constants.MaxCharacters) name = name.slice(0, Constants.MaxCharacters);
try {
role = await message.guild.roles.create({
data: {
name
},
reason: super.reason(message.author)
});
} catch(error) {
return {
msg: message.format('S_MUTE_ROLECREATEERROR'),
error: true
};
}
return role;
};
const hasPermission = message.guild.me.hasPermission('MANAGE_ROLES');
if(!hasPermission) return {
msg: message.format('S_MUTE_ROLEMISSINGPERMISSION'),
error: true
};
let role = null;
const existing = await this.client.resolver.resolveRole(name, true, message.guild);
if(existing) {
const prompt = await message.prompt(message.format('S_MUTE_ROLEPROMPT', {
name: existing.name,
id: existing.id
}), { emoji: 'loading' });
const boolean = this.client.resolver.resolveBoolean(prompt.content.toLowerCase());
if(boolean === null) return {
msg: message.format('S_MUTE_ROLEPROMPTERROR'),
error: true
};
if(boolean) {
role = existing;
}
}
let created = false;
if(!role) {
role = await createRole(name);
if(role.error) return role;
created = true;
}
const issues = [];
let updatedPermissions = false;
for(const channel of message.guild.channels.cache.values()) {
const configuration = channel.type === 'text'
? { permissions: { SEND_MESSAGES: false, ADD_REACTIONS: false }, bitwise: 0x800 }
: { permissions: { CONNECT: false }, bitwise: 0x100000 };
try {
if(channel.type === 'text' || channel.type === 'voice') {
await channel.createOverwrite(role, configuration.permissions, super.reason(message.author));
for(const permission of channel.permissionOverwrites.values()) {
if(permission.type !== 'role') continue;
const permissionRole = await this.client.resolver.resolveRole(permission.id, true, message.guild);
if((permission.allow & configuration.bitwise) === configuration.bitwise) { //eslint-disable-line no-bitwise
const issue = {
role: permissionRole.name,
permissions: Object.keys(configuration.permissions),
channel: channel.name,
type: channel.type,
position: permissionRole.rawPosition
};
issues.push(issue);
}
}
}
updatedPermissions = true;
} catch(error) {} //eslint-disable-line no-empty
}
return {
error: false,
updatedPermissions,
created,
issues,
role
};
}
/*
async handle(message, args) {
let { params, parsedArguments } = await this._parseArguments(args, message.guild); //eslint-disable-line prefer-const
if(['mutetype', 'mutedtype'].includes(message._settingCaller) || parsedArguments.type) {
if(!params[0]) return { error: true, msg: message.format('S_MUTE_TYPENAN') };
const num = params[0];
const number = parseInt(num);
if(Number.isNaN(number)) return {
msg: message.format('S_MUTE_TYPENAN'),
error: true
};
if(![0, 1, 2].includes(number)) return {
msg: message.format('S_MUTE_TYPEINVALID'),
error: true
};
await message.guild._updateSettings({
[this.index]: {
...message.guild._settings[this.index],
type: number
}
});
return {
msg: `${message.format('S_MUTE_TYPESUCCESS', { type: number })} ${message.format('S_MUTE_TYPESWITCH', { type: number }, true)}`,
error: false
};
} else if (['permamute', 'permanentmute'].includes(message._settingCaller) || parsedArguments.permanent) {
if(!params[0]) return { error: true, msg: message.format('S_MUTE_PERMANENTINVALID') };
const boolean = this.client.resolver.resolveBoolean(params[0]);
if(boolean === null) {
return {
msg: message.format('S_MUTE_PERMANENTINVALID'),
error: true
};
}
await message.guild._updateSettings({
[this.index]: {
...message.guild._settings[this.index],
permanent: boolean
}
});
return {
msg: message.format('S_MUTE_PERMANENTSUCCESS', { boolean }),
error: false
};
} else if (['defaultMuteDuration'].includes(message._settingCaller) || parsedArguments.defaultDuration) {
if(!params.length) return { error: true, msg: message.format('S_MUTE_PERMANENTINVALID') };
const time = this.client.resolver.resolveTime(params.join(' '));
if(!time) {
return {
msg: message.format('S_MUTE_DEFAULTINVALID'),
error: true
};
}
await message.guild._updateSettings({
[this.index]: {
...message.guild._settings[this.index],
defaultDuration: time
}
});
return {
msg: message.format('S_MUTE_DEFAULTSUCCESS', { time }),
error: false
};
}
let role = null,
updatedPermissions = false,
created = false;
const issues = [];
if(parsedArguments.create || ['createmute', 'createmuted', 'createmutedrole', 'createmuterole'].includes(message._settingCaller)) {
const missing = message.channel.permissionsFor(message.guild.me).missing('MANAGE_ROLES');
if(missing.length > 0) return {
msg: message.format('S_MUTE_ROLEMISSINGPERMISSION'),
error: true
};
const foundRole = await message.guild.resolveRole(params.join(' '), true);
if(foundRole) {
const prompt = await message.prompt(message.format('S_MUTE_ROLEPROMPT', { name: foundRole.name, id: foundRole.id }), { emoji: 'loading' });
const response = prompt.content.toLowerCase();
const bool = this.client.resolver.resolveBoolean(response);
if(bool === null) return { msg: message.format('S_MUTE_ROLEPROMPTERROR'), error: true };
if(!bool) {
role = await this._createRole(message, params);
if(role.error) return role;
created = true;
} else {
role = foundRole;
}
} else {
role = await this._createRole(message, params);
if(role.error) return role;
created = true;
}
const channels = message.guild.channels.cache;
for(const channel of channels.values()) {
const configuration = channel.type === 'text'
? { permissions: { SEND_MESSAGES: false, ADD_REACTIONS: false }, bitwise: 0x800 }
: { permissions: { CONNECT: false }, bitwise: 0x100000 };
try {
// console.log(channel.type)
if(channel.type === 'text' && !parsedArguments.voice || channel.type === 'voice' && !parsedArguments.text || !parsedArguments.text && !parsedArguments.voice) {
if(channel.type === 'category') continue;
await channel.createOverwrite(role, configuration.permissions, super.reason(message.author));
for(const permission of channel.permissionOverwrites.values()) {
if(permission.type !== 'role') continue;
const r = await this.client.resolver.resolveRole(permission.id, true, message.guild);
if((permission.allow & configuration.bitwise) === configuration.bitwise) { //eslint-disable-line no-bitwise
const info = {
role: r.name,
permission: channel.type === 'text' ? 'SEND_MESSAGES' : 'CONNECT',
channel: channel.name,
type: channel.type,
emoji: channel.type === 'text' ? emojis['text-channel'] : emojis['voice-channel']
};
issues.push(info);
}
}
}
} catch(err) {} //eslint-disable-line no-empty
}
updatedPermissions = true;
} else {
if(params.length > 1 && params[0].toLowerCase() === 'role') params = params.splice(1);
const search = params.join(' ');
role = await this.client.resolver.resolveRole(search, true, message.guild);
}
if(!role) return {
msg: message.format('S_MUTE_ROLEMISSING'),
error: true
};
await message.guild._updateSettings({
[this.index]: {
...message.guild._settings[this.index],
role: role.id
}
});
return {
msg: stripIndents`${message.format('S_MUTE_ROLESUCCESS', { role: role.name, type: created ? 'created' : 'set' })} ${updatedPermissions ? message.format('S_MUTE_GENERATEDPERMISSIONS') : message.format('S_MUTE_UNGENERATEDPERMISSIONS')}
${issues.length > 0 ? message.format('S_MUTE_ISSUES', { issues: issues.map((i) => `**\`${i.role}\`:** Has the \`${i.permission}\` permission in **${i.emoji}${i.channel}**.`).join('\n') }) : ''}`,
error: false
};
}
*/
/*
async _createRole(message, args) {
let role = null;
let name = args.join(' ') || 'Muted';
if(name.length > maxCharacters) name = name.slice(0, maxCharacters);
try {
role = await message.guild.roles.create({
data: {
name
},
reason: super.reason(message.author)
});
} catch(error) {
return {
msg: message.format('S_MUTE_ROLECREATEERROR'),
error: true
};
}
return role;
}
*/
fields(guild) {
const setting = guild._settings[this.index];
return [
{
name: '》 Muted Role',
value: setting?.role ? `<@&${guild._settings[this.index].role}>` : '`N/A`',
inline: true
},
{
name: '》 Mute Type',
value: `\`${setting?.type || 0}\``,
inline: true
},
{ name: '\u200b', value: '\u200b', inline: true }, //zero width spaces, not necessary, but could make things look nicer.
{
name: '》 Permanent Mutes',
value: guild.format('SETTING_STATUS', { bool: Boolean(setting?.permanent) }, true),
inline: true
},
{
name: '》 Default Duration',
value: `\`${setting.defaultDuration ? `${setting.defaultDuration} seconds` : 'N/A'}\``,
inline: true
},
{ name: '\u200b', value: '\u200b', inline: true } //zero width spaces, not necessary, but could make things look nicer.
];
}
}
module.exports = MuteSetting;