diff --git a/locales/en.json b/locales/en.json index 5cc2e89..ee66554 100644 --- a/locales/en.json +++ b/locales/en.json @@ -989,5 +989,11 @@ "label-jump": "Jump to Message", "no-message-link": "This ping was blocked by AutoMod", "list-entry-text": "%index. **Pinged %target** at %time\n%link" + }, + "name-list-cleaner": { + "owner-cannot-be-renamed": "The owner of the server (%u) cannot be renamed.", + "nickname-error": "An error occurred while trying to change the nickname of %u: %e", + "nickname-reset": "The nickname of %u has been reset, as it started with a disallowed character.", + "nickname-changed": "The nickname of %u has been changed, as it started with a disallowed character." } } diff --git a/modules/name-list-cleaner/configs/config.json b/modules/name-list-cleaner/configs/config.json new file mode 100644 index 0000000..9180dbe --- /dev/null +++ b/modules/name-list-cleaner/configs/config.json @@ -0,0 +1,90 @@ +{ + "description": { + "en": "Configure the function of the module here", + "de": "Stelle hier die Funktionen des Modules ein" + }, + "humanName": { + "en": "Configuration", + "de": "Konfiguration" + }, + "filename": "config.json", + "content": [ + { + "name": "keepNickname", + "humanName": { + "en": "Keep nickname", + "de": "Nickname behalten" + }, + "default": { + "en": true + }, + "description": { + "en": "If yes: special characters will be removed from nicknames; if no: the nickname will be removed and the username will be shown instead.", + "de": "Wenn ja: Sonderzeichen werden aus den Nicknames entfernt; wenn nein: der Nickname wird entfernt und stattdessen der Benutzername angezeigt." + }, + "type": "boolean" + }, + { + "name": "symbolWhitelist", + "humanName": { + "en": "Character Whitelist/Blacklist", + "de": "Zeichen Whitelist/Blacklist" + }, + "default": { + "en": [] + }, + "description": { + "en": "A list of characters that should be allowed (whitelist) or blocked (blacklist) at the start of usernames. If the list is empty, all non-alphanumeric characters will be removed.", + "de": "Eine Liste von Zeichen, die am Anfang von Benutzernamen erlaubt (Whitelist) oder blockiert (Blacklist) werden sollen. Wenn die Liste leer ist, werden alle nicht-alphanumerischen Zeichen entfernt." + }, + "type": "array", + "content": "string" + }, + { + "name": "isBlacklist", + "humanName": { + "en": "Use blacklist instead of whitelist", + "de": "Blacklist statt Whitelist verwenden" + }, + "default": { + "en": false + }, + "description": { + "en": "If yes: the list of characters will be treated as a blacklist (characters in the list will be blocked); if no: the list will be treated as a whitelist (only characters in the list and alphanumeric characters will be allowed).", + "de": "Wenn ja: die Liste der Zeichen wird als Blacklist behandelt (Zeichen in der Liste werden blockiert); wenn nein: die Liste wird als Whitelist behandelt (nur Zeichen in der Liste und alphanumerische Zeichen werden erlaubt)." + }, + "type": "boolean" + }, + { + "name": "userWhitelist", + "humanName": { + "en": "User Whitelist", + "de": "Benutzer-Whitelist" + }, + "default": { + "en": [] + }, + "description": { + "en": "A list of user IDs that should be exempt from the username check. Usernames of these users will not be modified.", + "de": "Eine Liste von Benutzer-IDs, die von der Benutzernamenprüfung ausgenommen werden sollen. Die Benutzernamen dieser Benutzer werden nicht geändert." + }, + "type": "array", + "content": "userID" + }, + { + "name": "alsoCheckUsernames", + "humanName": { + "en": "Also check usernames", + "de": "Auch Benutzernamen überprüfen" + }, + "default": { + "en": false + }, + "description": { + "en": "If yes: not only nicknames but also usernames will be checked for special characters and modified accordingly. If no: only nicknames will be checked and modified, usernames will be left unchanged.", + "de": "Wenn ja: nicht nur Nicknames, sondern auch Benutzernamen werden auf Sonderzeichen überprüft und entsprechend geändert. Wenn nein: nur Nicknames werden überprüft und geändert, Benutzernamen bleiben unverändert." + }, + "type": "boolean" + } + ] +} \ No newline at end of file diff --git a/modules/name-list-cleaner/events/botReady.js b/modules/name-list-cleaner/events/botReady.js new file mode 100644 index 0000000..aeb44e6 --- /dev/null +++ b/modules/name-list-cleaner/events/botReady.js @@ -0,0 +1,7 @@ +const {renameMember} = require('../renameMember'); + +module.exports.run = async function (client) { + for (const member of client.guild.members.cache.values()) { + await renameMember(client, member); + } +} \ No newline at end of file diff --git a/modules/name-list-cleaner/events/guildMemberUpdate.js b/modules/name-list-cleaner/events/guildMemberUpdate.js new file mode 100644 index 0000000..1e8d39d --- /dev/null +++ b/modules/name-list-cleaner/events/guildMemberUpdate.js @@ -0,0 +1,9 @@ +const {renameMember} = require("../renameMember"); +module.exports.run = async function (client, oldGuildMember, newGuildMember) { + + if (!client.botReadyAt) return; + if (newGuildMember.guild.id !== client.guild.id) return; + if (oldGuildMember.nickname === newGuildMember.nickname && oldGuildMember.user.username === newGuildMember.user.username) return; + await renameMember(client, newGuildMember); +} + diff --git a/modules/name-list-cleaner/module.json b/modules/name-list-cleaner/module.json new file mode 100644 index 0000000..890ebd1 --- /dev/null +++ b/modules/name-list-cleaner/module.json @@ -0,0 +1,24 @@ +{ + "name": "name-list-cleaner", + "humanReadableName": { + "en": "Name List Cleaner", + "de": "Namenslisten Cleaner" + }, + "author": { + "name": "hfgd", + "link": "https://github.com/hfgd123", + "scnxOrgID": "2" + }, + "openSourceURL": "https://github.com/hfgd123/CustomDCBot/tree/main/modules/name-list-cleaner", + "config-example-files": [ + "configs/config.json" + ], + "events-dir": "/events", + "tags": [ + "tools" + ], + "description": { + "en": "Remove special characters from the beginning of usernames", + "de": "Entferne Sonderzeichen vom Anfang von Benutzernamen" + } +} \ No newline at end of file diff --git a/modules/name-list-cleaner/renameMember.js b/modules/name-list-cleaner/renameMember.js new file mode 100644 index 0000000..b6d5242 --- /dev/null +++ b/modules/name-list-cleaner/renameMember.js @@ -0,0 +1,65 @@ +const {localize} = require("../../src/functions/localize"); +renameMember = async function (client, guildMember) { + let newName; + const moduleConf = client.configurations['name-list-cleaner']['config']; + if (moduleConf.userWhitelist.includes(guildMember.user.id)) return; + + + if (guildMember.nickname !== null) { + newName = await checkUsername(client, guildMember.nickname, false); + if (newName === guildMember.nickname) return; + } else if (moduleConf.alsoCheckUsernames) { + newName = await checkUsername(client, guildMember.user.username, true); + if (newName === guildMember.user.username) return; + } else return; + if (guildMember.guild.ownerId === guildMember.id) { + client.logger.error('[name-list-cleaner] ' + localize('name-list-cleaner', 'owner-cannot-be-renamed', {u: guildMember.user.username})) + return; + } + if (moduleConf.keepNickname) { + try { + await guildMember.setNickname(newName, localize('name-list-cleaner', 'nickname-changed', {u: guildMember.user.username})); + } catch (e) { + client.logger.error('[name-list-cleaner] ' + localize('name-list-cleaner', 'nickname-error', {u: guildMember.user.username, e: e})) + } + } else { + if (guildMember.nickname === null) { + return; + } + try { + await guildMember.setNickname(null, localize('name-list-cleaner', 'nickname-reset', {u: guildMember.user.username})); + } catch (e) { + client.logger.error('[name-list-cleaner] ' + localize('name-list-cleaner', 'nickname-error', {u: guildMember.user.username, e: e})) + } + } +} + +module.exports.renameMember = renameMember; + +async function checkUsername(client, name, isUsername) { + const moduleConf = client.configurations['name-list-cleaner']['config']; + if (name.length === 0) { + if (isUsername) { + return 'User' + } else { + return null; + } + } + if (moduleConf.symbolWhitelist.length === 0) { + if (name.charAt(0).match(/^[a-zA-Z0-9]$/)) { + return name; + } else { + return await checkUsername(client, name.substring(1), isUsername); + } + } else if (!moduleConf.symbolWhitelist.includes(name.charAt(0)) && !moduleConf.isBlacklist) { + if (name.charAt(0).match(/^[a-zA-Z0-9]$/)) { + return name; + } else { + return await checkUsername(client, name.substring(1), isUsername); + } + } else if (moduleConf.symbolWhitelist.includes(name.charAt(0)) && moduleConf.isBlacklist) { + return await checkUsername(client, name.substring(1), isUsername); + } else { + return name; + } +} \ No newline at end of file