mirror of
https://github.com/Lightcord/Lightcord.git
synced 2025-04-12 00:55:40 +02:00
Re"structuring" pluginCertifier
This commit is contained in:
parent
4ed3c4b78b
commit
93a735193b
File diff suppressed because one or more lines are too long
2
BetterDiscordApp/js/main.min.js
vendored
2
BetterDiscordApp/js/main.min.js
vendored
File diff suppressed because one or more lines are too long
@ -78,6 +78,7 @@ export const settings = {
|
||||
|
||||
/* Content */
|
||||
"Content Error Modal": {id: "fork-ps-1", info: "Shows a modal with plugin/theme errors", implemented: true, hidden: false, cat: "core", category: "content manager"},
|
||||
"Scan Plugins": {id: "fork-ps-6", info: "Scan plugins for any threat that can be hidden inside.", implemented: true, hidden: false, cat: "core", category: "content manager"},
|
||||
"Show Toasts": {id: "fork-ps-2", info: "Shows a small notification for important information", implemented: true, hidden: false, cat: "core", category: "content manager"},
|
||||
"Scroll To Settings": {id: "fork-ps-3", info: "Auto-scrolls to a plugin's settings when the button is clicked (only if out of view)", implemented: true, hidden: false, cat: "core", category: "content manager"},
|
||||
"Automatic Loading": {id: "fork-ps-5", info: "Automatically loads, reloads, and unloads plugins and themes", implemented: true, hidden: false, cat: "core", category: "content manager"},
|
||||
@ -129,6 +130,7 @@ export const defaultCookie = {
|
||||
"fork-ps-3": true,
|
||||
"fork-ps-4": true,
|
||||
"fork-ps-5": true,
|
||||
"fork-ps-6": true,
|
||||
"fork-es-2": false,
|
||||
"fork-es-3": true,
|
||||
"fork-wp-1": false,
|
||||
|
@ -1,8 +1,8 @@
|
||||
const __non_webpack_require__ = window.require
|
||||
import {bdConfig, bdplugins, bdthemes} from "../0globals";
|
||||
import pluginModule from "./pluginModule";
|
||||
import themeModule from "./themeModule";
|
||||
import Utils from "./utils";
|
||||
import * as crypto from "crypto"
|
||||
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
@ -171,9 +171,9 @@ export default new class ContentManager {
|
||||
if (typeof(filename) === "undefined" || typeof(type) === "undefined") return;
|
||||
const isPlugin = type === "plugin";
|
||||
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
|
||||
try {__non_webpack_require__(path.resolve(baseFolder, filename));}
|
||||
try {window.require(path.resolve(baseFolder, filename));}
|
||||
catch (error) {return {name: filename, file: filename, message: "Could not be compiled.", error: {message: error.message, stack: error.stack}};}
|
||||
const content = __non_webpack_require__(path.resolve(baseFolder, filename));
|
||||
const content = window.require(path.resolve(baseFolder, filename));
|
||||
if(!content.name)return {name: filename, file: filename, message: "Cannot escape the ID.", error: {message: "Cannot read property 'replace' of undefined", stack: "Cannot read property 'replace' of undefined"}}
|
||||
content.id = Utils.escapeID(content.name);
|
||||
if (isPlugin) {
|
||||
@ -189,14 +189,14 @@ export default new class ContentManager {
|
||||
delete bdthemes[content.name];
|
||||
bdthemes[content.name] = content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unloadContent(filename, type) {
|
||||
if (typeof(filename) === "undefined" || typeof(type) === "undefined") return;
|
||||
const isPlugin = type === "plugin";
|
||||
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
|
||||
try {
|
||||
delete __non_webpack_require__.cache[__non_webpack_require__.resolve(path.resolve(baseFolder, filename))];
|
||||
delete window.require.cache[window.require.resolve(path.resolve(baseFolder, filename))];
|
||||
}
|
||||
catch (err) {return {name: filename, file: filename, message: "Could not be unloaded.", error: {message: err.message, stack: err.stack}};}
|
||||
}
|
||||
@ -204,7 +204,7 @@ export default new class ContentManager {
|
||||
isLoaded(filename, type) {
|
||||
const isPlugin = type === "plugin";
|
||||
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
|
||||
try {__non_webpack_require__.cache[__non_webpack_require__.resolve(path.resolve(baseFolder, filename))];}
|
||||
try {window.require.cache[window.require.resolve(path.resolve(baseFolder, filename))];}
|
||||
catch (err) {return false;}
|
||||
return true;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ Core.prototype.init = async function() {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
const latestLocalVersion = bdConfig.updater ? bdConfig.updater.LatestVersion : bdConfig.latestVersion;
|
||||
if (latestLocalVersion > bdConfig.version) {
|
||||
Utils.showConfirmationModal("Update Available", [`There is an update available for BandagedBD's Injector (${latestLocalVersion}).`, "You can either update and restart now, or later."], {
|
||||
@ -66,7 +67,7 @@ Core.prototype.init = async function() {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}*/
|
||||
|
||||
Utils.log("Startup", "Initializing Settings");
|
||||
this.initSettings();
|
||||
@ -107,7 +108,7 @@ Core.prototype.init = async function() {
|
||||
DataStore.setBDData("version", bbdVersion);
|
||||
}
|
||||
|
||||
const emojiModule = EmojiModule
|
||||
EmojiModule.start()
|
||||
|
||||
Utils.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")();
|
||||
Utils.suppressErrors(this.patchGuildPills.bind(this), "BD Guild Pills Patch")();
|
||||
@ -125,6 +126,7 @@ Core.prototype.init = async function() {
|
||||
}
|
||||
const logo = document.querySelector("#app-mount > div.typeWindows-1za-n7.withFrame-haYltI.titleBar-AC4pGV.horizontalReverse-3tRjY7.flex-1O1GKY.directionRowReverse-m8IjIq.justifyStart-2NDFzi.alignStretch-DpGPf3.da-typeWindows.da-withFrame.da-titleBar.da-horizontalReverse.da-flex.da-directionRowReverse.da-justifyStart.da-alignStretch > div.wordmarkWindows-1v0lYD.wordmark-2iDDfm.da-wordmarkWindows.da-wordmark")
|
||||
if(logo){
|
||||
logo.style.top = "3px"
|
||||
logo.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" height="10" width="70" viewBox="0 0 72.54 10" style="margin-left: -5px, margin-top: 10px">
|
||||
<path fill="currentColor" d="M44.81,9.67V6.33c0-1.21,2.13-1.49,2.78-.28l2-.81A3.53,3.53,0,0,0,46.2,3c-1.92,0-3.81,1.13-3.81,3.33V9.67c0,2.21,1.89,3.33,3.77,3.33a3.87,3.87,0,0,0,3.45-2.18l-2.12-1C47,11.17,44.81,10.85,44.81,9.67ZM10.68,12.89h2.41V3.17H10.68ZM71.76,3.14H68.19V7.23L70.57,9.4v-4h1.27c.81,0,1.21.41,1.21,1v3c0,.63-.38,1.05-1.21,1.05H68.18v2.31h3.57c1.92,0,3.72-1,3.72-3.2V6.39C75.48,4.13,73.68,3.14,71.76,3.14ZM54.22,3c-2,0-4,1.1-4,3.34V9.66c0,2.23,2,3.34,4,3.34s3.95-1.11,3.95-3.34V6.34C58.19,4.11,56.2,3,54.22,3Zm1.55,6.66c0,.7-.78,1.06-1.54,1.06s-1.55-.35-1.55-1.06V6.34c0-.72.75-1.1,1.5-1.1s1.59.35,1.59,1.1ZM66.84,6.34c0-2.29-1.58-3.2-3.55-3.2H59.46v9.73h2.45V9.77h.43l2.22,3.09h3L65,9.52C66.13,9.15,66.84,8.14,66.84,6.34ZM63.33,7.65H61.91V5.43h1.42A1.11,1.11,0,1,1,63.33,7.65ZM29.83,13h2.42V3.06H29.83V6.73l-3,0V3.09H24.7v9.78h2.14V8.68l3,0ZM17.16,9.76V6.42c0-1.21,2.13-1.49,2.78-.28l2-.81a3.55,3.55,0,0,0-3.36-2.24c-1.92,0-3.81,1.13-3.81,3.33V9.76c0,2.21,2,3.15,3.9,3.15s3.58-1,3.58-3V7.58H18.79l0,1.36H20.3v.77C20.3,10.92,17.16,10.94,17.16,9.76Z" transform="translate(-2.93 -3)"/>
|
||||
<polygon fill="currentColor" points="35.91 0.06 38.43 0.06 38.43 1.84 35.92 1.81 35.97 10 33.55 10 33.49 1.75 30.98 1.74 30.98 0.06 33.49 0.06 35.91 0.06"/>
|
||||
@ -176,9 +178,13 @@ Core.prototype.initSettings = function () {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let classNameLayer
|
||||
let classNameSocialLinks
|
||||
let classNameModal
|
||||
|
||||
Core.prototype.initObserver = function () {
|
||||
const mainObserver = new MutationObserver((mutations) => {
|
||||
|
||||
for (let i = 0, mlen = mutations.length; i < mlen; i++) {
|
||||
const mutation = mutations[i];
|
||||
if (typeof pluginModule !== "undefined") pluginModule.rawObserver(mutation);
|
||||
@ -188,13 +194,9 @@ Core.prototype.initObserver = function () {
|
||||
|
||||
const node = mutation.addedNodes[0];
|
||||
|
||||
let [
|
||||
classNameLayer,
|
||||
classNameSocialLinks
|
||||
] = [
|
||||
BDModules.get((e) => e.layer && typeof e.layer === "string" && e.animating)[0].layer,
|
||||
BDModules.get((e) => e.socialLinks && typeof e.socialLinks === "string")[0].socialLinks
|
||||
]
|
||||
if(!classNameLayer)classNameLayer = BDModules.get((e) => e.layer && typeof e.layer === "string" && e.animating)[0].layer
|
||||
if(!classNameSocialLinks)classNameSocialLinks = BDModules.get((e) => e.socialLinks && typeof e.socialLinks === "string")[0].socialLinks
|
||||
if(!classNameModal)classNameModal = BDModules.get((e) => e.modal && typeof e.modal === "string" && e.inner && typeof e.inner === "string" && !e.responsiveWidthMobile)[0].modal
|
||||
|
||||
if (node.classList.contains(classNameLayer)) {
|
||||
if (node.getElementsByClassName("guild-settings-base-section").length) node.setAttribute("layer-id", "server-settings");
|
||||
@ -208,6 +210,28 @@ Core.prototype.initObserver = function () {
|
||||
|
||||
if (node.parentElement == document.body && node.querySelector("#ace_settingsmenu")) node.id = "ace_settingsmenu_container";
|
||||
|
||||
/*
|
||||
if(node.classList.contains(classNameModal)){
|
||||
try{
|
||||
/**
|
||||
* @type {Element}
|
||||
*//*
|
||||
const UserProfile = Utils.getNestedProp(node, "childNodes.0.childNodes.0")
|
||||
let user = BDV2.getInternalInstance(node).pendingProps.children.props.children.props.user
|
||||
console.log(user)
|
||||
|
||||
if(UserProfile && UserProfile.childNodes.length === 2){
|
||||
let header = UserProfile.childNodes[0].childNodes[0]
|
||||
|
||||
let children = BDV2.getInternalInstance(header).return.pendingProps.children[1]
|
||||
console.log(children)
|
||||
children.push(BDV2.react.createElement("p", {}, "sltsv"))
|
||||
}
|
||||
}catch(e){
|
||||
console.error("An error occured in Badge Rendering:", e)
|
||||
}
|
||||
}*/
|
||||
|
||||
// Emoji Picker
|
||||
//node.getElementsByClassName("emojiPicker-3m1S-j").length && !node.querySelector(".emojiPicker-3m1S-j").parentElement.classList.contains("animatorLeft-1EQxU0")
|
||||
//if (node.classList.contains(classNameLayer2) && node.getElementsByClassName(classNameEmojiPicker).length && !node.querySelector("."+classNameEmojiPicker).parentElement.classList.contains(classNameAnimatorLeft)) quickEmoteMenu.obsCallback(node);
|
||||
@ -481,7 +505,7 @@ Core.prototype.patchMemberList = function() {
|
||||
children.push(
|
||||
BDV2.React.createElement(TooltipWrap, {color: "black", side: "top", text: "Lightcord Developer"},
|
||||
BDV2.React.createElement(Anchor, {className: "bd-member-badge", href: "https://github.com/Lightcord/Lightcord", title: "Lightcord", target: "_blank"},
|
||||
BDV2.React.createElement(LightcordLogo, {size: "32px", className: "bd-logo"})
|
||||
BDV2.React.createElement(LightcordLogo, {size: "16px", className: "bd-logo"})
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -180,6 +180,10 @@ export default new class EmojiModule {
|
||||
this.cancelEmoteRender();
|
||||
this.cancelEmoteRender = null;
|
||||
}
|
||||
|
||||
start(){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function D(e, t, n, r, o, i, s, u, l, c) {
|
||||
|
@ -4,16 +4,11 @@ import * as crypto from "crypto"
|
||||
import BDV2 from "./v2"
|
||||
import tooltipWrap from "../ui/tooltipWrap"
|
||||
import Utils from "./utils"
|
||||
import { createReadStream } from "fs"
|
||||
import { basename } from "path"
|
||||
|
||||
const debug = true
|
||||
const cache = {}
|
||||
const cache2 = {}
|
||||
/*
|
||||
const PinnedModule = BDModules.get(e => e.default && e.default.getPinnedMessages)[0].default
|
||||
const ChannelModule = BDModules.get(e => e.default && e.default.getChannelId)[0].default
|
||||
const fetchMessagesModule = BDModules.get(e => e.default && e.default.fetchMessages)[0].default
|
||||
const fetchMessagesModule2 = BDModules.get(e => e.default && e.default.fetchMessages)[1].default
|
||||
const getMessagesModule = BDModules.get(e => e.default && e.default.getMessages)[0].default*/
|
||||
|
||||
export default new class PluginCertifier {
|
||||
constructor(){}
|
||||
@ -25,103 +20,15 @@ export default new class PluginCertifier {
|
||||
}
|
||||
|
||||
start(){
|
||||
/*const dispatcher = window.Lightcord.DiscordModules.dispatcher
|
||||
const constants = window.Lightcord.DiscordModules.constants
|
||||
|
||||
const originalFetchMessages = fetchMessagesModule.fetchMessages
|
||||
fetchMessagesModule.fetchMessages = function(){
|
||||
const returnValue = originalFetchMessages.apply(this, arguments)
|
||||
if(returnValue instanceof Promise){
|
||||
returnValue
|
||||
.then(() => {
|
||||
const ev = getMessagesModule.getMessages(ChannelModule.getChannelId())
|
||||
process.nextTick(() => {
|
||||
for(const message of ev._array){
|
||||
const attachments = message.attachments || []
|
||||
if(attachments.length === 0)continue // no attachments
|
||||
|
||||
attachments.forEach(attachment => {
|
||||
processAttachment(attachment)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
}
|
||||
|
||||
const originalFetchMessages2 = fetchMessagesModule2.fetchMessages
|
||||
fetchMessagesModule2.fetchMessages = function(){
|
||||
const returnValue = originalFetchMessages2.apply(this, arguments)
|
||||
if(returnValue instanceof Promise){
|
||||
returnValue
|
||||
.then(() => {
|
||||
const ev = getMessagesModule.getMessages(ChannelModule.getChannelId())
|
||||
process.nextTick(() => {
|
||||
for(const message of ev._array){
|
||||
const attachments = message.attachments || []
|
||||
if(attachments.length === 0)continue // no attachments
|
||||
|
||||
attachments.forEach(attachment => {
|
||||
processAttachment(attachment)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
|
||||
const alreadyUsed = {}
|
||||
const originalGetPinnedMessages = PinnedModule.getPinnedMessages.bind(PinnedModule)
|
||||
PinnedModule.getPinnedMessages = function(){
|
||||
const pinned = originalGetPinnedMessages(...arguments)
|
||||
if(!pinned || alreadyUsed[pinned.id])return pinned
|
||||
alreadyUsed[pinned.id] = true
|
||||
|
||||
setTimeout(() => {
|
||||
delete alreadyUsed[pinned.id]
|
||||
for(const message of pinned.messages){
|
||||
const attachments = message.attachments || []
|
||||
if(attachments.length === 0)continue // no attachments
|
||||
|
||||
attachments.forEach(attachment => {
|
||||
processAttachment(attachment)
|
||||
})
|
||||
}
|
||||
}, 50);
|
||||
|
||||
return pinned
|
||||
}
|
||||
|
||||
dispatcher.subscribe(constants.ActionTypes.MESSAGE_CREATE, (ev) => {
|
||||
const message = ev.message
|
||||
if(message.channel_id !== ChannelModule.getChannelId())return
|
||||
process.nextTick(() => {
|
||||
const attachments = message.attachments || []
|
||||
if(attachments.length === 0)return // no attachments
|
||||
|
||||
attachments.forEach(attachment => {
|
||||
processAttachment(attachment)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const messages = getMessagesModule.getMessages(ChannelModule.getChannelId())
|
||||
process.nextTick(() => {
|
||||
for(const message of messages._array){
|
||||
const attachments = message.attachments || []
|
||||
if(attachments.length === 0)continue // no attachments
|
||||
|
||||
attachments.forEach(attachment => {
|
||||
processAttachment(attachment)
|
||||
})
|
||||
}
|
||||
})*/
|
||||
isTrusted(hash){
|
||||
return cache[hash] && !cache[hash].suspect
|
||||
}
|
||||
}
|
||||
|
||||
function checkViruses(hash, data, id){
|
||||
export function checkViruses(hash, data, resultCallback, removeCallback){
|
||||
data = data.toString("utf8").split(/[^\w\d]+/g)
|
||||
let isHarmful = false
|
||||
for(let keyword of data){
|
||||
@ -161,8 +68,8 @@ function checkViruses(hash, data, id){
|
||||
/_0x\w{4}\('0x[\dabcdef]+'\)/g,
|
||||
/_0x\w{4}\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // _0x8db7('0x0', 'x1]f')
|
||||
/** mangled */
|
||||
/\w+\('0x[\dabcdef]+'\)/g,
|
||||
/\w+\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // _0x8db7('0x0', 'x1]f')
|
||||
/\w+\('0x[\dabcdef]+'\)/g, // b('0x0')
|
||||
/\w+\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // b('0x0', 'x1]f')
|
||||
]
|
||||
for(let regex of regexps){
|
||||
if(isHarmful)break
|
||||
@ -171,7 +78,7 @@ function checkViruses(hash, data, id){
|
||||
}
|
||||
}
|
||||
|
||||
if(!isHarmful)return
|
||||
if(!isHarmful)return removeCallback()
|
||||
cache[hash] = {
|
||||
suspect: true,
|
||||
name: hashToUrl[hash].split("/").pop(),
|
||||
@ -181,39 +88,57 @@ function checkViruses(hash, data, id){
|
||||
|
||||
console.log(`Found potentially dangerous ${cache[hash].type.toLowerCase()}: ${cache[hash].name}`)
|
||||
|
||||
renderToElements(id, cache[hash], cache[hash].name)
|
||||
resultCallback(cache[hash])
|
||||
}
|
||||
|
||||
const hashToUrl = {}
|
||||
|
||||
function processAttachment(attachment, id){
|
||||
export function checkHash(hash, data, filename, resultCallback, removeCallback){
|
||||
console.log(`File: ${filename} hash: ${hash}`)
|
||||
if(!cache[hash]){
|
||||
nodeFetch("https://cdn.jsdelivr.net/gh/Lightcord/filehashes@master/hashes/"+hash, { // Using node-fetch to bypass cors
|
||||
headers: {
|
||||
"User-Agent": electron.remote.getCurrentWebContents().userAgent // have to set user-agent
|
||||
}
|
||||
}).then(async res => {
|
||||
if(res.status !== 200){
|
||||
if(filename.endsWith(".theme.css"))return removeCallback()
|
||||
return checkViruses(hash, data, resultCallback, wrongCallback)
|
||||
}
|
||||
const result = await res.json()
|
||||
|
||||
cache[hash] = result
|
||||
|
||||
resultCallback(result)
|
||||
}).catch(()=>{})
|
||||
}else{
|
||||
const result = cache[hash]
|
||||
|
||||
resultCallback(result)
|
||||
}
|
||||
}
|
||||
|
||||
export function processFile(__path, resultCallback, removeCallback){
|
||||
const hash = crypto.createHash("sha256")
|
||||
let data = Buffer.alloc(0)
|
||||
|
||||
createReadStream(__path).on("data", chunk => {
|
||||
data = Buffer.concat([data, chunk])
|
||||
hash.update(chunk)
|
||||
}).on("end", () => {
|
||||
const hashResult = hash.digest("hex")
|
||||
|
||||
hashToUrl[hashResult] = __path
|
||||
|
||||
checkHash(hashResult, data, basename(__path), resultCallback, removeCallback)
|
||||
})
|
||||
}
|
||||
|
||||
export function processAttachment(attachment, id){
|
||||
if(!document.getElementById(id))return
|
||||
if(!attachment.url.startsWith("https://cdn.discordapp.com/"))return document.getElementById(id).remove()
|
||||
if(!attachment.filename.endsWith(".plugin.js") && !attachment.filename.endsWith(".theme.css"))return document.getElementById(id).remove()
|
||||
|
||||
let nextHash = (hash, data) => {
|
||||
if(!cache[hash]){
|
||||
nodeFetch("https://cdn.jsdelivr.net/gh/Lightcord/filehashes@master/hashes/"+hash, { // Using node-fetch to bypass cors
|
||||
headers: {
|
||||
"User-Agent": electron.remote.getCurrentWebContents().userAgent // have to set user-agent
|
||||
}
|
||||
}).then(async res => {
|
||||
if(res.status !== 200)return checkViruses(hash, data, id)
|
||||
const result = await res.json()
|
||||
|
||||
cache[hash] = result
|
||||
|
||||
renderToElements(id, result, attachment.filename)
|
||||
}).catch(()=>{})
|
||||
}else{
|
||||
const result = cache[hash]
|
||||
|
||||
renderToElements(id, result, attachment.filename)
|
||||
}
|
||||
}
|
||||
|
||||
if(cache2[attachment.url])return nextHash(cache2[attachment.url])
|
||||
|
||||
nodeFetch(attachment.url, {
|
||||
headers: {
|
||||
"User-Agent": electron.remote.getCurrentWebContents().userAgent
|
||||
@ -232,7 +157,11 @@ function processAttachment(attachment, id){
|
||||
cache2[attachment.url] = hashResult
|
||||
hashToUrl[hashResult] = attachment.url
|
||||
|
||||
nextHash(hashResult, data)
|
||||
checkHash(hashResult, data, attachment.filename, (result) => {
|
||||
renderToElements(id, result, attachment.filename)
|
||||
}, () => {
|
||||
document.getElementById(id).remove()
|
||||
})
|
||||
})
|
||||
}).catch(()=>{})
|
||||
}
|
||||
@ -252,7 +181,6 @@ function renderToElements(id, result, filename){
|
||||
if(!flowerStarModule)flowerStarModule = BDModules.get(e => e.flowerStarContainer)[0]
|
||||
if(!childModule)childModule = BDModules.get(e => e.childContainer)[0]
|
||||
|
||||
|
||||
console.log(result)
|
||||
if(result.suspect){
|
||||
try{
|
||||
|
@ -107,7 +107,7 @@ PluginModule.prototype.loadPlugin = async function(filename) {
|
||||
if (settingsCookie["fork-ps-2"]) Utils.showToast(`${filename} could not be loaded.`, {type: "error"});
|
||||
return Utils.err("ContentManager", `${filename} could not be loaded.`, error);
|
||||
}
|
||||
const plugin = Object.values(bdplugins).find(p => p.filename == filename).plugin;
|
||||
const plugin = Object.values(bdplugins).find(p => (console.log(p.filename, filename)) || p.filename == filename).plugin;
|
||||
try { if (plugin.load && typeof(plugin.load) == "function") plugin.load();}
|
||||
catch (err) {if (settingsCookie["fork-ps-1"]) Utils.showContentErrors({plugins: [err]});}
|
||||
Utils.log("ContentManager", `${plugin.getName()} v${plugin.getVersion()} was loaded.`);
|
||||
|
@ -9,6 +9,9 @@ import EditIcon from "./icons/edit";
|
||||
import DeleteIcon from "./icons/delete";
|
||||
import Switch from "./components/switch";
|
||||
import TooltipWrap from "./tooltipWrap";
|
||||
import { processFile } from "../modules/pluginCertifier";
|
||||
import contentManager from "../modules/contentManager";
|
||||
import { resolve } from "path";
|
||||
|
||||
const React = BDV2.React;
|
||||
const anchorClasses = BDV2.anchorClasses;
|
||||
@ -32,7 +35,8 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
|
||||
this.state = {
|
||||
checked: this.props.enabled,
|
||||
settings: false,
|
||||
reloads: 0
|
||||
reloads: 0,
|
||||
trusted: false
|
||||
};
|
||||
}
|
||||
|
||||
@ -135,6 +139,10 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
|
||||
</TooltipWrap>;
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
this.unmounted = true
|
||||
}
|
||||
|
||||
get links() {
|
||||
const links = [];
|
||||
const addon = this.props.addon;
|
||||
@ -182,7 +190,21 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
|
||||
if (this.state.settings) return this.settingsComponent;
|
||||
const {authorId, authorLink} = this.props.addon;
|
||||
|
||||
return BDV2.react.createElement("div", {className: "bd-card bd-addon-card settings-closed ui-switch-item"},
|
||||
const style = {}
|
||||
if(!this.isScanning){
|
||||
this.isScanning = true
|
||||
processFile(resolve(this.props.addon.filename.endsWith(".plugin.js") ? contentManager.pluginsFolder : contentManager.themesFolder, this.props.addon.filename), (result) => {
|
||||
if(this.unmounted)return
|
||||
this.setState({
|
||||
isTrusted: !result.suspect
|
||||
}, () => {})
|
||||
})
|
||||
}else{
|
||||
if(this.state.isTrusted){
|
||||
style.borderColor = "#4087ed"
|
||||
}
|
||||
}
|
||||
return BDV2.react.createElement("div", {className: "bd-card bd-addon-card settings-closed ui-switch-item", style},
|
||||
BDV2.react.createElement("div", {className: "bd-addon-header bda-header"},
|
||||
BDV2.react.createElement("div", {className: "bd-card-title bda-header-title"}, this.buildTitle(this.name, this.version, {name: this.author, id: authorId, link: authorLink})),
|
||||
BDV2.react.createElement("div", {className: "bd-addon-controls bda-controls"},
|
||||
|
@ -95,7 +95,8 @@ export default class CardList extends BDV2.reactComponent {
|
||||
toggle: this.manager.toggle.bind(this.manager),
|
||||
//edit: this.edit.bind(this),
|
||||
remove: this.delete.bind(this),
|
||||
addon: addon
|
||||
addon: addon,
|
||||
hash: addon.hash
|
||||
};
|
||||
}
|
||||
|
||||
|
BIN
assets/logo-wide.psd
Normal file
BIN
assets/logo-wide.psd
Normal file
Binary file not shown.
@ -109,8 +109,6 @@ async function privateInit(){
|
||||
fs.writeFileSync(ZeresPluginLibraryPath, content)
|
||||
})
|
||||
|
||||
// Should we download 1XenoLib and BDFDB too ? response: No
|
||||
|
||||
BetterDiscordConfig.haveInstalledDefault = true // Inform User about what we just did
|
||||
}
|
||||
if(!fs.existsSync(themePath)){
|
||||
|
Loading…
x
Reference in New Issue
Block a user