/** * @name PermissionsViewer * @description Allows you to view a user's permissions. Thanks to Noodlebox for the idea! * @version 0.3.2 * @author Zerebos * @authorId 249746236008169473 * @website https://github.com/zerebos/BetterDiscordAddons/tree/master/Plugins/PermissionsViewer * @source https://raw.githubusercontent.com/zerebos/BetterDiscordAddons/master/Plugins/PermissionsViewer/PermissionsViewer.plugin.js */ /*@cc_on @if (@_jscript) // Offer to self-install for clueless users that try to run this directly. var shell = WScript.CreateObject("WScript.Shell"); var fs = new ActiveXObject("Scripting.FileSystemObject"); var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\\BetterDiscord\\plugins"); var pathSelf = WScript.ScriptFullName; // Put the user at ease by addressing them in the first person shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30); if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); } else if (!fs.FolderExists(pathPlugins)) { shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); // Show the user where to put plugins in the future shell.Exec("explorer " + pathPlugins); shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); } WScript.Quit(); @else@*/ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/plugins/PermissionsViewer/index.ts var index_exports = {}; __export(index_exports, { default: () => PermissionsViewer }); module.exports = __toCommonJS(index_exports); // src/common/plugin.ts var Plugin = class { meta; manifest; settings; defaultSettings; LocaleManager; get strings() { if (!this.manifest.strings) return {}; const locale = this.LocaleManager?.locale.split("-")[0] ?? "en"; if (this.manifest.strings.hasOwnProperty(locale)) return this.manifest.strings[locale]; if (this.manifest.strings.hasOwnProperty("en")) return this.manifest.strings.en; return this.manifest.strings; } constructor(meta, zplConfig) { this.meta = meta; this.manifest = zplConfig; if (typeof this.manifest.config !== "undefined") { this.defaultSettings = {}; for (let s = 0; s < this.manifest.config.length; s++) { const current = this.manifest.config[s]; if (current.type != "category") { this.defaultSettings[current.id] = current.value; } else { for (let si = 0; si < current.settings.length; si++) { const subCurrent = current.settings[si]; this.defaultSettings[subCurrent.id] = subCurrent.value; } } } this.settings = BdApi.Utils.extend({}, this.defaultSettings); } const currentVersionInfo = BdApi.Data.load(this.meta.name, "version"); if (currentVersionInfo !== this.meta.version) { this.#showChangelog(); BdApi.Data.save(this.meta.name, "version", this.meta.version); } if (this.manifest.strings) this.LocaleManager = BdApi.Webpack.getByKeys("locale", "initialize"); if (this.manifest.config && !this.getSettingsPanel) { this.getSettingsPanel = () => { this.#updateConfig(); return BdApi.UI.buildSettingsPanel({ onChange: (_, id, value) => { this.settings[id] = value; this.saveSettings(); }, settings: this.manifest.config }); }; } } async start() { BdApi.Logger.info(this.meta.name, `version ${this.meta.version} has started.`); if (this.defaultSettings) this.settings = this.loadSettings(); if (typeof this.onStart == "function") this.onStart(); } stop() { BdApi.Logger.info(this.meta.name, `version ${this.meta.version} has stopped.`); if (typeof this.onStop == "function") this.onStop(); } #showChangelog() { if (typeof this.manifest.changelog == "undefined") return; const changelog = { title: this.meta.name + " Changelog", subtitle: `v${this.meta.version}`, changes: [] }; if (!Array.isArray(this.manifest.changelog)) Object.assign(changelog, this.manifest.changelog); else changelog.changes = this.manifest.changelog; BdApi.UI.showChangelogModal(changelog); } saveSettings() { BdApi.Data.save(this.meta.name, "settings", this.settings); } loadSettings() { return BdApi.Utils.extend({}, this.defaultSettings ?? {}, BdApi.Data.load(this.meta.name, "settings")); } #updateConfig() { if (!this.manifest.config) return; for (const setting of this.manifest.config) { if (setting.type !== "category") { setting.value = this.settings[setting.id] ?? setting.value; } else { for (const subsetting of setting.settings) { subsetting.value = this.settings[subsetting.id] ?? subsetting.value; } } } } buildSettingsPanel(onChange) { this.#updateConfig(); return BdApi.UI.buildSettingsPanel({ onChange: (groupId, id, value) => { this.settings[id] = value; onChange?.(groupId, id, value); this.saveSettings(); }, settings: this.manifest.config }); } }; // src/common/formatstring.ts function formatString(stringToFormat, ...replacements) { for (let v = 0; v < replacements.length; v++) { const values = replacements[v]; for (const val in values) { let replacement = values[val]; if (Array.isArray(replacement)) replacement = JSON.stringify(replacement); if (typeof replacement === "object" && replacement !== null) replacement = replacement.toString(); stringToFormat = stringToFormat.replace(new RegExp(`{{${val}}}`, "g"), replacement.toString()); } } return stringToFormat; } // src/plugins/PermissionsViewer/config.ts var manifest = { info: { name: "PermissionsViewer", authors: [{ name: "Zerebos", discord_id: "249746236008169473", github_username: "zerebos", twitter_username: "IAmZerebos" }], version: "0.3.2", description: "Allows you to view a user's permissions. Thanks to Noodlebox for the idea!", github: "https://github.com/zerebos/BetterDiscordAddons/tree/master/Plugins/PermissionsViewer", github_raw: "https://raw.githubusercontent.com/zerebos/BetterDiscordAddons/master/Plugins/PermissionsViewer/PermissionsViewer.plugin.js" }, changelog: [ { title: "Fixed Modal", type: "fixed", items: [ "Fixed the permissions modal not having a backdrop for some users." ] } ], config: [ { type: "switch", id: "contextMenus", name: "Context Menus", value: true }, { type: "switch", id: "popouts", name: "Popouts", value: true }, { type: "radio", id: "displayMode", name: "Modal Display Mode", value: "compact", options: [ { name: "Cozy", value: "cozy" }, { name: "Compact", value: "compact" } ] } ], strings: { es: { contextMenuLabel: "Permisos", popoutLabel: "Permisos", modal: { header: "Permisos de {{name}}", rolesLabel: "Roles", permissionsLabel: "Permisos", owner: "@propietario" }, settings: { popouts: { name: "Mostrar en Popouts", note: "Mostrar los permisos de usuario en popouts como los roles." }, contextMenus: { name: "Bot\xF3n de men\xFA contextual", note: "A\xF1adir un bot\xF3n para ver permisos en los men\xFAs contextuales." } } }, pt: { contextMenuLabel: "Permiss\xF5es", popoutLabel: "Permiss\xF5es", modal: { header: "Permiss\xF5es de {{name}}", rolesLabel: "Cargos", permissionsLabel: "Permiss\xF5es", owner: "@dono" }, settings: { popouts: { name: "Mostrar em Popouts", note: "Mostrar as permiss\xF5es em popouts como os cargos." }, contextMenus: { name: "Bot\xE3o do menu de contexto", note: "Adicionar um bot\xE3o parar ver permiss\xF5es ao menu de contexto." } } }, de: { contextMenuLabel: "Berechtigungen", popoutLabel: "Berechtigungen", modal: { header: "{{name}}s Berechtigungen", rolesLabel: "Rollen", permissionsLabel: "Berechtigungen", owner: "@eigent\xFCmer" }, settings: { popouts: { name: "In Popouts anzeigen", note: "Zeigt die Gesamtberechtigungen eines Benutzers in seinem Popup \xE4hnlich den Rollen an." }, contextMenus: { name: "Kontextmen\xFC-Schaltfl\xE4che", note: "F\xFCgt eine Schaltfl\xE4che hinzu, um die Berechtigungen mithilfe von Kontextmen\xFCs anzuzeigen." } } }, en: { contextMenuLabel: "Permissions", popoutLabel: "Permissions", modal: { header: "{{name}}'s Permissions", rolesLabel: "Roles", permissionsLabel: "Permissions", owner: "@owner" }, settings: { popouts: { name: "Show In Popouts", note: "Shows a user's total permissions in their popout similar to roles." }, contextMenus: { name: "Context Menu Button", note: "Adds a button to view the permissions modal to select context menus." }, displayMode: { name: "Modal Display Mode" } } }, ru: { contextMenuLabel: "\u041F\u043E\u043B\u043D\u043E\u043C\u043E\u0447\u0438\u044F", popoutLabel: "\u041F\u043E\u043B\u043D\u043E\u043C\u043E\u0447\u0438\u044F", modal: { header: "\u041F\u043E\u043B\u043D\u043E\u043C\u043E\u0447\u0438\u044F {{name}}", rolesLabel: "\u0420\u043E\u043B\u0438", permissionsLabel: "\u041F\u043E\u043B\u043D\u043E\u043C\u043E\u0447\u0438\u044F", owner: "\u0412\u043B\u0430\u0434\u0435\u043B\u0435\u0446" }, settings: { popouts: { name: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u043E \u0432\u0441\u043F\u043B\u044B\u0432\u0430\u044E\u0449\u0438\u0445 \u043E\u043A\u043D\u0430\u0445", note: "\u041E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u043F\u043E\u043B\u043D\u043E\u043C\u043E\u0447\u0438\u044F \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0432 \u0438\u0445 \u0432\u0441\u043F\u043B\u044B\u0432\u0430\u044E\u0449\u0435\u043C \u043E\u043A\u043D\u0435, \u0430\u043D\u0430\u043B\u043E\u0433\u0438\u0447\u043D\u043E\u043C \u0440\u043E\u043B\u044F\u043C." }, contextMenus: { name: "\u041A\u043D\u043E\u043F\u043A\u0430 \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u043D\u043E\u0433\u043E \u043C\u0435\u043D\u044E", note: "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043A\u043D\u043E\u043F\u043A\u0443 \u0434\u043B\u044F \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u043F\u043E\u043B\u043D\u043E\u043C\u043E\u0447\u0438\u0439 \u0441 \u043F\u043E\u043C\u043E\u0449\u044C\u044E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u043D\u044B\u0445 \u043C\u0435\u043D\u044E." } } }, nl: { contextMenuLabel: "Permissies", popoutLabel: "Permissies", modal: { header: "{{name}}'s Permissies", rolesLabel: "Rollen", permissionsLabel: "Permissies", owner: "@eigenaar" }, settings: { popouts: { name: "Toon in Popouts", note: "Toont de totale rechten van een gebruiker in zijn pop-out, vergelijkbaar met rollen." }, contextMenus: { name: "Contextmenuknop", note: "Voegt een knop toe om de machtigingsmodaliteit voor het selecteren van contextmenu's te bekijken." }, displayMode: { name: "Modal weergavemodus" } } } }, main: "index.ts" }; var config_default = manifest; // src/plugins/PermissionsViewer/styles.css var styles_default = ".perm-user-avatar {\n border-radius: 50%;\n width: 16px;\n height: 16px;\n margin-right: 3px;\n}\n\n.member-perms-header {\n color: var(--header-secondary);\n display: flex;\n justify-content: space-between;\n}\n\n.member-perms {\n display: flex;\n flex-wrap: wrap;\n margin-top: 2px;\n max-height: 160px;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.member-perms .member-perm .perm-circle {\n border-radius: 50%;\n height: 12px;\n margin: 0 8px 0 5px;\n width: 12px;\n}\n\n.member-perms .member-perm .name {\n margin-right: 4px;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.perm-details-button {\n cursor: pointer;\n height: 12px;\n}\n\n.perm-details {\n display: flex;\n justify-content: flex-end;\n}\n\n.member-perm-details {\n cursor: pointer;\n}\n\n.member-perm-details-button {\n fill: #72767d;\n height: 10px;\n}\n\n/* Modal */\n\n@keyframes permissions-backdrop {\n to { opacity: 0.85; }\n}\n\n@keyframes permissions-modal-wrapper {\n to { transform: scale(1); opacity: 1; }\n}\n\n@keyframes permissions-backdrop-closing {\n to { opacity: 0; }\n}\n\n@keyframes permissions-modal-wrapper-closing {\n to { transform: scale(0.7); opacity: 0; }\n}\n\n#permissions-modal-wrapper {\n z-index: 100;\n}\n\n#permissions-modal-wrapper .callout-backdrop {\n animation: permissions-backdrop 250ms ease;\n animation-fill-mode: forwards;\n opacity: 0;\n background-color: rgb(0, 0, 0);\n transform: translateZ(0px);\n}\n\n#permissions-modal-wrapper.closing .callout-backdrop {\n animation: permissions-backdrop-closing 200ms linear;\n animation-fill-mode: forwards;\n animation-delay: 50ms;\n opacity: 0.85;\n}\n\n#permissions-modal-wrapper.closing .modal-wrapper {\n animation: permissions-modal-wrapper-closing 250ms cubic-bezier(0.19, 1, 0.22, 1);\n animation-fill-mode: forwards;\n opacity: 1;\n transform: scale(1);\n}\n\n#permissions-modal-wrapper .modal-wrapper {\n animation: permissions-modal-wrapper 250ms cubic-bezier(0.175, 0.885, 0.32, 1.275);\n animation-fill-mode: forwards;\n transform: scale(0.7);\n transform-origin: 50% 50%;\n display: flex;\n align-items: center;\n box-sizing: border-box;\n contain: content;\n justify-content: center;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n user-select: none;\n z-index: 1000;\n}\n\n#permissions-modal-wrapper .modal-body {\n background-color: #36393f;\n height: 440px;\n width: auto;\n /*box-shadow: 0 0 0 1px rgba(32,34,37,.6), 0 2px 10px 0 rgba(0,0,0,.2);*/\n flex-direction: row;\n overflow: hidden;\n display: flex;\n flex: 1;\n contain: layout;\n position: relative;\n}\n\n#permissions-modal-wrapper #permissions-modal {\n contain: layout;\n flex-direction: column;\n pointer-events: auto;\n border: 1px solid rgba(28,36,43,.6);\n border-radius: 5px;\n box-shadow: 0 2px 10px 0 rgba(0,0,0,.2);\n overflow: hidden;\n}\n\n#permissions-modal-wrapper .header {\n background-color: #35393e;\n box-shadow: 0 2px 3px 0 rgba(0,0,0,.2);\n padding: 12px 20px;\n z-index: 1;\n color: #fff;\n font-size: 16px;\n font-weight: 700;\n line-height: 19px;\n}\n\n.role-side, .perm-side {\n flex-direction: column;\n padding-left: 6px;\n}\n\n.role-scroller, .perm-scroller {\n contain: layout;\n flex: 1;\n min-height: 1px;\n overflow-y: scroll;\n}\n\n#permissions-modal-wrapper .scroller-title {\n color: #fff;\n padding: 8px 0 4px 4px;\n margin-right: 8px;\n border-bottom: 1px solid rgba(0,0,0,0.3);\n display: none;\n}\n\n#permissions-modal-wrapper .role-side {\n width: auto;\n min-width: 150px;\n background: #2f3136;\n flex: 0 0 auto;\n overflow: hidden;\n display: flex;\n min-height: 1px;\n position: relative;\n}\n\n#permissions-modal-wrapper .role-scroller {\n contain: layout;\n flex: 1;\n min-height: 1px;\n overflow-y: scroll;\n padding-top: 8px;\n}\n\n#permissions-modal-wrapper .role-item {\n display: flex;\n border-radius: 2px;\n padding: 6px;\n margin-bottom: 5px;\n cursor: pointer;\n color: #dcddde;\n}\n\n#permissions-modal-wrapper .role-item:hover {\n background-color: rgba(0,0,0,0.1);\n}\n\n#permissions-modal-wrapper .role-item.selected {\n background-color: rgba(0,0,0,0.2);\n}\n\n#permissions-modal-wrapper .perm-side {\n width: 273px;\n background-color: #36393f;\n flex: 0 0 auto;\n display: flex;\n min-height: 1px;\n position: relative;\n padding-left: 10px;\n}\n\n#permissions-modal-wrapper .perm-item {\n box-shadow: inset 0 -1px 0 rgba(79,84,92,.3);\n box-sizing: border-box;\n height: 44px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n display: flex;\n}\n\n#permissions-modal-wrapper .perm-item.allowed svg {\n fill: #43B581;\n}\n\n#permissions-modal-wrapper .perm-item.denied svg {\n fill: #F04747;\n}\n\n#permissions-modal-wrapper .perm-name {\n display: inline;\n flex: 1;\n font-size: 16px;\n font-weight: 400;\n overflow: hidden;\n text-overflow: ellipsis;\n user-select: text;\n color: #dcddde;\n margin-left: 10px;\n}\n\n\n.member-perms::-webkit-scrollbar-thumb, .member-perms::-webkit-scrollbar-track,\n#permissions-modal-wrapper *::-webkit-scrollbar-thumb, #permissions-modal-wrapper *::-webkit-scrollbar-track {\n background-clip: padding-box;\n border-radius: 7.5px;\n border-style: solid;\n border-width: 3px;\n visibility: hidden;\n}\n\n.member-perms:hover::-webkit-scrollbar-thumb, .member-perms:hover::-webkit-scrollbar-track,\n#permissions-modal-wrapper *:hover::-webkit-scrollbar-thumb, #permissions-modal-wrapper *:hover::-webkit-scrollbar-track {\n visibility: visible;\n}\n\n.member-perms::-webkit-scrollbar-track,\n#permissions-modal-wrapper *::-webkit-scrollbar-track {\n border-width: initial;\n background-color: transparent;\n border: 2px solid transparent;\n}\n\n.member-perms::-webkit-scrollbar-thumb,\n#permissions-modal-wrapper *::-webkit-scrollbar-thumb {\n border: 2px solid transparent;\n border-radius: 4px;\n cursor: move;\n background-color: rgba(32,34,37,.6);\n}\n\n.member-perms::-webkit-scrollbar,\n#permissions-modal-wrapper *::-webkit-scrollbar {\n height: 8px;\n width: 8px;\n}\n\n\n\n.theme-light #permissions-modal-wrapper #permissions-modal {\n background: #fff;\n}\n\n.theme-light #permissions-modal-wrapper .modal-body {\n background: transparent;\n}\n\n.theme-light #permissions-modal-wrapper .header {\n background: transparent;\n color: #000;\n}\n\n.theme-light #permissions-modal-wrapper .role-side {\n background: rgba(0,0,0,.2);\n}\n\n.theme-light #permissions-modal-wrapper .perm-side {\n background: rgba(0,0,0,.1);\n}\n\n.theme-light #permissions-modal-wrapper .role-item,\n.theme-light #permissions-modal-wrapper .perm-name {\n color: #000;\n}\n\n#permissions-modal-wrapper #permissions-modal {\n width: auto;\n}"; // src/plugins/PermissionsViewer/jumbo.css var jumbo_default = "#permissions-modal-wrapper #permissions-modal {\n height: 840px;\n}\n\n#permissions-modal-wrapper #permissions-modal .perm-side {\n width: 500px;\n}\n\n#permissions-modal .perm-scroller {\n display: flex;\n flex-wrap: wrap;\n align-content: flex-start;\n}\n\n#permissions-modal .perm-item {\n width: 50%;\n}"; // src/plugins/PermissionsViewer/list.html var list_default = '