mirror of
https://github.com/Lightcord/Lightcord.git
synced 2025-04-12 00:55:40 +02:00
AccountInfos
PluginCertification
This commit is contained in:
parent
b28440fda6
commit
2fd9770d7e
File diff suppressed because one or more lines are too long
27
BetterDiscordApp/package-lock.json
generated
27
BetterDiscordApp/package-lock.json
generated
@ -994,6 +994,28 @@
|
|||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/prop-types": {
|
||||||
|
"version": "15.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
|
||||||
|
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
|
||||||
|
},
|
||||||
|
"@types/react": {
|
||||||
|
"version": "16.9.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.35.tgz",
|
||||||
|
"integrity": "sha512-q0n0SsWcGc8nDqH2GJfWQWUOmZSJhXV64CjVN5SvcNti3TdEaA3AH0D8DwNmMdzjMAC/78tB8nAZIlV8yTz+zQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"csstype": "^2.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"version": "16.9.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz",
|
||||||
|
"integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@webassemblyjs/ast": {
|
"@webassemblyjs/ast": {
|
||||||
"version": "1.8.5",
|
"version": "1.8.5",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||||
@ -2607,6 +2629,11 @@
|
|||||||
"css-tree": "1.0.0-alpha.29"
|
"css-tree": "1.0.0-alpha.29"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"csstype": {
|
||||||
|
"version": "2.6.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
|
||||||
|
"integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w=="
|
||||||
|
},
|
||||||
"cyclist": {
|
"cyclist": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
"webpack-cli": "^3.2.3"
|
"webpack-cli": "^3.2.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/react-dom": "^16.9.8",
|
||||||
"mkdirp": "^1.0.4",
|
"mkdirp": "^1.0.4",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
|
@ -49,7 +49,7 @@ export const settings = {
|
|||||||
"Automatic Loading": {id: "fork-ps-5", info: "Automatically loads, reloads, and unloads plugins and themes", 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"},
|
||||||
|
|
||||||
/* Developer */
|
/* Developer */
|
||||||
"Developer Mode": {id: "bda-gs-8", info: "Developer Mode", implemented: true, hidden: false, cat: "core", category: "developer settings"},
|
"Developer Mode": {id: "bda-gs-8", info: "Developer Mode Toggle", implemented: true, hidden: false, cat: "core", category: "developer settings"},
|
||||||
"Copy Selector": {id: "fork-dm-1", info: "Adds a \"Copy Selector\" option to context menus when developer mode is active", implemented: true, hidden: false, cat: "core", category: "developer settings"},
|
"Copy Selector": {id: "fork-dm-1", info: "Adds a \"Copy Selector\" option to context menus when developer mode is active", implemented: true, hidden: false, cat: "core", category: "developer settings"},
|
||||||
"React DevTools": {id: "reactDevTools", info: "Adds react developer tools to the devtools. Must be installed in Google Chrome on your pc.", implemented: true, hidden: true, cat: "core", category: "developer settings"},
|
"React DevTools": {id: "reactDevTools", info: "Adds react developer tools to the devtools. Must be installed in Google Chrome on your pc.", implemented: true, hidden: true, cat: "core", category: "developer settings"},
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ export const defaultCookie = {
|
|||||||
"bda-gs-5": true,
|
"bda-gs-5": true,
|
||||||
"bda-gs-6": false,
|
"bda-gs-6": false,
|
||||||
"bda-gs-7": false,
|
"bda-gs-7": false,
|
||||||
"bda-gs-8": false,
|
"bda-gs-8": true,
|
||||||
"bda-es-0": true,
|
"bda-es-0": true,
|
||||||
"bda-es-1": true,
|
"bda-es-1": true,
|
||||||
"bda-es-2": true,
|
"bda-es-2": true,
|
||||||
|
@ -12,6 +12,7 @@ import DOM from "./domtools";
|
|||||||
import BDLogo from "../ui/bdLogo";
|
import BDLogo from "../ui/bdLogo";
|
||||||
import TooltipWrap from "../ui/tooltipWrap";
|
import TooltipWrap from "../ui/tooltipWrap";
|
||||||
import LightcordLogo from "../ui/lightcordLogo";
|
import LightcordLogo from "../ui/lightcordLogo";
|
||||||
|
import PluginCertifier from "./pluginCertifier";
|
||||||
|
|
||||||
function Core() {
|
function Core() {
|
||||||
// Object.assign(bdConfig, __non_webpack_require__(DataStore.configFile));
|
// Object.assign(bdConfig, __non_webpack_require__(DataStore.configFile));
|
||||||
@ -84,6 +85,8 @@ Core.prototype.init = async function() {
|
|||||||
if (settingsCookie["bda-dc-0"]) document.querySelector(".btn.btn-disconnect").click();
|
if (settingsCookie["bda-dc-0"]) document.querySelector(".btn.btn-disconnect").click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
new PluginCertifier().start()
|
||||||
|
|
||||||
Utils.log("Startup", "Removing Loading Icon");
|
Utils.log("Startup", "Removing Loading Icon");
|
||||||
if (document.getElementsByClassName("bd-loaderv2").length) document.getElementsByClassName("bd-loaderv2")[0].remove();
|
if (document.getElementsByClassName("bd-loaderv2").length) document.getElementsByClassName("bd-loaderv2")[0].remove();
|
||||||
Utils.log("Startup", "Initializing Main Observer");
|
Utils.log("Startup", "Initializing Main Observer");
|
||||||
|
197
BetterDiscordApp/src/modules/pluginCertifier.js
Normal file
197
BetterDiscordApp/src/modules/pluginCertifier.js
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
import nodeFetch from "node-fetch"
|
||||||
|
import * as electron from "electron"
|
||||||
|
import * as crypto from "crypto"
|
||||||
|
import BDV2 from "./v2"
|
||||||
|
import tooltipWrap from "../ui/tooltipWrap"
|
||||||
|
|
||||||
|
const debug = false
|
||||||
|
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 class PluginCertifier {
|
||||||
|
constructor(){}
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processAttachment(attachment){
|
||||||
|
if(!attachment.url.startsWith("https://cdn.discordapp.com/"))return
|
||||||
|
if(!attachment.filename.endsWith(".plugin.js") && !attachment.filename.endsWith(".theme.css"))return
|
||||||
|
|
||||||
|
let nextHash = (hash) => {
|
||||||
|
if(!cache[hash]){
|
||||||
|
nodeFetch("https://raw.githubusercontent.com/Lightcord/filehashes/master/hashes/"+hash, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": electron.remote.getCurrentWebContents().userAgent
|
||||||
|
}
|
||||||
|
}).then(async res => {
|
||||||
|
if(res.status !== 200)return
|
||||||
|
const result = await res.json()
|
||||||
|
debug&&console.log(`Hash valid:`, result)
|
||||||
|
|
||||||
|
cache[hash] = result
|
||||||
|
|
||||||
|
let elements = Array.from(document.querySelectorAll(`a[href="${attachment.url}"]`)).filter(e => !e.classList.contains("da-fileNameLink")).map(e => e.parentElement)
|
||||||
|
renderToElements(elements, result, attachment.filename)
|
||||||
|
}).catch(()=>{})
|
||||||
|
}else{
|
||||||
|
const result = cache[hash]
|
||||||
|
debug&&console.log(`Hash valid:`, result)
|
||||||
|
|
||||||
|
let elements = Array.from(document.querySelectorAll(`a[href="${attachment.url}"]`)).filter(e => !e.classList.contains("da-fileNameLink")).map(e => e.parentElement)
|
||||||
|
renderToElements(elements, result, attachment.filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cache2[attachment.url])return nextHash(cache2[attachment.url])
|
||||||
|
|
||||||
|
nodeFetch(attachment.url, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": electron.remote.getCurrentWebContents().userAgent
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if(res.status !== 200)throw new Error("File doesn't exist.")
|
||||||
|
const hash = crypto.createHash("sha256")
|
||||||
|
res.body.pipe(hash)
|
||||||
|
res.body.on("end", () => {
|
||||||
|
const hashResult = hash.digest("hex")
|
||||||
|
debug&&console.log(`Calculated hash for file ${attachment.filename}: ${hashResult}`)
|
||||||
|
|
||||||
|
cache2[attachment.url] = hashResult
|
||||||
|
|
||||||
|
nextHash(hashResult)
|
||||||
|
})
|
||||||
|
}).catch(()=>{})
|
||||||
|
}
|
||||||
|
|
||||||
|
const flowerStarModule = BDModules.get(e => e.flowerStarContainer)[0]
|
||||||
|
const childModule = BDModules.get(e => e.childContainer)[0]
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {HTMLDivElement[]} elements
|
||||||
|
* @param {{type: "Theme"|"Plugin", name: string}} result
|
||||||
|
*/
|
||||||
|
function renderToElements(elements, result, filename){
|
||||||
|
|
||||||
|
elements.forEach(e => {
|
||||||
|
if(e.childNodes.length > 3)return
|
||||||
|
const div = document.createElement("div")
|
||||||
|
e.appendChild(div)
|
||||||
|
if(!result.official){
|
||||||
|
BDV2.reactDom.render(BDV2.react.createElement(tooltipWrap, {text: result.type+" "+result.name+" is certified by Lightcord."},
|
||||||
|
BDV2.react.createElement("div", {className: flowerStarModule.flowerStarContainer, style: {width: "16px", height: "16px"}},
|
||||||
|
BDV2.react.createElement("svg", {className: flowerStarModule.flowerStar, "aria-hidden":"false",width:"16px",height:"16px",viewBox:"0 0 16 15.2"},
|
||||||
|
BDV2.react.createElement("path", {fill:"#4f545c", "fill-rule":"evenodd",d:"m16 7.6c0 .79-1.28 1.38-1.52 2.09s.44 2 0 2.59-1.84.35-2.46.8-.79 1.84-1.54 2.09-1.67-.8-2.47-.8-1.75 1-2.47.8-.92-1.64-1.54-2.09-2-.18-2.46-.8.23-1.84 0-2.59-1.54-1.3-1.54-2.09 1.28-1.38 1.52-2.09-.44-2 0-2.59 1.85-.35 2.48-.8.78-1.84 1.53-2.12 1.67.83 2.47.83 1.75-1 2.47-.8.91 1.64 1.53 2.09 2 .18 2.46.8-.23 1.84 0 2.59 1.54 1.3 1.54 2.09z"})
|
||||||
|
),
|
||||||
|
BDV2.react.createElement("div", {className: childModule.childContainer},
|
||||||
|
BDV2.react.createElement("svg", {"aria-hidden":"false",width:"16px",height:"16px",viewBox:"0 0 16 15.2"},
|
||||||
|
BDV2.react.createElement("path", {fill:"#ffffff",d:"M7.4,11.17,4,8.62,5,7.26l2,1.53L10.64,4l1.36,1Z"})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), div)
|
||||||
|
}else{
|
||||||
|
BDV2.reactDom.render(BDV2.react.createElement(tooltipWrap, {text: result.type+" "+result.name+" was made by the developers of Lightcord.",style:"brand"},
|
||||||
|
BDV2.react.createElement("div", {className: flowerStarModule.flowerStarContainer, style: {width: "16px", height: "16px"}},
|
||||||
|
BDV2.react.createElement("svg", {className: flowerStarModule.flowerStar, "aria-hidden":"false",width:"16px",height:"16px",viewBox:"0 0 16 15.2",stroke:"#36393f",style:{color:"#4087ed"}},
|
||||||
|
BDV2.react.createElement("path", {fill:"currentColor", "fill-rule":"evenodd",d:"m16 7.6c0 .79-1.28 1.38-1.52 2.09s.44 2 0 2.59-1.84.35-2.46.8-.79 1.84-1.54 2.09-1.67-.8-2.47-.8-1.75 1-2.47.8-.92-1.64-1.54-2.09-2-.18-2.46-.8.23-1.84 0-2.59-1.54-1.3-1.54-2.09 1.28-1.38 1.52-2.09-.44-2 0-2.59 1.85-.35 2.48-.8.78-1.84 1.53-2.12 1.67.83 2.47.83 1.75-1 2.47-.8.91 1.64 1.53 2.09 2 .18 2.46.8-.23 1.84 0 2.59 1.54 1.3 1.54 2.09z"})
|
||||||
|
),
|
||||||
|
BDV2.react.createElement("div", {className: childModule.childContainer},
|
||||||
|
BDV2.react.createElement("svg", {"aria-hidden":"false",width:"16px",height:"16px",viewBox:"0 0 16 15.2"},
|
||||||
|
BDV2.react.createElement("path", {fill:"#ffffff",d:"M10.7,5.28a2.9,2.9,0,0,0-2.11.86.11.11,0,0,0,0,.16l1.05.94a.11.11,0,0,0,.15,0,1.27,1.27,0,0,1,.9-.33c.65,0,.65.73.65.73a.64.64,0,0,1-.65.65,1.73,1.73,0,0,1-1.18-.54c-.31-.26-.36-.32-.73-.66S7.06,5.28,5.65,5.28A2.26,2.26,0,0,0,3.37,7.56,2.59,2.59,0,0,0,3.82,9a2.18,2.18,0,0,0,1.83.89,2.94,2.94,0,0,0,2.1-.81.11.11,0,0,0,0-.16L6.74,8A.11.11,0,0,0,6.6,8a1.58,1.58,0,0,1-.94.29h0A.71.71,0,0,1,5,7.56H5a.63.63,0,0,1,.65-.64c.71,0,1.42.75,1.94,1.27.75.76,1.66,1.79,3.11,1.74A2.28,2.28,0,0,0,13,7.64a2.59,2.59,0,0,0-.45-1.47A2.14,2.14,0,0,0,10.7,5.28Z"})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), div)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -86,13 +86,25 @@ export default new class V2 {
|
|||||||
* @type {typeof React}
|
* @type {typeof React}
|
||||||
*/
|
*/
|
||||||
get react() {return this.internal.react;}
|
get react() {return this.internal.react;}
|
||||||
|
/**
|
||||||
|
* @type {typeof React}
|
||||||
|
*/
|
||||||
get React() {return this.internal.react;}
|
get React() {return this.internal.react;}
|
||||||
|
/**
|
||||||
|
* @type {typeof import("react-dom")}
|
||||||
|
*/
|
||||||
get reactDom() {return this.internal.reactDom;}
|
get reactDom() {return this.internal.reactDom;}
|
||||||
|
/**
|
||||||
|
* @type {typeof import("react-dom")}
|
||||||
|
*/
|
||||||
get ReactDom() {return this.internal.reactDom;}
|
get ReactDom() {return this.internal.reactDom;}
|
||||||
/**
|
/**
|
||||||
* @type {typeof React.Component}
|
* @type {typeof React.Component}
|
||||||
*/
|
*/
|
||||||
get reactComponent() {return this.internal.react.Component;}
|
get reactComponent() {return this.internal.react.Component;}
|
||||||
|
/**
|
||||||
|
* @type {typeof React.Component}
|
||||||
|
*/
|
||||||
get ReactComponent() {return this.internal.react.Component;}
|
get ReactComponent() {return this.internal.react.Component;}
|
||||||
|
|
||||||
get anchorClasses() {return this.WebpackModules.findByUniqueProperties(["anchorUnderlineOnHover"]) || {anchor: "anchor-3Z-8Bb", anchorUnderlineOnHover: "anchorUnderlineOnHover-2ESHQB"};}
|
get anchorClasses() {return this.WebpackModules.findByUniqueProperties(["anchorUnderlineOnHover"]) || {anchor: "anchor-3Z-8Bb", anchorUnderlineOnHover: "anchorUnderlineOnHover-2ESHQB"};}
|
||||||
|
@ -69,6 +69,10 @@ export default class V2C_AccountInfos extends React.Component {
|
|||||||
|
|
||||||
getProfileValue(){
|
getProfileValue(){
|
||||||
const user = userModule.getCurrentUser()
|
const user = userModule.getCurrentUser()
|
||||||
|
/**
|
||||||
|
* @type {Date}
|
||||||
|
*/
|
||||||
|
const createdAt = user.createdAt
|
||||||
|
|
||||||
return `+ Username: ${user.username}
|
return `+ Username: ${user.username}
|
||||||
+ Discriminator: ${user.discriminator}
|
+ Discriminator: ${user.discriminator}
|
||||||
@ -76,13 +80,14 @@ export default class V2C_AccountInfos extends React.Component {
|
|||||||
+ ID: ${user.id}
|
+ ID: ${user.id}
|
||||||
+ Avatar: ${user.avatar}
|
+ Avatar: ${user.avatar}
|
||||||
+ Avatar URL: https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.${user.avatar.startsWith("a_") ? "gif" : "png"}?size=4096
|
+ Avatar URL: https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.${user.avatar.startsWith("a_") ? "gif" : "png"}?size=4096
|
||||||
+ Email: ${user.email}
|
+ Creation Date: ${(createdAt.getDate()).toString().padStart(2, "0")}/${(createdAt.getMonth()+1).toString().padStart(2, "0")}/${(createdAt.getFullYear()).toString().padStart(2, "0")} ${createdAt.getHours().toString().padStart(2, "0")}h ${createdAt.getMinutes().toString().padStart(2, "0")}min ${createdAt.getSeconds()}s
|
||||||
+ Flags: ${user.flags}
|
+ Flags: ${user.flags}
|
||||||
+ 2FA: ${user.mfaEnabled ? "Yes" : "No"}
|
+ Has Nitro: ${user.hasPremiumSubscription ? "Yes" : "No"}
|
||||||
+ Has Been On Mobile: ${user.mobile ? "Yes" : "No"}
|
- Email: ${user.email}
|
||||||
+ Phone: ${user.phone || "None"}
|
- 2FA: ${user.mfaEnabled ? "Yes" : "No"}
|
||||||
+ Verified: ${user.verified}
|
- Has Been On Mobile: ${user.mobile ? "Yes" : "No"}
|
||||||
+ Has Nitro: ${user.hasPremiumSubscription ? "Yes" : "No"}`
|
- Phone: ${user.phone || "None"}
|
||||||
|
- Verified: ${user.verified}`
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatistics(){
|
getStatistics(){
|
||||||
|
@ -21,7 +21,8 @@ module.exports = {
|
|||||||
rimraf: `rimraf`,
|
rimraf: `rimraf`,
|
||||||
yauzl: `yauzl`,
|
yauzl: `yauzl`,
|
||||||
mkdirp: `mkdirp`,
|
mkdirp: `mkdirp`,
|
||||||
request: `request`
|
request: `request`,
|
||||||
|
"node-fetch": "node-fetch"
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: [".js", ".jsx"],
|
extensions: [".js", ".jsx"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user