Commit 8e90be50 authored by Yashin's avatar Yashin
Browse files

Adding per server locale support and adding German locale.

parent 60f91040
const { SlashCommandBuilder } = require('@discordjs/builders');
const {SlashCommandBuilder} = require('@discordjs/builders');
module.exports = new SlashCommandBuilder()
.setName('add_role_menu')
.setDescription('Create a new role menu')
.addChannelOption( option =>
option.setName('channel')
.setDescription('Channel the menu will be put inside.')
.setRequired(true))
.addStringOption( option =>
option.setName('message')
.setDescription('Message content.')
.setRequired(true))
.addStringOption( option =>
option.setName('type')
.setDescription('NOT YET IMPLEMENTED Sets type of role menu.')
.setRequired(true)
.addChoice('One of N', 'one')
.addChoice('M of N', 'm')
.addChoice('Any of N', 'any'))
.addBooleanOption( option =>
option.setName('verification')
.setDescription('NOT YET IMPLEMENTED Sets verification state of role menu.')
.setRequired(true))
\ No newline at end of file
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.add_role_menu;
return new SlashCommandBuilder()
.setName('add_role_menu')
.setDescription(commandLocale.description)
.addChannelOption(option =>
option.setName('channel')
.setDescription(commandLocale.channelDescription)
.setRequired(true))
.addStringOption(option =>
option.setName('message')
.setDescription(commandLocale.messageDescription)
.setRequired(true))
.addStringOption(option =>
option.setName('type')
.setDescription(commandLocale.typeDescription)
.setRequired(true)
.addChoice(commandLocale.typeChoices.oneOfN, 'one')
.addChoice(commandLocale.typeChoices.mOfN, 'm')
.addChoice(commandLocale.typeChoices.anyOfN, 'any'))
.addBooleanOption(option =>
option.setName('verification')
.setDescription(commandLocale.verificationDescription)
.setRequired(true));
}
\ No newline at end of file
const { SlashCommandBuilder } = require('@discordjs/builders');
const {SlashCommandBuilder} = require('@discordjs/builders');
module.exports = new SlashCommandBuilder()
.setName('add_role_to_menu')
.setDescription('Add role to a menu.')
.addChannelOption( option =>
option.setName('channel')
.setDescription('Channel of the menu.')
.setRequired(true))
.addStringOption( option =>
option.setName('message_id')
.setDescription('Message ID of the menu.')
.setRequired(true))
.addRoleOption(option =>
option.setName('role')
.setDescription('Role to add to the menu.')
.setRequired(true))
\ No newline at end of file
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.add_role_to_menu;
return new SlashCommandBuilder()
.setName('add_role_to_menu')
.setDescription(commandLocale.description)
.addChannelOption(option =>
option.setName('channel')
.setDescription(commandLocale.channelDescription)
.setRequired(true))
.addStringOption(option =>
option.setName('message_id')
.setDescription(commandLocale.messageIDDescription)
.setRequired(true))
.addRoleOption(option =>
option.setName('role')
.setDescription(commandLocale.roleDescription)
.setRequired(true));
}
\ No newline at end of file
const { SlashCommandBuilder } = require('@discordjs/builders');
const {SlashCommandBuilder} = require('@discordjs/builders');
module.exports = new SlashCommandBuilder()
.setName('assign_permission')
.setDescription('Assign a permission to a role')
.addStringOption(option =>
option.setName('permission')
.setDescription('Permission to assign.')
.setRequired(true)
.addChoice("Role Menus", 'role_menu'))
.addRoleOption(option =>
option.setName('role')
.setDescription('Role to assign permission to.')
.setRequired(true))
\ No newline at end of file
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.assign_permission;
return new SlashCommandBuilder()
.setName('assign_permission')
.setDescription(commandLocale.description)
.addStringOption(option =>
option.setName('permission')
.setDescription(commandLocale.permissionDescription)
.setRequired(true)
.addChoice(commandLocale.permissionChoices.roleMenus, 'role_menu')
.addChoice(commandLocale.permissionChoices.locale, 'locale'))
.addRoleOption(option =>
option.setName('role')
.setDescription(commandLocale.roleDescription)
.setRequired(true));
}
\ No newline at end of file
const {SlashCommandBuilder} = require('@discordjs/builders');
const fs = require('fs');
locale = require('../util/locale');
module.exports = (loc, pathToLocales) => {
const commandLocale = locale.get(loc).slashCommands.change_locale;
return new SlashCommandBuilder()
.setName('change_locale')
.setDescription(commandLocale.description)
.addStringOption((option) => {
option.setName('locale')
.setDescription(commandLocale.localeDescription)
.setRequired(true)
const localeFiles = fs.readdirSync('./locales').filter(file => file.endsWith('.json'));
for (const localeFile of localeFiles) {
const locale1 = JSON.parse(fs.readFileSync(`./locales/${localeFile}`));
option.addChoice(locale1.commonName, locale1.locale);
}
return option
});
}
const { SlashCommandBuilder } = require('@discordjs/builders');
const {SlashCommandBuilder} = require('@discordjs/builders');
module.exports = new SlashCommandBuilder()
.setName('delete_role_from_menu')
.setDescription('Delete role from menu.')
.addChannelOption( option =>
option.setName('channel')
.setDescription('Channel of the menu.')
.setRequired(true))
.addStringOption( option =>
option.setName('message_id')
.setDescription('Message ID of the menu.')
.setRequired(true))
.addRoleOption(option =>
option.setName('role')
.setDescription('Role to remove from the menu.')
.setRequired(true))
\ No newline at end of file
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.delete_role_from_menu;
return new SlashCommandBuilder()
.setName('delete_role_from_menu')
.setDescription(commandLocale.description)
.addChannelOption(option =>
option.setName('channel')
.setDescription(commandLocale.channelDescription)
.setRequired(true))
.addStringOption(option =>
option.setName('message_id')
.setDescription(commandLocale.messageIDDescription)
.setRequired(true))
.addRoleOption(option =>
option.setName('role')
.setDescription(commandLocale.roleDescription)
.setRequired(true));
}
\ No newline at end of file
const { SlashCommandBuilder } = require('@discordjs/builders');
const {SlashCommandBuilder} = require('@discordjs/builders');
module.exports = new SlashCommandBuilder()
.setName('delete_role_menu')
.setDescription('Delete a role menu')
.addChannelOption( option =>
option.setName('channel')
.setDescription('Select channel of to be deleted menu')
.setRequired(true))
.addStringOption( option =>
option.setName('message_id')
.setDescription('Message ID of to be deleted menu')
.setRequired(true))
\ No newline at end of file
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.delete_role_menu;
return new SlashCommandBuilder()
.setName('delete_role_menu')
.setDescription(commandLocale.description)
.addChannelOption(option =>
option.setName('channel')
.setDescription(commandLocale.channelDescription)
.setRequired(true))
.addStringOption(option =>
option.setName('message_id')
.setDescription(commandLocale.messageIDDescription)
.setRequired(true));
}
\ No newline at end of file
const { SlashCommandBuilder } = require('@discordjs/builders');
const {SlashCommandBuilder} = require('@discordjs/builders');
module.exports = new SlashCommandBuilder()
.setName('edit_role_menu')
.setDescription('Edit an existing role menu.')
.addChannelOption( option =>
option.setName('channel')
.setDescription('Channel of the menu.')
.setRequired(true))
.addStringOption( option =>
option.setName('message_id')
.setDescription('Message ID of the menu.')
.setRequired(true))
.addStringOption( option =>
option.setName('message')
.setDescription('Message content.'))
.addStringOption( option =>
option.setName('type')
.setDescription('NOT YET IMPLEMENTED')
.addChoice('One of N', 'one')
.addChoice('M of N', 'm')
.addChoice('Any of N', 'any'))
.addBooleanOption( option =>
option.setName('verification')
.setDescription('NOT YET IMPLEMENTED Sets verification state of role menu.'))
\ No newline at end of file
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.edit_role_menu;
return new SlashCommandBuilder()
.setName('edit_role_menu')
.setDescription(commandLocale.description)
.addChannelOption(option =>
option.setName('channel')
.setDescription(commandLocale.channelDescription)
.setRequired(true))
.addStringOption(option =>
option.setName('message_id')
.setDescription(commandLocale.messageIDDescription)
.setRequired(true))
.addStringOption(option =>
option.setName('message')
.setDescription(commandLocale.messageDescription))
.addStringOption(option =>
option.setName('type')
.setDescription(commandLocale.typeDescription)
.addChoice(commandLocale.typeChoices.oneOfN, 'one')
.addChoice(commandLocale.typeChoices.mOfN, 'm')
.addChoice(commandLocale.typeChoices.anyOfN, 'any'))
.addBooleanOption(option =>
option.setName('verification')
.setDescription(commandLocale.verificationDescription));
}
\ No newline at end of file
const { SlashCommandBuilder } = require('@discordjs/builders');
const {SlashCommandBuilder} = require('@discordjs/builders');
module.exports = new SlashCommandBuilder()
.setName('list_permissions')
.setDescription('List all Permissions for this Server.');
\ No newline at end of file
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.list_permissions;
return new SlashCommandBuilder()
.setName('list_permissions')
.setDescription(commandLocale.description);
}
\ No newline at end of file
const { SlashCommandBuilder } = require('@discordjs/builders');
module.exports = new SlashCommandBuilder()
.setName('revoke_permission')
.setDescription('Revoke a permission from a role')
.addStringOption(option =>
option.setName('permission')
.setDescription('Permission to revoke.')
.setRequired(true)
.addChoice("Role Menus", 'role_menu'))
.addRoleOption(option =>
option.setName('role')
.setDescription('Role to revoke permission from.')
.setRequired(true))
\ No newline at end of file
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.revoke_permission;
return new SlashCommandBuilder()
.setName('revoke_permission')
.setDescription(commandLocale.description)
.addStringOption(option =>
option.setName('permission')
.setDescription(commandLocale.permissionDescription)
.setRequired(true)
.addChoice(commandLocale.permissionChoices.roleMenus, 'role_menu'))
.addRoleOption(option =>
option.setName('role')
.setDescription(commandLocale.roleDescription)
.setRequired(true));
}
\ No newline at end of file
const ServerConfig = require('../models/ServerConfig');
const RoleMenu = require('../models/RoleMenu');
const checkPerm = require("../util/perm");
const locales = require('../util/locale');
const registerCommands = require('../util/registerCommands');
async function changeLocale(interaction) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.locale;
if (!(await checkPerm(interaction.member, 'locale'))) {
await interaction.reply({content: functionLocale.authDenied, ephemeral: true})
return;
}
const newLocale = interaction.options.getString('locale');
if (newLocale !== config.locale) {
if (config == null) {
config = new ServerConfig()
config.guildID = interaction.guild.id.toString();
config.permissions = {
roleMenu: [], locale: []
}
}
config.locale = newLocale;
const messageLocale = locales.get(newLocale).misc.messageTemplates.roleDropdown
const menus = await RoleMenu.find({guildID: interaction.guild.id.toString()});
await Promise.all(menus.map(async (menu) => {
console.log(menu);
const message = await (await interaction.guild.channels.fetch(menu.channelID)).messages.fetch(menu.messageID);
let components = message.components;
components[0].components[0].options[components[0].components[0].options.map((option) => option.value).indexOf('select_reset')].label = messageLocale.selectResetText;
components[0].components[0].placeholder = messageLocale.placeholder;
await message.edit({content: message.content, components});
return true;
}));
await config.save();
await interaction.reply({content: locales.get(newLocale).components.locale.localeApplied, ephemeral: true});
await registerCommands(interaction.guild.id.toString(), './commands');
} else {
await interaction.reply({content: functionLocale.sameLocale, ephemeral: true});
}
}
const slashCommandHandler = async (interaction) => {
if (interaction.commandName === 'change_locale') {
await changeLocale(interaction);
}
}
module.exports = {
slashCommandHandler
}
const ServerConfig = require('../models/ServerConfig');
const {Permissions} = require('discord.js');
const locales = require("../util/locale");
async function assignPermission(interaction) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.permConfig;
if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) {
const role = interaction.options.getRole('role');
const perm = interaction.options.getString('permission');
let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
if (config == null) {
config = new ServerConfig();
config.guildID = interaction.guild.id.toString();
......@@ -15,15 +21,30 @@ async function assignPermission(interaction) {
if (!config.permissions.roleMenu.includes(role.id.toString())) {
config.permissions.roleMenu.push(role.id.toString());
}
} else if (perm === 'locale') {
if (!config.permissions.locale.includes(role.id.toString())) {
config.permissions.locale.push(role.id.toString());
}
}
await config.save();
await interaction.reply({content: `Role ${role.name} has been added to ${perm} permission.`, ephemeral: true});
await interaction.reply({
content: functionLocale.replyAssign
.replaceAll("$$ROLE$$", `${role.name}`)
.replaceAll('$$PERM$$', `${perm}`),
ephemeral: true
});
} else {
await interaction.reply({content: 'Only administrators can access this command.', ephemeral: true});
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true});
}
}
async function revokePermission(interaction) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.permConfig;
if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) {
const role = interaction.options.getRole('role');
const perm = interaction.options.getString('permission');
......@@ -37,18 +58,30 @@ async function revokePermission(interaction) {
if (config.permissions.roleMenu.includes(role.id.toString())) {
config.permissions.roleMenu.splice(config.permissions.roleMenu.indexOf(role.id.toString()), 1);
}
} else if (perm === 'locale') {
if (config.permissions.locale.includes(role.id.toString())) {
config.permissions.locale.splice(config.permissions.locale.indexOf(role.id.toString()), 1);
}
}
await config.save();
await interaction.reply({
content: `Role ${role.name} has been removed from ${perm} permission.`,
content: functionLocale.replyRevoke
.replaceAll("$$ROLE$$", `${role.name}`)
.replaceAll('$$PERM$$', `${perm}`),
ephemeral: true
});
} else {
await interaction.reply({content: 'Only administrators can access this command.', ephemeral: true});
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true});
}
}
async function listPermissions(interaction) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.permConfig;
if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
if (config == null) {
......@@ -58,7 +91,12 @@ async function listPermissions(interaction) {
}
const roles = await Promise.all(config.permissions.roleMenu.map(async (roleID) => (await interaction.guild.roles.fetch(roleID)).name));
await interaction.reply({content: `List of Permissions:\n\nRole Menu: ${roles.join(',')}`, ephemeral: true});
await interaction.reply({
content: functionLocale.replyList.replaceAll('$$ROLEMENU$$', `${roles.join(',')}`),
ephemeral: true
});
} else {
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true});
}
}
......
const RoleMenu = require('../models/RoleMenu');
const ServerConfig = require('../models/ServerConfig');
const {MessageActionRow, MessageSelectMenu} = require("discord.js");
const checkPerm = require('../util/perm');
const locales = require("../util/locale");
// slashcommand handler
async function addRoleMenu(interaction) {
const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.roleMenu;
const messageLocale = locales.get(locale).misc.messageTemplates.roleDropdown;
if (!(await checkPerm(interaction.member, 'role_menu'))) {
await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true})
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true});
return;
}
const channel = interaction.options.getChannel('channel');
......@@ -16,10 +25,10 @@ async function addRoleMenu(interaction) {
.addComponents(
new MessageSelectMenu()
.setCustomId('selectRole')
.setPlaceholder("Select a role.")
.setPlaceholder(messageLocale.placeholder)
.addOptions([
{
label: 'Reset Selection',
label: messageLocale.selectResetText,
value: 'select_reset'
}
])
......@@ -33,42 +42,64 @@ async function addRoleMenu(interaction) {
menu.type = type;
menu.roles = [];
await menu.save();
await interaction.reply({content: 'Role Menu has been created.', ephemeral: true});
await interaction.reply({content: functionLocale.roleMenuCreated, ephemeral: true});
}
async function deleteRoleMenu(interaction) {
const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.roleMenu;
if (!(await checkPerm(interaction.member, 'role_menu'))) {
await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true})
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
return;
}
const channel = interaction.options.getChannel('channel');
const messageID = interaction.options.getString('message_id');
let menu = await RoleMenu.findOne({guildID: channel.guild.id, channelID: channel.id, messageID});
if (channel.isText()) {
const message = await channel.messages.fetch(messageID);
if (message != null) {
if (menu != null) {
try {
await RoleMenu.deleteOne({_id: menu._id});
await message.delete();
await interaction.reply({content: 'Menu has been deleted.', ephemeral: true});
} catch (e) {
await interaction.reply({content: 'Deleting the Menu has failed.', ephemeral: true});
var message = null;
var messageSuccess = true;
try {
message = await channel.messages.fetch(messageID);
} catch (e) {
messageSuccess = false;
}
if (messageSuccess) {
if (message != null) {
if (menu != null) {
try {
await RoleMenu.deleteOne({_id: menu._id});
await message.delete();
await interaction.reply({content: functionLocale.roleMenuDeleted, ephemeral: true});
} catch (e) {
await interaction.reply({content: functionLocale.roleMenuDeletedFailed, ephemeral: true});
}
} else {
await interaction.reply({content: functionLocale.notMenuMessage, ephemeral: true});
}
} else {
await interaction.reply({content: 'Please select a menu message.', ephemeral: true});
await interaction.reply({content: functionLocale.messageIdNotFound, ephemeral: true});
}
} else {
await interaction.reply({content: 'The message ID does not exist in this channel.', ephemeral: true});
await interaction.reply({content: functionLocale.invalidMessageId, ephemeral: true})
}
} else {
await interaction.reply({content: 'Please select a text channel.', ephemeral: true});
await interaction.reply({content: functionLocale