├── NitroPerks.plugin.js └── README.md /NitroPerks.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name NitroPerks 3 | * @website https://github.com/respecting/NitroPerks 4 | * @source https://raw.githubusercontent.com/respecting/NitroPerks/main/NitroPerks.plugin.js 5 | * @updateUrl https://raw.githubusercontent.com/respecting/NitroPerks/main/NitroPerks.plugin.js 6 | */ 7 | /*@cc_on 8 | @if (@_jscript) 9 | 10 | // Offer to self-install for clueless users that try to run this directly. 11 | var shell = WScript.CreateObject("WScript.Shell"); 12 | var fs = new ActiveXObject("Scripting.FileSystemObject"); 13 | var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins"); 14 | var pathSelf = WScript.ScriptFullName; 15 | // Put the user at ease by addressing them in the first person 16 | 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); 17 | if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { 18 | shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); 19 | } else if (!fs.FolderExists(pathPlugins)) { 20 | shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); 21 | } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { 22 | fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); 23 | // Show the user where to put plugins in the future 24 | shell.Exec("explorer " + pathPlugins); 25 | shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); 26 | } 27 | WScript.Quit(); 28 | 29 | @else@*/ 30 | module.exports = (() => { 31 | const config = { 32 | "info": { 33 | "name": "NitroPerks", 34 | "authors": [{ 35 | "name": "lemons", 36 | "discord_id": "407348579376693260", 37 | "github_username": "respecting" 38 | }], 39 | "version": "1.3.6", 40 | "description": "Unlock all screensharing modes, and use cross-server emotes & gif emotes, Discord wide! (You CANNOT upload 100MB files though. :/)", 41 | "github": "https://github.com/respecting/NitroPerks", 42 | "github_raw": "https://raw.githubusercontent.com/respecting/NitroPerks/main/NitroPerks.plugin.js" 43 | }, 44 | "main": "NitroPerks.plugin.js" 45 | }; 46 | 47 | return !global.ZeresPluginLibrary ? class { 48 | constructor() { 49 | this._config = config; 50 | } 51 | getName() { 52 | return config.info.name; 53 | } 54 | getAuthor() { 55 | return config.info.authors.map(a => a.name).join(", "); 56 | } 57 | getDescription() { 58 | return config.info.description; 59 | } 60 | getVersion() { 61 | return config.info.version; 62 | } 63 | load() { 64 | BdApi.showConfirmationModal("Library Missing", `The library plugin needed for ${config.info.name} is missing. Please click Download Now to install it.`, { 65 | confirmText: "Download Now", 66 | cancelText: "Cancel", 67 | onConfirm: () => { 68 | require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => { 69 | if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 70 | await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r)); 71 | }); 72 | } 73 | }); 74 | } 75 | start() {} 76 | stop() {} 77 | } : (([Plugin, Api]) => { 78 | const plugin = (Plugin, Api) => { 79 | const { 80 | Patcher, 81 | DiscordModules, 82 | DiscordAPI, 83 | Settings, 84 | Toasts, 85 | PluginUtilities 86 | } = Api; 87 | return class NitroPerks extends Plugin { 88 | defaultSettings = { 89 | "emojiSize": "40", 90 | "screenSharing": false, 91 | "emojiBypass": true, 92 | "clientsidePfp": false, 93 | "pfpUrl": "", 94 | }; 95 | settings = PluginUtilities.loadSettings(this.getName(), this.defaultSettings); 96 | originalNitroStatus = 0; 97 | clientsidePfp; 98 | screenShareFix; 99 | getSettingsPanel() { 100 | return Settings.SettingPanel.build(_ => this.saveAndUpdate(), ...[ 101 | new Settings.SettingGroup("Features").append(...[ 102 | new Settings.Switch("High Quality Screensharing", "Enable or disable 1080p/source @ 60fps screensharing. This adapts to your current nitro status.", this.settings.screenSharing, value => this.settings.screenSharing = value) 103 | ]), 104 | new Settings.SettingGroup("Emojis").append( 105 | new Settings.Switch("Nitro Emotes Bypass", "Enable or disable using the Nitro Emote bypass.", this.settings.emojiBypass, value => this.settings.emojiBypass = value), 106 | new Settings.Slider("Size", "The size of the emoji in pixels. 40 is recommended.", 16, 64, this.settings.emojiSize, size=>this.settings.emojiSize = size, {markers:[16,20,32,40,64], stickToMarkers:true}) 107 | ), 108 | new Settings.SettingGroup("Profile Picture").append(...[ 109 | new Settings.Switch("Clientsided Profile Picture", "Enable or disable clientsided profile pictures.", this.settings.clientsidePfp, value => this.settings.clientsidePfp = value), 110 | new Settings.Textbox("URL", "The direct URL that has the profile picture you want.", this.settings.pfpUrl, 111 | image => { 112 | try { 113 | new URL(image) 114 | } catch { 115 | return Toasts.error('This is an invalid URL!') 116 | } 117 | this.settings.pfpUrl = image 118 | } 119 | ) 120 | ]) 121 | ]) 122 | } 123 | 124 | saveAndUpdate() { 125 | PluginUtilities.saveSettings(this.getName(), this.settings) 126 | if (!this.settings.screenSharing) { 127 | switch (this.originalNitroStatus) { 128 | case 1: 129 | BdApi.injectCSS("screenShare", `#app-mount > div.layerContainer-yqaFcK > div.layer-2KE1M9 > div > div > form > div:nth-child(2) > div > div > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignStretch-DpGPf3.noWrap-3jynv6.modalContent-BM7Qeh > div:nth-child(1) > div > button:nth-child(4) { 130 | display: none; 131 | }`) 132 | this.screenShareFix = setInterval(()=>{ 133 | document.querySelector("#app-mount > div.layerContainer-yqaFcK > div.layer-2KE1M9 > div > div > form > div:nth-child(2) > div > div > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignStretch-DpGPf3.noWrap-3jynv6.modalContent-BM7Qeh > div:nth-child(1) > div > button:nth-child(3)").click() 134 | clearInterval(this.screenShareFix) 135 | }, 100) 136 | break; 137 | default: //if user doesn't have nitro? 138 | BdApi.injectCSS("screenShare", `#app-mount > div.layerContainer-yqaFcK > div.layer-2KE1M9 > div > div > form > div:nth-child(2) > div > div > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignStretch-DpGPf3.noWrap-3jynv6.modalContent-BM7Qeh > div:nth-child(1) > div > button:nth-child(4) { 139 | display: none; 140 | } 141 | #app-mount > div.layerContainer-yqaFcK > div.layer-2KE1M9 > div > div > form > div:nth-child(2) > div > div > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignStretch-DpGPf3.noWrap-3jynv6.modalContent-BM7Qeh > div:nth-child(1) > div > button:nth-child(3) { 142 | display: none; 143 | } 144 | #app-mount > div.layerContainer-yqaFcK > div.layer-2KE1M9 > div > div > form > div:nth-child(2) > div > div > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignStretch-DpGPf3.noWrap-3jynv6.modalContent-BM7Qeh > div:nth-child(2) > div > button:nth-child(3) { 145 | display: none; 146 | }`) 147 | this.screenShareFix = setInterval(()=>{ 148 | document.querySelector("#app-mount > div.layerContainer-yqaFcK > div.layer-2KE1M9 > div > div > form > div:nth-child(2) > div > div > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignStretch-DpGPf3.noWrap-3jynv6.modalContent-BM7Qeh > div:nth-child(1) > div > button:nth-child(2)").click() 149 | document.querySelector("#app-mount > div.layerContainer-yqaFcK > div.layer-2KE1M9 > div > div > form > div:nth-child(2) > div > div > div.flex-1xMQg5.flex-1O1GKY.horizontal-1ae9ci.horizontal-2EEEnY.flex-1O1GKY.directionRow-3v3tfG.justifyStart-2NDFzi.alignStretch-DpGPf3.noWrap-3jynv6.modalContent-BM7Qeh > div:nth-child(2) > div > button:nth-child(2)").click() 150 | clearInterval(this.screenShareFix) 151 | }, 100) 152 | break; 153 | } 154 | } 155 | 156 | if (this.settings.screenSharing) BdApi.clearCSS("screenShare") 157 | 158 | if (this.settings.emojiBypass) { 159 | //fix emotes with bad method 160 | Patcher.before(DiscordModules.MessageActions, "sendMessage", (_, [, msg]) => { 161 | msg.validNonShortcutEmojis.forEach(emoji => { 162 | if (emoji.url.startsWith("/assets/")) return; 163 | msg.content = msg.content.replace(`<${emoji.animated ? "a" : ""}${emoji.allNamesString.replace(/~\d/g, "")}${emoji.id}>`, emoji.url + `&size=${this.settings.emojiSize} `) 164 | }) 165 | }); 166 | //for editing message also 167 | Patcher.before(DiscordModules.MessageActions, "editMessage", (_,obj) => { 168 | let msg = obj[2].content 169 | if (msg.search(/\d{18}/g) == -1) return; 170 | msg.match(/|<:.+?:\d{18}>/g).forEach(idfkAnymore=>{ 171 | obj[2].content = obj[2].content.replace(idfkAnymore, `https://cdn.discordapp.com/emojis/${idfkAnymore.match(/\d{18}/g)[0]}?size=${this.settings.emojiSize}`) 172 | }) 173 | }); 174 | } 175 | 176 | if(!this.settings.emojiBypass) Patcher.unpatchAll(DiscordModules.MessageActions) 177 | 178 | if (this.settings.clientsidePfp && this.settings.pfpUrl) { 179 | this.clientsidePfp = setInterval(()=>{ 180 | document.querySelectorAll(`[src="${DiscordAPI.currentUser.discordObject.avatarURL.replace(".png", ".webp")}"]`).forEach(avatar=>{ 181 | avatar.src = this.settings.pfpUrl 182 | }) 183 | document.querySelectorAll(`[src="${DiscordAPI.currentUser.discordObject.avatarURL}"]`).forEach(avatar=>{ 184 | avatar.src = this.settings.pfpUrl 185 | }) 186 | document.querySelectorAll(`.avatarContainer-28iYmV.avatar-3tNQiO.avatarSmall-1PJoGO`).forEach(avatar=>{ 187 | if (!avatar.style.backgroundImage.includes(DiscordAPI.currentUser.discordObject.avatarURL)) return; 188 | avatar.style = `background-image: url("${this.settings.pfpUrl}");` 189 | }) 190 | }, 100) 191 | } 192 | if (!this.settings.clientsidePfp) this.removeClientsidePfp() 193 | } 194 | removeClientsidePfp() { 195 | clearInterval(this.clientsidePfp) 196 | document.querySelectorAll(`[src="${this.settings.pfpUrl}"]`).forEach(avatar=>{ 197 | avatar.src = DiscordAPI.currentUser.discordObject.avatarURL 198 | }) 199 | document.querySelectorAll(`[src="${this.settings.pfpUrl}"]`).forEach(avatar=>{ 200 | avatar.src = DiscordAPI.currentUser.discordObject.avatarURL 201 | }) 202 | document.querySelectorAll(`.avatarContainer-28iYmV.avatar-3tNQiO.avatarSmall-1PJoGO`).forEach(avatar=>{ 203 | if (!avatar.style.backgroundImage.includes(this.settings.pfpUrl)) return; 204 | avatar.style = `background-image: url("${DiscordAPI.currentUser.discordObject.avatarURL}");` 205 | }) 206 | } 207 | onStart() { 208 | this.originalNitroStatus = DiscordAPI.currentUser.discordObject.premiumType; 209 | this.saveAndUpdate() 210 | DiscordAPI.currentUser.discordObject.premiumType = 2 211 | } 212 | 213 | onStop() { 214 | DiscordAPI.currentUser.discordObject.premiumType = this.originalNitroStatus; 215 | this.removeClientsidePfp() 216 | Patcher.unpatchAll(); 217 | } 218 | }; 219 | }; 220 | return plugin(Plugin, Api); 221 | })(global.ZeresPluginLibrary.buildPlugin(config)); 222 | })(); 223 | /*@end@*/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NitroPerks-Working-Version- (Currently Defunct) 2 | Working version of NitroPerks Betterdiscord plugin. 3 | Available feature includes: 4 | - 1080p 60 FPS streaming 5 | - Free Emojis from all server 6 | - Use animated profile pictures (Only Client side) 7 | - Use Custom Discord Tag (Only Client side) 8 | --------------------------------------------------------------------------------