diff --git a/docs/commands.md b/docs/commands.md index 0651d4d2c..d42471df3 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -10,6 +10,7 @@ Slash Command | Description ------------- | ----------- [**/alarm**](commands.md#alarm) | Operations on Smart Alarms. +[**/blacklist**](commands.md#blacklist) | Blacklist a user from using the bot. [**/cctv**](commands.md#cctv) | Posts CCTV codes for a monument. [**/credentials**](commands.md#credentials) | Set/Clear the FCM Credentials for the user account. [**/help**](commands.md#help) | Display help message. @@ -38,6 +39,23 @@ Subcommand | Options | Description | Required ![Discord Slash Command alarm Image](images/alarms_edit.png) +## **/blacklist** + +> **Blacklist a user from using the bot.** + +Subcommand | Options | Description | Required +---------- | ------- | ----------- | -------- +`add` |   | Add user to the blacklist. |   +  | `discord_user` | The discord user. | `False` +  | `steamid` | The steamid of the user. | `False` +`remove` |   | Remove user from the blacklist. |   +  | `discord_user` | The discord user. | `False` +  | `steamid` | The steamid of the user. | `False` +`show` |   | Show blacklisted users. |   + +![Discord Slash Command blacklist Image](images/blacklist.png) + + ## **/cctv** > **Posts CCTV codes for a monument.** diff --git a/docs/full_list_features.md b/docs/full_list_features.md index 37725dc1a..31c631d6a 100644 --- a/docs/full_list_features.md +++ b/docs/full_list_features.md @@ -53,4 +53,5 @@ * Translate messages from different languages from teamchat. * Send a Text-To-Speech message from in-game to Discord teamchat channel. * Check the upkeep of all Tool Cupboard via the `upkeep` command. -* Get Facepunch news in Discord. \ No newline at end of file +* Get Facepunch news in Discord. +* Blacklist users from using the bot. \ No newline at end of file diff --git a/docs/images/blacklist.png b/docs/images/blacklist.png new file mode 100644 index 000000000..075c11c6b Binary files /dev/null and b/docs/images/blacklist.png differ diff --git a/src/commands/blacklist.js b/src/commands/blacklist.js new file mode 100644 index 000000000..1bd1ab6b8 --- /dev/null +++ b/src/commands/blacklist.js @@ -0,0 +1,252 @@ +/* + Copyright (C) 2023 Alexander Emanuelsson (alexemanuelol) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + https://github.com/alexemanuelol/rustplusplus + +*/ + +const Builder = require('@discordjs/builders'); + +const Constants = require('../util/constants.js'); +const DiscordEmbeds = require('../discordTools/discordEmbeds.js'); +const DiscordTools = require('../discordTools/discordTools.js'); +const PermissionHandler = require('../handlers/permissionHandler.js'); +const Scrape = require('../util/scrape.js'); + +module.exports = { + name: 'blacklist', + + getData(client, guildId) { + return new Builder.SlashCommandBuilder() + .setName('blacklist') + .setDescription(client.intlGet(guildId, 'commandsBlacklistDesc')) + .addSubcommand(subcommand => subcommand + .setName('add') + .setDescription(client.intlGet(guildId, 'commandsBlacklistAddDesc')) + .addUserOption(option => option + .setName('discord_user') + .setDescription(client.intlGet(guildId, 'commandsBlacklistDiscordUserDesc')) + .setRequired(false)) + .addStringOption(option => option + .setName('steamid') + .setDescription(client.intlGet(guildId, 'commandsBlacklistSteamidDesc')) + .setRequired(false))) + .addSubcommand(subcommand => subcommand + .setName('remove') + .setDescription(client.intlGet(guildId, 'commandsBlacklistRemoveDesc')) + .addUserOption(option => option + .setName('discord_user') + .setDescription(client.intlGet(guildId, 'commandsBlacklistDiscordUserDesc')) + .setRequired(false)) + .addStringOption(option => option + .setName('steamid') + .setDescription(client.intlGet(guildId, 'commandsBlacklistSteamidDesc')) + .setRequired(false))) + .addSubcommand(subcommand => subcommand + .setName('show') + .setDescription(client.intlGet(guildId, 'commandsBlacklistShowDesc'))); + }, + + async execute(client, interaction) { + const guildId = interaction.guildId; + const instance = client.getInstance(guildId); + + if (!await client.validatePermissions(interaction)) return; + + if (!client.isAdministrator(interaction)) { + const str = client.intlGet(guildId, 'missingPermission'); + await client.interactionReply(interaction, DiscordEmbeds.getActionInfoEmbed(1, str)); + client.log(client.intlGet(null, 'warningCap'), str); + return; + } + + await interaction.deferReply({ ephemeral: true }); + + const guild = DiscordTools.getGuild(guildId); + + switch (interaction.options.getSubcommand()) { + case 'add': { + const discordUser = interaction.options.getUser('discord_user'); + const steamid = interaction.options.getString('steamid'); + + if (discordUser === null && steamid === null) { + const str = client.intlGet(guildId, 'missingArguments'); + await client.interactionEditReply(interaction, DiscordEmbeds.getActionInfoEmbed(1, str)); + client.log(client.intlGet(null, 'warningCap'), str); + return; + } + + let successful = 0; + + let str = ''; + if (discordUser !== null) { + if (instance.blacklist['discordIds'].includes(discordUser.id)) { + str += client.intlGet(guildId, 'userAlreadyInBlacklist', { + user: `${discordUser.username} (${discordUser.id})` + }) + ' '; + successful = 1; + } + else { + instance.blacklist['discordIds'].push(discordUser.id); + client.setInstance(guildId, instance); + + await PermissionHandler.resetPermissionsAllChannels(client, guild); + + str += client.intlGet(guildId, 'userAddedToBlacklist', { + user: `${discordUser.username} (${discordUser.id})` + }) + ' '; + } + } + + if (steamid !== null) { + let name = ''; + const steamName = await Scrape.scrapeSteamProfileName(client, steamid); + if (steamName) name += `${steamName} (${steamid})`; + else name += `${steamid}`; + + if (instance.blacklist['steamIds'].includes(steamid)) { + str += client.intlGet(guildId, 'userAlreadyInBlacklist', { + user: name + }) + ' '; + successful = 1; + } + else { + instance.blacklist['steamIds'].push(steamid); + client.setInstance(guildId, instance); + str += client.intlGet(guildId, 'userAddedToBlacklist', { + user: name + }) + ' '; + } + } + + await client.interactionEditReply(interaction, DiscordEmbeds.getActionInfoEmbed(successful, str)); + client.log(client.intlGet(null, 'infoCap'), str); + return; + } break; + + case 'remove': { + const discordUser = interaction.options.getUser('discord_user'); + const steamid = interaction.options.getString('steamid'); + + if (discordUser === null && steamid === null) { + const str = client.intlGet(guildId, 'missingArguments'); + await client.interactionEditReply(interaction, DiscordEmbeds.getActionInfoEmbed(1, str)); + client.log(client.intlGet(null, 'warningCap'), str); + return; + } + + let successful = 0; + + let str = ''; + if (discordUser !== null) { + if (!instance.blacklist['discordIds'].includes(discordUser.id)) { + str += client.intlGet(guildId, 'userNotInBlacklist', { + user: `${discordUser.username} (${discordUser.id})` + }) + ' '; + successful = 1; + } + else { + instance.blacklist['discordIds'] = + instance.blacklist['discordIds'].filter(e => e !== discordUser.id) + client.setInstance(guildId, instance); + + await PermissionHandler.resetPermissionsAllChannels(client, guild); + + str += client.intlGet(guildId, 'userRemovedFromBlacklist', { + user: `${discordUser.username} (${discordUser.id})` + }) + ' '; + } + } + + if (steamid !== null) { + let name = ''; + const steamName = await Scrape.scrapeSteamProfileName(client, steamid); + if (steamName) name += `${steamName} (${steamid})`; + else name += `${steamid}`; + + if (!instance.blacklist['steamIds'].includes(steamid)) { + str += client.intlGet(guildId, 'userNotInBlacklist', { + user: name + }) + ' '; + successful = 1; + } + else { + instance.blacklist['steamIds'] = + instance.blacklist['steamIds'].filter(e => e !== steamid) + client.setInstance(guildId, instance); + str += client.intlGet(guildId, 'userRemovedFromBlacklist', { + user: name + }) + ' '; + } + } + + + await client.interactionEditReply(interaction, DiscordEmbeds.getActionInfoEmbed(successful, str)); + client.log(client.intlGet(null, 'infoCap'), str); + return; + } break; + + case 'show': { + let discordUsers = ''; + let steamIds = ''; + + for (const discordId of instance.blacklist['discordIds']) { + const user = await DiscordTools.getUserById(guildId, discordId); + let name = ''; + if (user) name = `${user.user.username} (${user.id})`; + else name = `${discordId}`; + + discordUsers += `${name}\n`; + } + + for (const steamId of instance.blacklist['steamIds']) { + let name = ''; + const steamName = await Scrape.scrapeSteamProfileName(client, steamId); + if (steamName) name = `${steamName} (${steamId})`; + else name = `${steamId}`; + + steamIds += `${name}\n`; + } + + await client.interactionEditReply(interaction, { + embeds: [DiscordEmbeds.getEmbed({ + color: Constants.COLOR_DEFAULT, + title: client.intlGet(interaction.guildId, 'blacklist'), + fields: [ + { + name: client.intlGet(interaction.guildId, 'discordUsers'), + value: discordUsers === '' ? '\u200B' : discordUsers, + inline: true + }, + { + name: 'SteamId', + value: steamIds === '' ? '\u200B' : steamIds, + inline: true + }] + })], + ephemeral: true + }); + + client.log(client.intlGet(guildId, 'infoCap'), client.intlGet(interaction.guildId, 'showingBlacklist')); + } break; + + default: { + } break; + } + + return; + }, +}; \ No newline at end of file diff --git a/src/commands/cctv.js b/src/commands/cctv.js index 00736f491..e1dbfd142 100644 --- a/src/commands/cctv.js +++ b/src/commands/cctv.js @@ -48,6 +48,8 @@ module.exports = { }, async execute(client, interaction) { + if (!await client.validatePermissions(interaction)) return; + const monument = interaction.options.getString('monument'); const cctvCodes = client.cctv.getCodes(monument); const dynamic = client.cctv.isDynamic(monument); diff --git a/src/commands/help.js b/src/commands/help.js index 4fdb0ca8d..dc9b5ea84 100644 --- a/src/commands/help.js +++ b/src/commands/help.js @@ -32,6 +32,8 @@ module.exports = { }, async execute(client, interaction) { + if (!await client.validatePermissions(interaction)) return; + await DiscordMessages.sendHelpMessage(interaction); client.log(client.intlGet(null, 'infoCap'), client.intlGet(interaction.guildId, 'commandsHelpDesc')); }, diff --git a/src/commands/reset.js b/src/commands/reset.js index 3073aec1f..aef6ce008 100644 --- a/src/commands/reset.js +++ b/src/commands/reset.js @@ -81,7 +81,13 @@ module.exports = { const category = await require('../discordTools/SetupGuildCategory')(client, guild); await require('../discordTools/SetupGuildChannels')(client, guild, category); - await PermissionHandler.removeViewPermission(client, guild); + const perms = PermissionHandler.getPermissionsRemoved(client, guild); + try { + await category.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } await DiscordTools.clearTextChannel(guild.id, instance.channelId.information, 100); await DiscordTools.clearTextChannel(guild.id, instance.channelId.switches, 100); @@ -106,7 +112,7 @@ module.exports = { await require('../discordTools/SetupTrackers')(client, guild); - await PermissionHandler.resetPermissions(client, guild); + await PermissionHandler.resetPermissionsAllChannels(client, guild); } break; case 'information': { @@ -120,28 +126,55 @@ module.exports = { } break; case 'servers': { - await PermissionHandler.removeViewPermission(client, guild); + const perms = PermissionHandler.getPermissionsRemoved(client, guild); + try { + const category = await DiscordTools.getCategoryById(guild.id, instance.channelId.category); + await category.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } + await require('../discordTools/SetupServerList')(client, guild); - await PermissionHandler.resetPermissions(client, guild); + + await PermissionHandler.resetPermissionsAllChannels(client, guild); } break; case 'settings': { - await PermissionHandler.removeViewPermission(client, guild); + const perms = PermissionHandler.getPermissionsRemoved(client, guild); + try { + const category = await DiscordTools.getCategoryById(guild.id, instance.channelId.category); + await category.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } + await require('../discordTools/SetupSettingsMenu')(client, guild, true); - await PermissionHandler.resetPermissions(client, guild); + + await PermissionHandler.resetPermissionsAllChannels(client, guild); } break; case 'switches': { await DiscordTools.clearTextChannel(guild.id, instance.channelId.switches, 100); await DiscordTools.clearTextChannel(guild.id, instance.channelId.switchGroups, 100); - await PermissionHandler.removeViewPermission(client, guild); + const perms = PermissionHandler.getPermissionsRemoved(client, guild); + try { + const category = await DiscordTools.getCategoryById(guild.id, instance.channelId.category); + await category.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } + const rustplus = client.rustplusInstances[guild.id]; if (rustplus && rustplus.isOperational) { await require('../discordTools/SetupSwitches')(client, rustplus); await require('../discordTools/SetupSwitchGroups')(client, rustplus); } - await PermissionHandler.resetPermissions(client, guild); + + await PermissionHandler.resetPermissionsAllChannels(client, guild); } break; case 'alarms': { @@ -154,18 +187,36 @@ module.exports = { case 'storagemonitors': { await DiscordTools.clearTextChannel(guild.id, instance.channelId.storageMonitors, 100); - await PermissionHandler.removeViewPermission(client, guild); + const perms = PermissionHandler.getPermissionsRemoved(client, guild); + try { + const category = await DiscordTools.getCategoryById(guild.id, instance.channelId.category); + await category.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } + const rustplus = client.rustplusInstances[guild.id]; if (rustplus && rustplus.isOperational) { await require('../discordTools/SetupStorageMonitors')(client, rustplus); } - await PermissionHandler.resetPermissions(client, guild); + + await PermissionHandler.resetPermissionsAllChannels(client, guild); } break; case 'trackers': { - await PermissionHandler.removeViewPermission(client, guild); + const perms = PermissionHandler.getPermissionsRemoved(client, guild); + try { + const category = await DiscordTools.getCategoryById(guild.id, instance.channelId.category); + await category.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } + await require('../discordTools/SetupTrackers')(client, guild); - await PermissionHandler.resetPermissions(client, guild); + + await PermissionHandler.resetPermissionsAllChannels(client, guild); } break; default: { diff --git a/src/commands/role.js b/src/commands/role.js index 8084bf2af..eafd10672 100644 --- a/src/commands/role.js +++ b/src/commands/role.js @@ -80,7 +80,7 @@ module.exports = { if (guild) { const category = await require('../discordTools/SetupGuildCategory')(client, guild); await require('../discordTools/SetupGuildChannels')(client, guild, category); - await PermissionHandler.resetPermissions(client, guild); + await PermissionHandler.resetPermissionsAllChannels(client, guild); } if (interaction.options.getSubcommand() === 'set') { diff --git a/src/discordTools/SetupGuildCategory.js b/src/discordTools/SetupGuildCategory.js index 905c259dd..9fd001d23 100644 --- a/src/discordTools/SetupGuildCategory.js +++ b/src/discordTools/SetupGuildCategory.js @@ -18,9 +18,8 @@ */ -const Discord = require('discord.js'); - const DiscordTools = require('../discordTools/discordTools.js'); +const PermissionHandler = require('../handlers/permissionHandler.js'); module.exports = async (client, guild) => { const instance = client.getInstance(guild.id); @@ -35,26 +34,7 @@ module.exports = async (client, guild) => { client.setInstance(guild.id, instance); } - const perms = []; - const everyoneAllow = []; - const everyoneDeny = []; - const roleAllow = []; - const roleDeny = []; - if (instance.role !== null) { - everyoneDeny.push(Discord.PermissionFlagsBits.ViewChannel); - everyoneDeny.push(Discord.PermissionFlagsBits.SendMessages); - roleAllow.push(Discord.PermissionFlagsBits.ViewChannel); - roleDeny.push(Discord.PermissionFlagsBits.SendMessages); - - perms.push({ id: guild.roles.everyone.id, deny: everyoneDeny }); - perms.push({ id: instance.role, allow: roleAllow, deny: roleDeny }); - } - else { - everyoneAllow.push(Discord.PermissionFlagsBits.ViewChannel); - everyoneDeny.push(Discord.PermissionFlagsBits.SendMessages); - - perms.push({ id: guild.roles.everyone.id, allow: everyoneAllow, deny: everyoneDeny }); - } + const perms = PermissionHandler.getPermissionsReset(client, guild, false); try { await category.permissionOverwrites.set(perms); diff --git a/src/discordTools/SetupGuildChannels.js b/src/discordTools/SetupGuildChannels.js index 26756c3b9..6144ed3e2 100644 --- a/src/discordTools/SetupGuildChannels.js +++ b/src/discordTools/SetupGuildChannels.js @@ -18,9 +18,8 @@ */ -const Discord = require('discord.js'); - const DiscordTools = require('../discordTools/discordTools.js'); +const PermissionHandler = require('../handlers/permissionHandler.js'); module.exports = async (client, guild, category) => { await addTextChannel(client.intlGet(guild.id, 'channelNameInformation'), 'information', client, guild, category); @@ -69,38 +68,7 @@ async function addTextChannel(name, idName, client, guild, parent, permissionWri } } - const perms = []; - const everyoneAllow = []; - const everyoneDeny = []; - const roleAllow = []; - const roleDeny = []; - if (instance.role !== null) { - if (permissionWrite) { - roleAllow.push(Discord.PermissionFlagsBits.SendMessages); - } - else { - roleDeny.push(Discord.PermissionFlagsBits.SendMessages); - } - - everyoneDeny.push(Discord.PermissionFlagsBits.ViewChannel); - everyoneDeny.push(Discord.PermissionFlagsBits.SendMessages); - roleAllow.push(Discord.PermissionFlagsBits.ViewChannel); - - perms.push({ id: guild.roles.everyone.id, deny: everyoneDeny }); - perms.push({ id: instance.role, allow: roleAllow, deny: roleDeny }); - } - else { - if (permissionWrite) { - everyoneAllow.push(Discord.PermissionFlagsBits.SendMessages); - } - else { - everyoneDeny.push(Discord.PermissionFlagsBits.SendMessages); - } - - everyoneAllow.push(Discord.PermissionFlagsBits.ViewChannel); - - perms.push({ id: guild.roles.everyone.id, allow: everyoneAllow, deny: everyoneDeny }); - } + const perms = PermissionHandler.getPermissionsReset(client, guild, permissionWrite); try { await channel.permissionOverwrites.set(perms); diff --git a/src/discordTools/discordMessages.js b/src/discordTools/discordMessages.js index 5e1b0f9bc..0554a5b81 100644 --- a/src/discordTools/discordMessages.js +++ b/src/discordTools/discordMessages.js @@ -531,6 +531,7 @@ module.exports = { sendCctvMessage: async function (interaction, monument, cctvCodes, dynamic) { const content = { embeds: [DiscordEmbeds.getCctvEmbed(interaction.guildId, monument, cctvCodes, dynamic)], + ephemeral: true } await Client.client.interactionReply(interaction, content); diff --git a/src/handlers/buttonHandler.js b/src/handlers/buttonHandler.js index 5c75ae0fb..b70be3eba 100644 --- a/src/handlers/buttonHandler.js +++ b/src/handlers/buttonHandler.js @@ -18,6 +18,8 @@ */ +const Discord = require('discord.js'); + const Config = require('../../config'); const DiscordMessages = require('../discordTools/discordMessages.js'); const DiscordTools = require('../discordTools/discordTools.js'); @@ -31,6 +33,11 @@ module.exports = async (client, interaction) => { const guildId = interaction.guildId; const rustplus = client.rustplusInstances[guildId]; + if (instance.blacklist['discordIds'].includes(interaction.user.id) && + !interaction.member.permissions.has(Discord.PermissionsBitField.Flags.Administrator)) { + return; + } + if (interaction.customId.startsWith('DiscordNotification')) { const ids = JSON.parse(interaction.customId.replace('DiscordNotification', '')); const setting = instance.notificationSettings[ids.setting]; diff --git a/src/handlers/modalHandler.js b/src/handlers/modalHandler.js index 0ed6d239e..8ba276db3 100644 --- a/src/handlers/modalHandler.js +++ b/src/handlers/modalHandler.js @@ -18,6 +18,8 @@ */ +const Discord = require('discord.js'); + const BattlemetricsAPI = require('../util/battlemetricsAPI.js'); const Constants = require('../util/constants.js'); const DiscordMessages = require('../discordTools/discordMessages.js'); @@ -27,6 +29,11 @@ module.exports = async (client, interaction) => { const instance = client.getInstance(interaction.guildId); const guildId = interaction.guildId; + if (instance.blacklist['discordIds'].includes(interaction.user.id) && + !interaction.member.permissions.has(Discord.PermissionsBitField.Flags.Administrator)) { + return; + } + if (interaction.customId.startsWith('CustomTimersEdit')) { const ids = JSON.parse(interaction.customId.replace('CustomTimersEdit', '')); const server = instance.serverList[ids.serverId]; diff --git a/src/handlers/permissionHandler.js b/src/handlers/permissionHandler.js index 9ec1d1fd7..eea76a1cc 100644 --- a/src/handlers/permissionHandler.js +++ b/src/handlers/permissionHandler.js @@ -18,49 +18,107 @@ */ +const Discord = require('discord.js'); + const DiscordTools = require('../discordTools/discordTools.js'); module.exports = { - removeViewPermission: async function (client, guild) { + getPermissionsReset: function (client, guild, permissionWrite = false) { const instance = client.getInstance(guild.id); - if (instance.channelId.category === null) return; + const perms = []; + const everyoneAllow = []; + const everyoneDeny = []; + const roleAllow = []; + const roleDeny = []; - const category = await DiscordTools.getCategoryById(guild.id, instance.channelId.category); + if (instance.role !== null) { + if (permissionWrite) { + roleAllow.push(Discord.PermissionFlagsBits.SendMessages); + } + else { + roleDeny.push(Discord.PermissionFlagsBits.SendMessages); + } + + everyoneDeny.push(Discord.PermissionFlagsBits.ViewChannel); + everyoneDeny.push(Discord.PermissionFlagsBits.SendMessages); + roleAllow.push(Discord.PermissionFlagsBits.ViewChannel); + + perms.push({ id: guild.roles.everyone.id, deny: everyoneDeny }); + perms.push({ id: instance.role, allow: roleAllow, deny: roleDeny }); + } + else { + if (permissionWrite) { + everyoneAllow.push(Discord.PermissionFlagsBits.SendMessages); + } + else { + everyoneDeny.push(Discord.PermissionFlagsBits.SendMessages); + } + + everyoneAllow.push(Discord.PermissionFlagsBits.ViewChannel); + + perms.push({ id: guild.roles.everyone.id, allow: everyoneAllow, deny: everyoneDeny }); + } + + for (const discordId of instance.blacklist['discordIds']) { + perms.push({ + id: discordId, + deny: [Discord.PermissionFlagsBits.ViewChannel, Discord.PermissionFlagsBits.SendMessages] + }); + } + + return perms; + }, + + getPermissionsRemoved: function (client, guild) { + const instance = client.getInstance(guild.id); + + const perms = []; if (instance.role !== null) { - await category.permissionOverwrites.edit( - instance.role, { - ViewChannel: false + perms.push({ + id: instance.role, + deny: [Discord.PermissionFlagsBits.ViewChannel, Discord.PermissionFlagsBits.SendMessages] }); } - await category.permissionOverwrites.edit( - guild.roles.everyone.id, { - ViewChannel: false + perms.push({ + id: guild.roles.everyone.id, + deny: [Discord.PermissionFlagsBits.ViewChannel, Discord.PermissionFlagsBits.SendMessages] }); + + return perms; }, - resetPermissions: async function (client, guild) { + resetPermissionsAllChannels: async function (client, guild) { const instance = client.getInstance(guild.id); if (instance.channelId.category === null) return; const category = await DiscordTools.getCategoryById(guild.id, instance.channelId.category); - - await category.permissionOverwrites.edit( - instance.role === null ? guild.roles.everyone.id : instance.role, { - ViewChannel: true - }); + if (category) { + const perms = module.exports.getPermissionsReset(client, guild); + try { + await category.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } + } for (const [name, id] of Object.entries(instance.channelId)) { - if (name !== 'commands' && name !== 'teamchat') continue; + const writePerm = (name !== 'commands' && name !== 'teamchat') ? false : true; const channel = DiscordTools.getTextChannelById(guild.id, id); - await channel.permissionOverwrites.edit( - instance.role === null ? guild.roles.everyone.id : instance.role, { - SendMessages: true - }); + if (channel) { + const perms = module.exports.getPermissionsReset(client, guild, writePerm); + try { + await channel.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } + } } }, } \ No newline at end of file diff --git a/src/handlers/selectMenuHandler.js b/src/handlers/selectMenuHandler.js index 66db44b08..5b352b0e3 100644 --- a/src/handlers/selectMenuHandler.js +++ b/src/handlers/selectMenuHandler.js @@ -18,6 +18,8 @@ */ +const Discord = require('discord.js'); + const DiscordMessages = require('../discordTools/discordMessages.js'); const DiscordSelectMenus = require('../discordTools/discordSelectMenus.js'); const DiscordTools = require('../discordTools/discordTools.js'); @@ -27,6 +29,11 @@ module.exports = async (client, interaction) => { const guildId = interaction.guildId; const rustplus = client.rustplusInstances[guildId]; + if (instance.blacklist['discordIds'].includes(interaction.user.id) && + !interaction.member.permissions.has(Discord.PermissionsBitField.Flags.Administrator)) { + return; + } + if (interaction.customId === 'language') { instance.generalSettings.language = interaction.values[0]; client.setInstance(guildId, instance); diff --git a/src/languages/en.json b/src/languages/en.json index 4568ea551..af0cd787a 100644 --- a/src/languages/en.json +++ b/src/languages/en.json @@ -38,6 +38,7 @@ "banditCamp": "Bandit Camp", "baseIsUnderAttack": "Your base is under attack!", "battlemetricsCap": "BATTLEMETRICS", + "blacklist": "Blacklist", "boomBox": "Boom Box", "bot": "bot", "broadcaster": "Broadcaster", @@ -141,6 +142,12 @@ "commandsAlarmEditDesc": "Edit the properties of a Smart Alarm.", "commandsAlarmEditIdDesc": "The ID of the Smart Alarm.", "commandsAlarmEditImageDesc": "Set the image that best represent the Smart Alarm.", + "commandsBlacklistAddDesc": "Add user to the blacklist.", + "commandsBlacklistDesc": "Blacklist a user from using the bot.", + "commandsBlacklistDiscordUserDesc": "The discord user.", + "commandsBlacklistRemoveDesc": "Remove user from the blacklist.", + "commandsBlacklistShowDesc": "Show blacklisted users.", + "commandsBlacklistSteamidDesc": "The steamid of the user.", "commandsCctvDesc": "Display CCTV codes for a monument", "commandsCredentialsAddDesc": "Add FCM Credentials.", "commandsCredentialsDesc": "Set/Clear the FCM Credentials for the user account.", @@ -281,6 +288,7 @@ "disconnectedCap": "DISCONNECTED", "disconnectedFromServer": "DISCONNECTED FROM SERVER.", "discordCap": "DISCORD", + "discordUsers": "Discord Users", "displayingMap": "Displaying {mapName} map.", "displayingOnlinePlayers": "Displaying online players.", "distanceDirectionGrid": "{distance}m in direction {direction}° [{grid}].", @@ -542,6 +550,7 @@ "shouldLeaderCommandOnlyForPairedSetting": "Should the leader command only work for people that are paired with the server?", "shouldSmartAlarmNotifyNotConnectedSetting": "Should Smart Alarms notify even if they are not setup on the connected rust server?", "shouldSmartAlarmsNotifyInGameSetting": "Should Smart Alarms notify In-Game?", + "showingBlacklist": "Showing the blacklist.", "showingSubscriptionList": "Showing the subscription list.", "sirenLight": "Siren Light", "six": "Six", @@ -643,8 +652,12 @@ "unknownInteraction": "Unknown Interaction...", "unmutedCap": "UNMUTED", "upkeep": "Upkeep", + "userAddedToBlacklist": "{user} was added to blacklist.", + "userAlreadyInBlacklist": "{user} already in blacklist.", "userJustConnected": "{name} just connected.", + "userNotInBlacklist": "{user} not in blacklist.", "userNotRegistered": "{user} is not registered.", + "userRemovedFromBlacklist": "{user} was removed from blacklist.", "userSaid": "{user} said, {text}", "vendingMachine": "Vending Machine", "vendingMachineDetectedSetting": "When a new Vending Machine is detected, send a notification.", diff --git a/src/rustplusEvents/message.js b/src/rustplusEvents/message.js index 415587552..a97b0fb48 100644 --- a/src/rustplusEvents/message.js +++ b/src/rustplusEvents/message.js @@ -72,6 +72,11 @@ async function messageBroadcastTeamMessage(rustplus, client, message) { message.broadcast.teamMessage.message.message = message.broadcast.teamMessage.message.message.replace(/^/g, ''); + if (instance.blacklist['steamIds'].includes(`${message.broadcast.teamMessage.message.steamId}`)) { + TeamChatHandler(rustplus, client, message.broadcast.teamMessage.message); + return; + } + const startsWithTrademark = message.broadcast.teamMessage.message.message .startsWith(instance.generalSettings.trademark); diff --git a/src/structures/DiscordBot.js b/src/structures/DiscordBot.js index d816cf400..913cf2ef3 100644 --- a/src/structures/DiscordBot.js +++ b/src/structures/DiscordBot.js @@ -195,10 +195,16 @@ class DiscordBot extends Discord.Client { let category = await require('../discordTools/SetupGuildCategory')(this, guild); await require('../discordTools/SetupGuildChannels')(this, guild, category); if (firstTime) { - await PermissionHandler.removeViewPermission(this, guild); + const perms = PermissionHandler.getPermissionsRemoved(this, guild); + try { + await category.permissionOverwrites.set(perms); + } + catch (e) { + /* Ignore */ + } } else { - await PermissionHandler.resetPermissions(this, guild); + await PermissionHandler.resetPermissionsAllChannels(this, guild); } require('../util/FcmListener')(this, guild); @@ -211,7 +217,7 @@ class DiscordBot extends Discord.Client { await require('../discordTools/SetupSettingsMenu')(this, guild); - if (firstTime) await PermissionHandler.resetPermissions(this, guild); + if (firstTime) await PermissionHandler.resetPermissionsAllChannels(this, guild); this.resetRustplusVariables(guild.id); } @@ -423,6 +429,11 @@ class DiscordBot extends Discord.Client { async validatePermissions(interaction) { const instance = this.getInstance(interaction.guildId); + if (instance.blacklist['discordIds'].includes(interaction.user.id) && + !interaction.member.permissions.has(Discord.PermissionsBitField.Flags.Administrator)) { + return false; + } + /* If role isn't setup yet, validate as true */ if (instance.role === null) return true; diff --git a/src/util/CreateInstanceFile.js b/src/util/CreateInstanceFile.js index a20c6b22d..a4fa795f4 100644 --- a/src/util/CreateInstanceFile.js +++ b/src/util/CreateInstanceFile.js @@ -61,7 +61,11 @@ module.exports = (client, guild) => { buy: [], sell: [] }, - teamChatColors: {} + teamChatColors: {}, + blacklist: { + discordIds: [], + steamIds: [] + } }; } else { @@ -169,6 +173,12 @@ module.exports = (client, guild) => { if (!instance.marketSubscriptionList.hasOwnProperty('buy')) instance.marketSubscriptionList['buy'] = []; if (!instance.marketSubscriptionList.hasOwnProperty('sell')) instance.marketSubscriptionList['sell'] = []; if (!instance.hasOwnProperty('teamChatColors')) instance.teamChatColors = {}; + if (!instance.hasOwnProperty('blacklist')) instance.blacklist = { + discordIds: [], + steamIds: [] + } + if (!instance.blacklist.hasOwnProperty('discordIds')) instance.blacklist['discordIds'] = []; + if (!instance.blacklist.hasOwnProperty('steamIds')) instance.blacklist['steamIds'] = []; for (const serverId of Object.keys(instance.serverList)) { if (!Object.keys(instance.serverListLite).includes(serverId)) {