commit 2bf11c113a5082fa88b6c6d3f8dcc3fb761b55ee Author: Ruthenic Date: Sun Jul 10 13:59:30 2022 -0400 Initial commit Co-authored-by: Tymon diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1d0107b --- /dev/null +++ b/LICENSE @@ -0,0 +1,11 @@ +Copyright 2022 Ruthenic + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/build.js b/dist/build.js new file mode 100644 index 0000000..533a40f --- /dev/null +++ b/dist/build.js @@ -0,0 +1 @@ +!function(){"use strict";function e(){let t={};return window.webpackChunkdiscord_app.push([[Math.random().toString(36)],{},e=>{t=e}]),t.c}let n={modules:e(),filter:function(e,t){let n=[];for(const r in t){var o=t[r].exports;o&&(o.default&&o.__esModule&&e(o.default)?n.push(o.default):e(o)&&n.push(o))}return n},find:e=>n.filter(e,n.modules)[0],findAll:e=>n.filter(e,n.modules),findByProps:(...e)=>n.find(t=>e.every(e=>void 0!==t[e])),findByPropsAll:(...e)=>n.findAll(t=>e.every(e=>void 0!==t[e])),findByDisplayName:t=>n.find(e=>function(e){let t=void 0,n=e[0],o=1;for(;on.call(t,...e)),t=void 0)}return n}([e,"optionalAccess",e=>e.default,"optionalAccess",e=>e.displayName])===t),findByStrings:(...e)=>n.find(t=>e.every(e=>t.toString().contains(e))),reloadModules:()=>{n.modules=e()}};function s(n){return new Promise((e,t)=>{n.oncomplete=n.onsuccess=()=>e(n.result),n.onabort=n.onerror=()=>t(n.error)})}function t(t,o){const e=(!navigator.userAgentData&&/Safari\//.test(navigator.userAgent)&&!/Chrom(e|ium)\//.test(navigator.userAgent)&&indexedDB.databases?new Promise(function(e){function t(){return indexedDB.databases().finally(e)}n=setInterval(t,100),t()}).finally(function(){return clearInterval(n)}):Promise.resolve()).then(()=>{const e=indexedDB.open(t);return e.onupgradeneeded=()=>e.result.createObjectStore(o),s(e)});var n;return(t,n)=>e.then(e=>n(e.transaction(o,t).objectStore(o)))}let o;function i(){return o=o||t("keyval-store","keyval")}function r(t,e=i()){return e("readonly",e=>s(e.get(t)))}function a(t,n,e=i()){return e("readwrite",e=>(e.put(n,t),s(e.transaction)))}function l(e,t){return e.openCursor().onsuccess=function(){this.result&&(t(this.result),this.result.continue())},s(e.transaction)}var c=Object.freeze({__proto__:null,clear:function(e=i()){return e("readwrite",e=>(e.clear(),s(e.transaction)))},createStore:t,del:function(t,e=i()){return e("readwrite",e=>(e.delete(t),s(e.transaction)))},delMany:function(e,t=i()){return t("readwrite",t=>(e.forEach(e=>t.delete(e)),s(t.transaction)))},entries:function(n=i()){return n("readonly",e=>{if(e.getAll&&e.getAllKeys)return Promise.all([s(e.getAllKeys()),s(e.getAll())]).then(([e,n])=>e.map((e,t)=>[e,n[t]]));const t=[];return n("readonly",e=>l(e,e=>t.push([e.key,e.value])).then(()=>t))})},get:r,getMany:function(e,t=i()){return t("readonly",t=>Promise.all(e.map(e=>s(t.get(e)))))},keys:function(e=i()){return e("readonly",e=>{if(e.getAllKeys)return s(e.getAllKeys());const t=[];return l(e,e=>t.push(e.key)).then(()=>t)})},promisifyRequest:s,set:a,setMany:function(e,t=i()){return t("readwrite",t=>(e.forEach(e=>t.put(e[1],e[0])),s(t.transaction)))},update:function(o,r,e=i()){return e("readwrite",n=>new Promise((e,t)=>{n.get(o).onsuccess=function(){try{n.put(r(this.result),o),e(s(n.transaction))}catch(e){t(e)}}}))},values:function(e=i()){return e("readonly",e=>{if(e.getAll)return s(e.getAll());const t=[];return l(e,e=>t.push(e.value)).then(()=>t)})}}),u=Object.freeze({GET:"GET",SET:"SET",DELETE:"DELETE",UPDATE:"UPDATE"});class d{constructor(){this.listeners=Object.values(u).reduce((e,t)=>(e[t]=new Set,e),{}),this.on=function(e,t){if(this.listeners[e].has(t))throw Error(`This listener on ${e} already exists.`);this.listeners[e].add(t)},this.once=function(e,n){const o=(e,t)=>{this.off(e,o),n(e,t)};this.on(e,o)},this.off=function(e,t){this.listeners[e].delete(t)},this.emit=function(e,t){for(const n of this.listeners[e])n(e,t)};for(const t of Object.values(u))this[t.toLowerCase()]=e=>{this.emit(t,e)}}}function f(e={},{nestArrays:a=!0}={}){const l=new d;return Object.assign({store:function r(e,s,i){return new Proxy(e,{get(e,t){var n=[...i,t],o=e[t];return null!=o?(l.get({path:n,value:o}),!a&&Array.isArray(o)||"object"!=typeof o?o:r(o,s,n)):r(e[t]={},s,n)},set(e,t,n){return e[t]=n,l.set({path:[...i,t],value:n}),!0},deleteProperty(e,t){return delete e[t]&&(l.delete({path:[...i,t]}),!0)},has(e,t){return("object"!=typeof e[t]||0!==Object.keys(e[t]).length)&&t in e}})}(e,e,[]),ghost:e},l)}var p=Object.freeze({__proto__:null,Events:u,make:f});const g=n["findByProps"],h=g("__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","createElement");c={React:h,ReactDOM:g("__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","hydrate"),dispatch:g("dirtyDispatch").__proto__,idb:c,nests:p};function m(s,i=!1){return function(e,...t){t=t.join(""),void 0===e&&(e=["Default"],m("warn")("Requested hierarchy has not been passed to logger function, defaulting to default string",["Logger"])),"string"==typeof e&&(t=e,e=["Default"]);let n=["Demoncord",...e,t],o=[],r="";i&&n.splice(0,1);for(let e=0;e{e=o.plugins[e];const t=(0,eval)(e.initialize);var n=t.onStart();y.store[e.meta.name].ctx=n,o.status[e.meta.name]={running:!0}}),e.store.pluginsList=o.plugins,await a("demon",o)},add:async function(e,t){const n=await r("demon");n.plugins[t.name]={initialize:e,meta:t},extNest.store.pluginsList=n.plugins,await a("demon",n)},del:async function(e){const t=await r("demon");var n;t.plugins[e]&&t.status[e].running&&(n=y.store[e].ctx,(0,eval)(t.plugins[e].initialize).onStop(n)),delete t.status[e],delete t.plugins[e],extNest.store.pluginsList=t.plugins,await a("demon",t)},toggle:async function(t){const e=await r("demon");var n;e.plugins[t]&&(!function(e){let t=void 0,n=e[0],o=1;for(;on.call(t,...e)),t=void 0)}return n}([e,"access",e=>e.status,"access",e=>e[t],"optionalAccess",e=>e.running])?(n=(0,eval)(e.plugins[t].initialize).onStart(),y.store[t].ctx=n,e.status[t]={running:!0}):(console.log(e.status[t].ctx),n=y.store[t].ctx,(0,eval)(e.plugins[t].initialize).onStop(n),e.status[t].running=!1)),await a("demon",e)}};const v=["a","b","i"],_=new Map;var E;E="a";const b=(i,a,e,o=!1)=>{if("function"!=typeof a[i])throw new Error(i+" is not a function in "+a.constructor.name);_.has(a)||_.set(a,{});const t=_.get(a);if(!t[i]){const s=a[i],c=(t[i]={o:s,b:new Map,i:new Map,a:new Map},(e,t,n)=>{t=function(e,t,n,o,r){const s=_.get(t)?.[e];if(!s)return r?Reflect.construct(t[e],n,o):t[e].apply(o,n);for(const c of s.b.values()){var i=c.call(o,n);Array.isArray(i)&&(n=i)}let a=(...e)=>r?Reflect.construct(s.o,e,o):s.o.apply(o,e);for(const u of s.i.values()){const d=a;a=(...e)=>u.call(o,e,d)}let l=a(...n);for(const f of s.a.values())l=f.call(o,n,l)??l;return l}(i,a,t,e,n);return o&&r(),t});var n=new Proxy(s,{apply:(e,t,n)=>c(t,n,!1),construct:(e,t)=>c(s,t,!0),get:(e,t,n)=>"toString"==t?s.toString.bind(s):Reflect.get(e,t,n)});Reflect.defineProperty(a,i,{value:n,configurable:!0,writable:!0})||(a[i]=n)}const l=Symbol(),r=()=>{{var e=a,t=i,n=l,o=E;const r=_.get(e),s=r?.[t];return!!s?.[o].has(n)&&(s[o].delete(n),v.every(e=>0===s[e].size)&&(Reflect.defineProperty(e,t,{value:s.o,writable:!0,configurable:!0})||(e[t]=s.o),delete r[t]),0==Object.keys(r).length&&_.delete(e),!0)}};return t[i][E].set(l,e),r},A="/home/ruthenic/Coding/Javascript/demoncord/demoncord-rewrite/src/api/ui/settings/test.jsx";var S=()=>{var e=demon.require("internal/nest"),e=Object.keys(e.ghost.pluginsList);return h.createElement("h1",{__self:void 0,__source:{fileName:A,lineNumber:7}},e)};const x=n.findByDisplayName("SettingsView");var D={init:function(){b("getPredicateSections",x.default.prototype,(e,t)=>(t.unshift({section:"HEADER",label:"Demoncord"},{section:"demoncord",label:"Plugins",element:S},{section:"DIVIDER"}),t))}};if(!window.DiscordNative)throw new Error("Sorry, Demoncord cannot be used on web!");const P={modules:{webpack:n,common:c},utils:p,plugins:w,internal:{nest:c.nests.make()}};window.demon={require:function(e){const t=e.split("/");let n=P;return t.forEach(e=>{if(!(e in n))throw new Error("Module does not exist!");n=n[e]}),n}},w.init(),D.init()}(); diff --git a/package.json b/package.json new file mode 100644 index 0000000..e7415fd --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "demoncord-rewrite", + "version": "0.0.1", + "description": "A client mod for sinners.", + "main": "src/index.js", + "scripts": { + "build": "rollup --config rollup.config.js", + "watch": "rollup --config rollup.config.js --watch" + }, + "author": "Drake", + "license": "BSD-3-Clause", + "dependencies": { + "@rollup/plugin-alias": "^3.1.9", + "@rollup/plugin-node-resolve": "^13.3.0", + "@rollup/plugin-sucrase": "^4.0.4", + "idb-keyval": "^6.1.0", + "nests": "^2.3.1", + "rollup": "^2.73.0", + "rollup-plugin-swc": "^0.2.1", + "rollup-plugin-uglify": "^6.0.4", + "spitroast": "^1.4.2", + "uglify-js": "^3.15.5" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..df991a7 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,450 @@ +lockfileVersion: 5.4 + +specifiers: + '@rollup/plugin-alias': ^3.1.9 + '@rollup/plugin-node-resolve': ^13.3.0 + '@rollup/plugin-sucrase': ^4.0.4 + idb-keyval: ^6.1.0 + nests: ^2.3.1 + rollup: ^2.73.0 + rollup-plugin-swc: ^0.2.1 + rollup-plugin-uglify: ^6.0.4 + spitroast: ^1.4.2 + uglify-js: ^3.15.5 + +dependencies: + '@rollup/plugin-alias': 3.1.9_rollup@2.73.0 + '@rollup/plugin-node-resolve': 13.3.0_rollup@2.73.0 + '@rollup/plugin-sucrase': 4.0.4_rollup@2.73.0 + idb-keyval: 6.1.0 + nests: 2.3.1 + rollup: 2.73.0 + rollup-plugin-swc: 0.2.1_rollup@2.73.0 + rollup-plugin-uglify: 6.0.4_rollup@2.73.0 + spitroast: 1.4.2 + uglify-js: 3.15.5 + +packages: + + /@babel/code-frame/7.16.7: + resolution: {integrity: sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.17.9 + dev: false + + /@babel/helper-validator-identifier/7.16.7: + resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/highlight/7.17.9: + resolution: {integrity: sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.16.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: false + + /@rollup/plugin-alias/3.1.9_rollup@2.73.0: + resolution: {integrity: sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==} + engines: {node: '>=8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + rollup: 2.73.0 + slash: 3.0.0 + dev: false + + /@rollup/plugin-node-resolve/13.3.0_rollup@2.73.0: + resolution: {integrity: sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==} + engines: {node: '>= 10.0.0'} + peerDependencies: + rollup: ^2.42.0 + dependencies: + '@rollup/pluginutils': 3.1.0_rollup@2.73.0 + '@types/resolve': 1.17.1 + deepmerge: 4.2.2 + is-builtin-module: 3.1.0 + is-module: 1.0.0 + resolve: 1.22.0 + rollup: 2.73.0 + dev: false + + /@rollup/plugin-sucrase/4.0.4_rollup@2.73.0: + resolution: {integrity: sha512-YH4J8yoJb5EVnLhAwWxYAQNh2SJOR+SdZ6XdgoKEv6Kxm33riYkM8MlMaggN87UoISP52qAFyZ5ey56wu6umGg==} + engines: {node: '>=12.0.0'} + peerDependencies: + rollup: ^2.53.1 + dependencies: + '@rollup/pluginutils': 4.2.1 + rollup: 2.73.0 + sucrase: 3.23.0 + dev: false + + /@rollup/pluginutils/3.1.0_rollup@2.73.0: + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: 2.73.0 + dev: false + + /@rollup/pluginutils/4.2.1: + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: false + + /@types/estree/0.0.39: + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} + dev: false + + /@types/node/17.0.33: + resolution: {integrity: sha512-miWq2m2FiQZmaHfdZNcbpp9PuXg34W5JZ5CrJ/BaS70VuhoJENBEQybeiYSaPBRNq6KQGnjfEnc/F3PN++D+XQ==} + dev: false + + /@types/resolve/1.17.1: + resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} + dependencies: + '@types/node': 17.0.33 + dev: false + + /ansi-styles/3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: false + + /any-promise/1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: false + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: false + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: false + + /builtin-modules/3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: false + + /chalk/2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: false + + /color-convert/1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: false + + /color-name/1.1.3: + resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} + dev: false + + /commander/4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: false + + /concat-map/0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: false + + /deepmerge/4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: false + + /escape-string-regexp/1.0.5: + resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} + engines: {node: '>=0.8.0'} + dev: false + + /estree-walker/1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + dev: false + + /estree-walker/2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: false + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: false + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: false + + /glob/7.1.6: + resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: false + + /has-flag/3.0.0: + resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} + engines: {node: '>=4'} + dev: false + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: false + + /idb-keyval/6.1.0: + resolution: {integrity: sha512-u/qHZ75rlD3gH+Zah8dAJVJcGW/RfCnfNrFkElC5RpRCnpsCXXhqjVk+6MoVKJ3WhmNbRYdI6IIVP88e+5sxGw==} + dependencies: + safari-14-idb-fix: 3.0.0 + dev: false + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: false + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /is-builtin-module/3.1.0: + resolution: {integrity: sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: false + + /is-core-module/2.9.0: + resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} + dependencies: + has: 1.0.3 + dev: false + + /is-module/1.0.0: + resolution: {integrity: sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=} + dev: false + + /jest-worker/24.9.0: + resolution: {integrity: sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==} + engines: {node: '>= 6'} + dependencies: + merge-stream: 2.0.0 + supports-color: 6.1.0 + dev: false + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: false + + /lines-and-columns/1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: false + + /merge-stream/2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: false + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: false + + /mz/2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: false + + /nests/2.3.1: + resolution: {integrity: sha512-mq9g10tzsaGbS/c5RUJVwiJVqo89JA/KIYPpBDQlKnyviJ7EDUaboIWsuWx0Abe49nys8MjnB6vK53KF1m6MUQ==} + peerDependencies: + react: '>=16.8' + solid-js: '>=1.0.0' + dev: false + + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: false + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: false + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: false + + /pirates/4.0.5: + resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} + engines: {node: '>= 6'} + dev: false + + /resolve/1.22.0: + resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} + hasBin: true + dependencies: + is-core-module: 2.9.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: false + + /rollup-plugin-swc/0.2.1_rollup@2.73.0: + resolution: {integrity: sha512-wWRYt9tC0aIBvRQHNnVtwJ6DRPDj9XYpOAcOyFB11sKSkR/R+NAmbrjBACCPNVmZcxg6joV29wXgb5mU1DI7eA==} + peerDependencies: + '@swc/core': '>=1.0' + rollup: '>=1.5.0' + dependencies: + '@rollup/pluginutils': 4.2.1 + rollup: 2.73.0 + dev: false + + /rollup-plugin-uglify/6.0.4_rollup@2.73.0: + resolution: {integrity: sha512-ddgqkH02klveu34TF0JqygPwZnsbhHVI6t8+hGTcYHngPkQb5MIHI0XiztXIN/d6V9j+efwHAqEL7LspSxQXGw==} + peerDependencies: + rollup: '>=0.66.0 <2' + dependencies: + '@babel/code-frame': 7.16.7 + jest-worker: 24.9.0 + rollup: 2.73.0 + serialize-javascript: 2.1.2 + uglify-js: 3.15.5 + dev: false + + /rollup/2.73.0: + resolution: {integrity: sha512-h/UngC3S4Zt28mB3g0+2YCMegT5yoftnQplwzPqGZcKvlld5e+kT/QRmJiL+qxGyZKOYpgirWGdLyEO1b0dpLQ==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: false + + /safari-14-idb-fix/3.0.0: + resolution: {integrity: sha512-eBNFLob4PMq8JA1dGyFn6G97q3/WzNtFK4RnzT1fnLq+9RyrGknzYiM/9B12MnKAxuj1IXr7UKYtTNtjyKMBog==} + dev: false + + /serialize-javascript/2.1.2: + resolution: {integrity: sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==} + dev: false + + /slash/3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: false + + /spitroast/1.4.2: + resolution: {integrity: sha512-iEBsKg3EXTQj2nikYIMtOE5YSqbI5CtRxVYI+Gh+9HeQxf4u86UWF5yC5eTVAoReZSogbD2M37JYG8TYGBnFTg==} + dev: false + + /sucrase/3.23.0: + resolution: {integrity: sha512-xgC1xboStzGhCnRywlBf/DLmkC+SkdAKqrNCDsxGrzM0phR5oUxoFKiQNrsc2D8wDdAm03iLbSZqjHDddo3IzQ==} + engines: {node: '>=8'} + hasBin: true + dependencies: + commander: 4.1.1 + glob: 7.1.6 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.5 + ts-interface-checker: 0.1.13 + dev: false + + /supports-color/5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: false + + /supports-color/6.1.0: + resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} + engines: {node: '>=6'} + dependencies: + has-flag: 3.0.0 + dev: false + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: false + + /thenify-all/1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: false + + /thenify/3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: false + + /ts-interface-checker/0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: false + + /uglify-js/3.15.5: + resolution: {integrity: sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==} + engines: {node: '>=0.8.0'} + hasBin: true + dev: false + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: false diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..67caf0b --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,22 @@ +import pkjs from "./package.json" +import { defineConfig } from "rollup"; +import { uglify } from "rollup-plugin-uglify" +import { nodeResolve } from '@rollup/plugin-node-resolve' +import sucrase from '@rollup/plugin-sucrase'; +import alias from '@rollup/plugin-alias' + +export default defineConfig({ + input: pkjs.main, + output: { + file: "dist/build.js", + format: "iife" + }, + plugins: [alias({ + entries: [ + { find: "nests", replacement: "../../node_modules/nests/esm/index.js" } + ] + }), nodeResolve(), sucrase({ + exclude: ["node_modules/**"], + transforms: ["jsx"] + }), uglify()] +}) diff --git a/src/api/common.js b/src/api/common.js new file mode 100644 index 0000000..687ac05 --- /dev/null +++ b/src/api/common.js @@ -0,0 +1,23 @@ +import webpack from "./webpack" +import * as idb from "idb-keyval" +import * as nests from "nests" + +const { findByProps } = webpack + +const React = findByProps( + "__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED", + "createElement" +) + +export default { + React, + ReactDOM: findByProps( + "__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED", + "hydrate" + ), + dispatch: findByProps("dirtyDispatch").__proto__, + idb, + nests +} + +export { idb, nests, React } \ No newline at end of file diff --git a/src/api/patcher.js b/src/api/patcher.js new file mode 100644 index 0000000..22152f1 --- /dev/null +++ b/src/api/patcher.js @@ -0,0 +1,5 @@ +//NOTE: this isn't even a wrapper around spitroast, it's more a convienence for importing patcher internally +import * as spitroast from "spitroast" + +export * from "spitroast" +export default spitroast \ No newline at end of file diff --git a/src/api/plugin.js b/src/api/plugin.js new file mode 100644 index 0000000..4bfe1e6 --- /dev/null +++ b/src/api/plugin.js @@ -0,0 +1,83 @@ +import { idb, nests } from "./common" + +const nest = nests.make() + +async function init() { + const extNest = demon.require("internal/nest") + if (!window.__demon) { // this *shouldn't* be required but if we magically run into a race condition it's better to be safe + window.__demon = {} + } + if (!(await idb.get("demon"))) { + await idb.set("demon", { + status: { + + }, + plugins: { + + } + }) + } + const currdemon = await idb.get("demon") + currdemon.status = {} + Object.keys(currdemon.plugins).forEach(key => { + const plug = currdemon.plugins[key] + const exports = (0, eval)(plug.initialize) + const ret = exports.onStart() + nest.store[plug.meta.name].ctx = ret + currdemon.status[plug.meta.name] = { + running: true + } + }) + extNest.store.pluginsList = currdemon.plugins + await idb.set("demon", currdemon) +} + +async function add(iife, meta) { + const currdemon = await idb.get("demon") + currdemon.plugins[meta.name] = { + initialize: iife, + meta: meta + } + extNest.store.pluginsList = currdemon.plugins + await idb.set("demon", currdemon) +} + +async function del(name) { + const currdemon = await idb.get("demon") + if (!!currdemon.plugins[name]) + if (currdemon.status[name].running) { + const ctx = nest.store[name].ctx; + (0, eval)(currdemon.plugins[name].initialize).onStop(ctx) + } + delete currdemon.status[name] + delete currdemon.plugins[name] + extNest.store.pluginsList = currdemon.plugins + await idb.set("demon", currdemon) +} + +async function toggle(name) { + const currdemon = await idb.get("demon") + if (!!currdemon.plugins[name]) { + if (currdemon.status[name]?.running) { + console.log(currdemon.status[name].ctx) + const ctx = nest.store[name].ctx; + (0, eval)(currdemon.plugins[name].initialize).onStop(ctx) + currdemon.status[name].running = false + } + else { + const ret = (0, eval)(currdemon.plugins[name].initialize).onStart() + nest.store[name].ctx = ret + currdemon.status[name] = { + running: true + } + } + } + await idb.set("demon", currdemon) +} + +export default { + init, + add, + del, + toggle +} \ No newline at end of file diff --git a/src/api/ui/settings/settings.js b/src/api/ui/settings/settings.js new file mode 100644 index 0000000..54f148c --- /dev/null +++ b/src/api/ui/settings/settings.js @@ -0,0 +1,26 @@ +import webpack from "../../webpack" +import { after } from "../../patcher" +import test from "./test.jsx" + +const SettingsView = webpack.findByDisplayName("SettingsView") + +function init() { + after("getPredicateSections", SettingsView.default.prototype, (args, sections) => { + sections.unshift( + { + section: "HEADER", + label: "Demoncord" + }, + { + section: "demoncord", + label: "Plugins", + element: test + }, + { + section: "DIVIDER" + }) + return sections; + }) +} + +export default { init } \ No newline at end of file diff --git a/src/api/ui/settings/test.jsx b/src/api/ui/settings/test.jsx new file mode 100644 index 0000000..0d7dac9 --- /dev/null +++ b/src/api/ui/settings/test.jsx @@ -0,0 +1,9 @@ +import { React, nests } from "../../common" + +export default () => { + const extNest = demon.require("internal/nest") + const pluginList = Object.keys(extNest.ghost.pluginsList) + return ( +

{pluginList}

+ ) +} \ No newline at end of file diff --git a/src/api/utils/index.js b/src/api/utils/index.js new file mode 100644 index 0000000..844c02c --- /dev/null +++ b/src/api/utils/index.js @@ -0,0 +1,5 @@ +import logger from "./logger" + +export default { + logger +} diff --git a/src/api/utils/logger.js b/src/api/utils/logger.js new file mode 100644 index 0000000..91e77ce --- /dev/null +++ b/src/api/utils/logger.js @@ -0,0 +1,84 @@ +// hopefully separating out styles like this is more readable -- sink +const styleBase = ` +@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@700&display=swap'); +font-family: 'IBM Plex Mono', monospace; +`; + +const styleBg = ` +${styleBase} +color: #1d1131; +background-color: #aa8dd8; +font-weight: 600; +font-size: 0.9em; +padding: 0px 5px 1px 5px; +border-radius: 5px; +`; + +const styleTxt = ` +${styleBase} +color: #E2EECE; +font-weight: 500; +font-size: 0.9em; +`; + +//TODO: make setting to save logs in idb, for debugging and troubleshooting purposes +function makeLogger(print, noDemoncord = false) { + return function (locs, ...message) { + message = message.join("") + if (locs === undefined) { + locs = ["Default"] + makeLogger("warn")("Requested hierarchy has not been passed to logger function, defaulting to default string", ["Logger"]) + } + if (typeof(locs) === "string") { + message = locs + locs = ["Default"] + } + let rawParts = ["Demoncord", ...locs, message]; + let styleParts = []; + let content = ""; + + if (noDemoncord) rawParts.splice(0, 1); + + for (let i = 0; i < rawParts.length; i++) { + if (i === rawParts.length - 1) { + // last item + content += "%c" + rawParts[i]; + styleParts.push(styleTxt); + } else { + content += "%c" + rawParts[i] + "%c "; + styleParts.push(styleBg, ""); + } + } + + print(content, ...styleParts); + }; +} + +const log = makeLogger(console.log); +const warn = makeLogger(console.warn); +const error = makeLogger(console.error); +const trace = makeLogger(console.trace); + +/*const group = (msg, loc, sublogs) => { + // start group + getLogger(console.group)(msg, loc); + + for (const sublog of sublogs) { + const logFunc = getLogger( + sublog.length === 3 ? sublog[2] : "log", + true + ); + + logFunc(sublog[0], sublog[1]); + } + + console.groupEnd(); +};*/ + +export default { + log, + warn, + error, + trace, + makeLogger +}; diff --git a/src/api/webpack.js b/src/api/webpack.js new file mode 100644 index 0000000..64fd035 --- /dev/null +++ b/src/api/webpack.js @@ -0,0 +1,58 @@ +function getModules() { + let modules = {}; + + window.webpackChunkdiscord_app.push([ + [Math.random().toString(36)], + {}, + (e) => { + modules = e; + } + ]); + + return modules.c; +} + +function filter(filter, moduleList) { + let modules = []; + for (const mod in moduleList) { + const module = moduleList[mod].exports; + if (module) { + if (module.default && module.__esModule && filter(module.default)) { + modules.push(module.default); + } else if (filter(module)) { + modules.push(module); + } + } + } + return modules; +} + +let webpack = { + modules: getModules(), + filter: filter, + find: (filter) => webpack.filter(filter, webpack.modules)[0], + findAll: (filter) => webpack.filter(filter, webpack.modules), + findByProps: (...props) => { + return webpack.find((module) => { + return props.every((prop) => module[prop] !== undefined); + }); + }, + findByPropsAll: (...props) => { + return webpack.findAll((module) => + props.every((prop) => module[prop] !== undefined) + ); + }, + findByDisplayName: (prop) => { + return webpack.find((m) => m?.default?.displayName === prop); + }, + findByStrings: (...props) => { + return webpack.find((module) => + props.every((prop) => module.toString().contains(prop))) + }, + reloadModules: () => { + //NOTE: i have no idea why this could even feasibly need to be used, but i'm adding it anyways + webpack.modules = getModules(); + } +}; + +export default webpack; diff --git a/src/api/ws.js b/src/api/ws.js new file mode 100644 index 0000000..afb7cb3 --- /dev/null +++ b/src/api/ws.js @@ -0,0 +1 @@ +//TODO: funny websocket control api \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..0d0243e --- /dev/null +++ b/src/index.js @@ -0,0 +1,49 @@ +import webpack from "./api/webpack.js" +import common from "./api/common.js" +import utils from "./api/utils/index.js" +import plugins from "./api/plugin.js" +import settings from "./api/ui/settings/settings.js" + +if (!window.DiscordNative) { + throw new Error("Sorry, Demoncord cannot be used on web!") +} + +const demon = { + modules: { + webpack, + common + }, + utils, + plugins, + internal: { + nest: common.nests.make() + } +} + +function isAllowed(mod) { + //TODO: actually implement permissions + return true +} + +function require(mod) { + if (!isAllowed(mod)) { + throw new Error("Not allowed!"); //TODO: make this not irrepairably error out + } + const mods = mod.split("/"); + let res = demon; + mods.forEach((m) => { + if (m in res) { + res = res[m]; + } else { + throw new Error("Module does not exist!"); + } + }); + return res; +} + +window.demon = { + require +} + +plugins.init() +settings.init() \ No newline at end of file