From b3829e311c39dfdb7505a2b5de4eb89566db12f0 Mon Sep 17 00:00:00 2001 From: Flex Date: Sun, 20 May 2018 15:36:05 -0600 Subject: [PATCH] rework epapi for dependency/priority loading + plugin list plugin --- TODO.md | 2 +- app/index.html | 1 + crispr/crispr.js | 8 ++-- epapi/epapi.js | 47 ++++++++++++++++++- plugin/plugins.js | 110 +++++++++++++++++++++++++++++++++++++++++++++ plugin/settings.js | 5 ++- plugin/system.js | 23 ++++++---- 7 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 plugin/plugins.js diff --git a/TODO.md b/TODO.md index f2e3b5e..5c13f73 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,7 @@ - Nothing yet. # EPAPI -- [ ] Native settingsapi +- [x] Native settingsapi # CRISPR - [ ] Plugin loading changes diff --git a/app/index.html b/app/index.html index d61c00c..dbbcb83 100644 --- a/app/index.html +++ b/app/index.html @@ -168,6 +168,7 @@ fs.writeFileSync(data + '/crxpwn/payload.js', await (await fetch(approot + '/crxpwn.js?_=' + Date.now())).text()); fs.writeFileSync(data + '/epapi.js', await (await fetch(approot + '/epapi/epapi.js?_=' + Date.now())).text()); fs.writeFileSync(data + '/crispr.js', await (await fetch(approot + '/crispr/crispr.js?_=' + Date.now())).text()); + fs.writeFileSync(data + '/plugins/plugins.js', await (await fetch(approot + '/plugin/plugins.js?_=' + Date.now())).text()); fs.writeFileSync(data + '/plugins/system.js', await (await fetch(approot + '/plugin/system.js?_=' + Date.now())).text()); fs.writeFileSync(data + '/plugins/customizer.js', await (await fetch(approot + '/plugin/customizer.js?_=' + Date.now())).text()); fs.writeFileSync(data + '/plugins/settings.js', await (await fetch(approot + '/plugin/settings.js?_=' + Date.now())).text()); diff --git a/crispr/crispr.js b/crispr/crispr.js index 940d476..f0ef4b7 100644 --- a/crispr/crispr.js +++ b/crispr/crispr.js @@ -3,16 +3,16 @@ EndPwn CRISPR Copyright 2018 EndPwn Project - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. DO NOT EDIT THIS FILE! Your bootstrap may overwrite changes to it, and you will lose your work! EndPwn3 users: You can prevent this by creating a file in the same directory named DONTUPDATE - + https://github.com/endpwn/ */ diff --git a/epapi/epapi.js b/epapi/epapi.js index a8753fa..0ed94b1 100644 --- a/epapi/epapi.js +++ b/epapi/epapi.js @@ -296,11 +296,14 @@ function evaluate(str, exportsR) { wc.findFunc("clyde")[0].exports.BOT_AVATARS.EndPwn = "https://cdn.discordapp.com/avatars/350987786037493773/ae0a2f95898cfd867c843c1290e2b917.png"; // dont try loading plugins in lite mode + window.$pluginStore = {}; + + var loadOrder = {}; + if (internal.lite) { } else { - // load styles if (fs.existsSync(exports.data + '/styles')) { fs.readdirSync(exports.data + '/styles').forEach(x => { @@ -316,10 +319,50 @@ function evaluate(str, exportsR) { // load plugins... if (fs.existsSync(exports.data + '/plugins')) { + fs.readdirSync(exports.data + '/plugins').forEach(x => { + if (x.endsWith('.js')) { + var plugin = krequire(x); + $pluginStore[x.replace(".js","")] = plugin.manifest ? plugin.manifest : {name:x.replace(".js",""),description:"Manifest is missing for this plugin.",author:"Unknown"}; + loadOrder[x.replace(".js","")] = loadOrder[x.replace(".js","")] ? loadOrder[x.replace(".js","")] : ((plugin.manifest && plugin.manifest.prioirty) ? plugin.manifest.prioirty : 0); + if(plugin.manifest && plugin.manifest.loadAfter){ + let la = plugin.manifest.loadAfter; + if(Array.isArray(la)){ + internal.print('/plugins/' + x + ' depends on: ' + la.join(", ")); + la.forEach(y=>{loadOrder[y] ? loadOrder[y]=loadOrder[y]+1 : loadOrder[y] = 1}); + }else{ + internal.print('/plugins/' + x + '\'s loadAfter is not an array, ignoring...'); + } + } + } + }); + } + + loadOrder = Object.keys(loadOrder).sort(function(a,b){return -(loadOrder[a] - loadOrder[b])}); + + loadOrder.forEach(x=>{ + try { + var plugin = krequire(x+".js"); + + if (plugin.start !== undefined) { + internal.print('loading /plugins/' + x); + plugin.start(); + } else { + internal.print('/plugins/' + x + ' does not export start(), ignoring...'); + } + } + catch (e) { + internal.error(e, x + ' failed to initialize properly'); + warning++; + } + }); + + /*if (fs.existsSync(exports.data + '/plugins')) { fs.readdirSync(exports.data + '/plugins').forEach(x => { if (x.endsWith('.js')) { try { var plugin = krequire(x); + $pluginStore[x.replace(".js","")] = plugin.manifest ? plugin.manifest : {name:x.replace(".js",""),description:"Manifest is missing for this plugin.",author:"Unknown"}; + if (plugin.start !== undefined) { internal.print('loading /plugins/' + x); plugin.start(); @@ -333,7 +376,7 @@ function evaluate(str, exportsR) { } } }); - } + }*/ // execute autoruns... if (fs.existsSync(exports.data + '/autorun')) { diff --git a/plugin/plugins.js b/plugin/plugins.js new file mode 100644 index 0000000..32f6c48 --- /dev/null +++ b/plugin/plugins.js @@ -0,0 +1,110 @@ +exports = { + manifest: { + author: "Cynosphere", + name: "Plugins Page", + description: "Shows what plugins you have", + loadAfter:["settings"] + }, + + start:function(){ + let em = $settingsapi.elements; + let int = em.internal; + + var createPlugin = function(id,data){ + var info = {}; + info.name = data.name ? data.name : (id ? id : ""); + info.description = data.description ? data.description : "Manifest is missing for this plugin."; + info.author = data.author ? data.author : "Unknown"; + info.loadAfter = data.loadAfter ? data.loadAfter : []; + info.priority = data.priority ? data.priority : 0; + info.replacements = data.replacements ? data.replacements : []; + + var cont = em.createVerticalPanel(); + + var head = em.createHorizontalPanel() + .appendTo(cont); + + var title = createElement("h3") + .withClass( + int.headers.h3, + int.headers.title, + int.headers.size16, + int.headers.height20, + int.headers.defaultColor + ) + .withText(info.name) + .appendTo(head); + + em.createH5('By '+info.author) + .appendTo(title); + + em.createSwitch(() => { }, true) + .appendTo(head); + + createElement("div") + .withClass( + int.misc3.description, + int.misc3.formText, + int.misc3.modeDefault + ) + .withText(info.description) + .appendTo(cont); + + var body = em.createHorizontalPanel() + .appendTo(cont); + + createElement("div") + .withClass( + int.misc3.description, + int.misc3.formText, + int.misc3.modeDefault + ) + .withText(`Replacements: ${info.replacements.length}`) + .appendTo(body); + + createElement("div") + .withClass( + int.misc3.description, + int.misc3.formText, + int.misc3.modeDefault + ) + .modify(x=>x.style.marginLeft = "8px") + .withText(`Priority: ${info.priority}`) + .appendTo(body); + + createElement("div") + .withClass( + int.misc3.description, + int.misc3.formText, + int.misc3.modeDefault + ) + .modify(x=>x.style.marginLeft = "8px") + .withText(info.loadAfter.length > 0 ? `Depends on: ${info.loadAfter.join(", ")}` : "No dependencies") + .appendTo(body); + + createElement("div") + .withClass(em.internal.dividers.divider) + .appendTo(cont); + + return cont; + } + + $settingsapi.addSection("Plugins","Plugins",null,function(pnl){ + em.createH2("Plugins") + .appendTo(pnl); + + let plugins = {} + + Object.keys($pluginStore).forEach(x=>{ + console.log(x); + plugins[x] = {id:x,data:$pluginStore[x]}; + }); + + Object.keys(plugins).forEach(x=>{ + let d = plugins[x]; + createPlugin(d.id,d.data) + .appendTo(pnl); + }); + }); + } +} \ No newline at end of file diff --git a/plugin/settings.js b/plugin/settings.js index 5368908..efeef14 100644 --- a/plugin/settings.js +++ b/plugin/settings.js @@ -25,7 +25,8 @@ exports = { description: "Hijacking the settings pages.", replacements: [ {signature:'/function z\\(\\){return\\[{(.+)}]}/',payload:'window.$settingsapi={sections:[{$1}]};function z(){return window.$settingsapi.sections;}'} - ] + ], + loadAfter: ["system"] }, init: function () { @@ -36,6 +37,7 @@ exports = { var checkboxes = $api.util.findFuncExports('checkboxEnabled'); var misc = $api.util.findFuncExports('statusRed-', 'inputDefault'); var misc2 = $api.util.findFuncExports('multiInputField'); + var misc3 = $api.util.findFuncExports('formText-','formText'); var headers = $api.util.findFuncExports('h5-', 'h5'); var dividers = wc.findFunc('divider-')[0].exports; @@ -203,6 +205,7 @@ exports = { checkboxes:checkboxes, misc:misc, misc2:misc2, + misc3:misc3, headers:headers, dividers:dividers } diff --git a/plugin/system.js b/plugin/system.js index 7c7111b..90ea2d8 100644 --- a/plugin/system.js +++ b/plugin/system.js @@ -117,16 +117,21 @@ exports = { }, - replacements: { - - // changelog injection - 'key:"changeLog",get:function(){return E}': - 'key:"changeLog",get:function(){if(!E.injected){E.injected=1;E.date=E.date<=window.endpwn.changelog.date?window.endpwn.changelog.date:E.date;E.body=window.endpwn.changelog.body+"\\n\\n"+E.body}return E}', - - // crash screen hijack - 'var e=o("div",{},void 0,o("p",{},void 0,a.default.Messages.ERRORS_UNEXPECTED_CRASH),o("p",{},void 0,a.default.Messages.ERRORS_ACTION_TO_TAKE)),t=o(c.default,{size:l.ButtonSizes.LARGE,onClick:this._handleSubmitReport},void 0,a.default.Messages.ERRORS_RELOAD);return o(u.default,{theme:this.props.theme,title:a.default.Messages.UNSUPPORTED_BROWSER_TITLE,': - `var e=o("div",{},void 0,o("p",{},void 0,"Something has gone very, very wrong, and Discord has crashed."),o("p",{},void 0,"If this is the first time you've seen this error screen, reload and hope for the best. If this screen appears again, follow these steps:"),o("p",{},void 0,"Try removing any new plugins and restarting again. If this solves the problem there may be a bug in a plugin or a conflict."),o("p",{},void 0,"If problems continue, it's likely that there is a bug in EndPwn or Discord."),o("p",{},void 0,"If you need help, join the EndPwn Discord server (https://discord.gg/wXdPNf2)"),o("p",{},void 0,"Details may be available in the console (Ctrl+Shift+I), but at this level of crash we can't be certain.")),t=o("div",{},void 0,o(c.default,{size:l.ButtonSizes.LARGE,onClick:()=>window.electron.getCurrentWindow().reload()},void 0,"Reload"),o(c.default,{size:l.ButtonSizes.LARGE,onClick:()=>{window.$api.localStorage.set('safemode',1);window.electron.getCurrentWindow().reload()}},void 0,"Reload in safe mode"));return o(u.default,{theme:this.props.theme,title:"Discord: Fatal Error",` + manifest: { + replacements: [ + // changelog injection + { + signature:'key:"changeLog",get:function(){return E}', + payload:'key:"changeLog",get:function(){if(!E.injected){E.injected=1;E.date=E.date<=window.endpwn.changelog.date?window.endpwn.changelog.date:E.date;E.body=window.endpwn.changelog.body+"\\n\\n"+E.body}return E}' + }, + // crash screen hijack + { + signature:'var e=o("div",{},void 0,o("p",{},void 0,a.default.Messages.ERRORS_UNEXPECTED_CRASH),o("p",{},void 0,a.default.Messages.ERRORS_ACTION_TO_TAKE)),t=o(c.default,{size:l.ButtonSizes.LARGE,onClick:this._handleSubmitReport},void 0,a.default.Messages.ERRORS_RELOAD);return o(u.default,{theme:this.props.theme,title:a.default.Messages.UNSUPPORTED_BROWSER_TITLE,', + payload:`var e=o("div",{},void 0,o("p",{},void 0,"Something has gone very, very wrong, and Discord has crashed."),o("p",{},void 0,"If this is the first time you've seen this error screen, reload and hope for the best. If this screen appears again, follow these steps:"),o("p",{},void 0,"Try removing any new plugins and restarting again. If this solves the problem there may be a bug in a plugin or a conflict."),o("p",{},void 0,"If problems continue, it's likely that there is a bug in EndPwn or Discord."),o("p",{},void 0,"If you need help, join the EndPwn Discord server (https://discord.gg/wXdPNf2)"),o("p",{},void 0,"Details may be available in the console (Ctrl+Shift+I), but at this level of crash we can't be certain.")),t=o("div",{},void 0,o(c.default,{size:l.ButtonSizes.LARGE,onClick:()=>window.electron.getCurrentWindow().reload()},void 0,"Reload"),o(c.default,{size:l.ButtonSizes.LARGE,onClick:()=>{window.$api.localStorage.set('safemode',1);window.electron.getCurrentWindow().reload()}},void 0,"Reload in safe mode"));return o(u.default,{theme:this.props.theme,title:"Discord: Fatal Error",` + } + ], + priority: 9999 }, start: function () {