2020-05-16 23:24:51 +02:00
|
|
|
const ModuleLoader = require("./loaders/modules")
|
|
|
|
const { EventEmitter } = require("events")
|
|
|
|
const Logger = require("./Logger")
|
|
|
|
const fs = require("fs")
|
|
|
|
const path = require("path")
|
2020-05-20 21:37:39 +02:00
|
|
|
const electron = require("electron")
|
2020-05-23 05:03:03 +02:00
|
|
|
const fetch = require("node-fetch").default
|
2020-05-16 23:24:51 +02:00
|
|
|
|
|
|
|
const events = exports.events = new EventEmitter()
|
|
|
|
const logger = exports.logger = new Logger("LightCord")
|
|
|
|
|
|
|
|
let hasInit = false
|
|
|
|
let tries = 0
|
|
|
|
|
|
|
|
exports.init = function(){
|
|
|
|
if(hasInit == true){
|
|
|
|
console.warn(new Error("LightCord has already inited."))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
hasInit = true
|
|
|
|
let readyInterval = setInterval(()=>{
|
2020-05-30 15:12:10 +02:00
|
|
|
events.emit("debug", `[INIT] try ${tries++} loading LightCord`)
|
2020-05-16 23:24:51 +02:00
|
|
|
try{
|
|
|
|
if(!global.webpackJsonp)return
|
|
|
|
if(!ModuleLoader.get(4))return
|
|
|
|
clearInterval(readyInterval)
|
|
|
|
privateInit()
|
|
|
|
.then(() => {
|
|
|
|
console.log("Finished loading Lightcord.")
|
|
|
|
})
|
|
|
|
}catch(e){
|
|
|
|
console.error(e)
|
|
|
|
}
|
|
|
|
}, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
let hasPrivateInit = false
|
|
|
|
|
|
|
|
async function privateInit(){
|
|
|
|
if(!hasInit)return
|
|
|
|
if(hasPrivateInit)return
|
|
|
|
hasPrivateInit = true
|
|
|
|
|
|
|
|
//disabling sentry
|
2020-05-30 15:12:10 +02:00
|
|
|
ModuleLoader.get(e => e.getCurrentHub)[0].getCurrentHub().getClient().getOptions().enabled = false
|
2020-05-26 16:14:09 +02:00
|
|
|
|
|
|
|
// setting react in require cache
|
|
|
|
try{
|
|
|
|
window.React = require("react")
|
|
|
|
}catch(e){
|
|
|
|
const React = ModuleLoader.get(e => !["Component", "PureComponent", "Children", "createElement", "cloneElement"].map(c => !!e[c]).includes(false))[0]
|
|
|
|
window.React = React
|
2020-05-31 20:19:20 +02:00
|
|
|
require.cache["react"] = React
|
2020-05-26 16:14:09 +02:00
|
|
|
}
|
|
|
|
try{
|
|
|
|
window.ReactDOM = require("react-dom")
|
|
|
|
}catch(e){
|
|
|
|
const ReactDOM = ModuleLoader.get(e => e.findDOMNode)[0]
|
|
|
|
window.ReactDOM = ReactDOM
|
2020-05-31 20:19:20 +02:00
|
|
|
require.cache["react-dom"] = ReactDOM
|
2020-05-26 16:14:09 +02:00
|
|
|
}
|
2020-05-16 23:24:51 +02:00
|
|
|
|
2020-05-30 15:12:10 +02:00
|
|
|
let original = ModuleLoader.get((e) => e.createSound)[0].createSound
|
|
|
|
ModuleLoader.get((e) => e.createSound)[0].createSound = function(sound){
|
2020-05-16 23:24:51 +02:00
|
|
|
let isCalling = sound === "call_ringing_beat" || sound === "call_ringing"
|
|
|
|
if(isCalling){
|
|
|
|
let returned = original(...arguments)
|
|
|
|
Object.defineProperty(returned, "name", {
|
|
|
|
get(){
|
2020-05-21 00:34:31 +02:00
|
|
|
return window.Lightcord.Settings.callRingingBeat ? "call_ringing_beat" : "call_ringing"
|
2020-05-16 23:24:51 +02:00
|
|
|
},
|
|
|
|
set(data){
|
|
|
|
console.log("Attempting to set call_ringing value. Canceling "+data)
|
2020-05-26 16:14:09 +02:00
|
|
|
},
|
|
|
|
configurable: false
|
2020-05-16 23:24:51 +02:00
|
|
|
})
|
|
|
|
return returned
|
|
|
|
}else{
|
|
|
|
return original(...arguments)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let constants = ModuleLoader.get(m=>m.API_HOST)[0]
|
2020-05-21 00:34:31 +02:00
|
|
|
let dispatcher = ModuleLoader.get(m=>m.Dispatcher&&m.default&&m.default.dispatch)[0].default
|
2020-05-16 23:24:51 +02:00
|
|
|
require("../../../../../BetterDiscordApp/css/main.css")
|
|
|
|
require("./lightcord.css")
|
|
|
|
|
|
|
|
|
|
|
|
window.$ = window.jQuery = require("./jquery.min.js")
|
|
|
|
require("./ace.js")
|
|
|
|
|
|
|
|
if(!fs.existsSync(BetterDiscordConfig.dataPath))fs.mkdirSync(BetterDiscordConfig.dataPath, {recursive: true})
|
|
|
|
let pluginPath = path.join(BetterDiscordConfig.dataPath, "plugins")
|
|
|
|
let themePath = path.join(BetterDiscordConfig.dataPath, "themes")
|
|
|
|
console.log(`Plugins: ${pluginPath}\nThemes: ${themePath}`)
|
2020-05-23 05:03:03 +02:00
|
|
|
if(!fs.existsSync(pluginPath)){
|
|
|
|
fs.mkdirSync(pluginPath, {recursive: true})
|
|
|
|
|
|
|
|
/** Downloads Util Plugins So the user don't have to install it manually */
|
|
|
|
|
|
|
|
/** ZeresPluginLibrary */
|
|
|
|
const ZeresPluginLibraryPath = path.join(pluginPath, "0PluginLibrary.plugin.js")
|
|
|
|
fetch("https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js")
|
|
|
|
.then(async res => {
|
|
|
|
if(res.status !== 200)return
|
|
|
|
const content = await res.buffer()
|
|
|
|
fs.writeFileSync(ZeresPluginLibraryPath, content)
|
|
|
|
})
|
|
|
|
|
|
|
|
// Should we download 1XenoLib and BDFDB too ?
|
|
|
|
|
|
|
|
BetterDiscordConfig.haveInstalledDefault = true // Inform User about what we just did
|
|
|
|
}
|
|
|
|
if(!fs.existsSync(themePath)){
|
|
|
|
fs.mkdirSync(themePath, {recursive: true})
|
|
|
|
|
|
|
|
/** Downloads Basic Themes to guide user and showcase features */
|
|
|
|
|
|
|
|
/** Discord Dark */
|
|
|
|
const DiscordDarkPath = path.join(themePath, "DiscordDark.theme.css")
|
|
|
|
const themeContent = fs.readFileSync(path.join(__dirname, "assets", "DiscordDark.theme.css"), "utf8")
|
|
|
|
fs.writeFileSync(DiscordDarkPath, themeContent, "utf8")
|
|
|
|
|
|
|
|
/** Glasscord Example */
|
|
|
|
const GlasscordExamplePath = path.join(themePath, "glasscord_example.theme.css")
|
|
|
|
fetch("https://raw.githubusercontent.com/AryToNeX/Glasscord/master/extras/discord_example.theme.css")
|
|
|
|
.then(async res => {
|
|
|
|
if(res.status !== 200)return
|
|
|
|
const content = await res.buffer()
|
|
|
|
fs.writeFileSync(GlasscordExamplePath, content)
|
|
|
|
})
|
|
|
|
|
|
|
|
BetterDiscordConfig.haveInstalledDefault = true // Inform User about what we just did
|
|
|
|
}
|
2020-05-16 23:24:51 +02:00
|
|
|
|
|
|
|
// setting Discord Internal Developer Mode for developement and test purposes.
|
|
|
|
Object.defineProperty(ModuleLoader.get(e => e.default && typeof e.default === "object" && ("isDeveloper" in e.default))[0].default, "isDeveloper", {
|
2020-05-21 00:34:31 +02:00
|
|
|
get(){return !!window.Lightcord.Settings.devMode},
|
|
|
|
set(data){return !!window.Lightcord.Settings.devMode}
|
2020-05-16 23:24:51 +02:00
|
|
|
})
|
|
|
|
|
2020-05-21 01:40:58 +02:00
|
|
|
/**
|
|
|
|
* @type {typeof import("../../../../../DiscordJS").default}
|
|
|
|
*/
|
|
|
|
let DiscordJS
|
|
|
|
try{
|
|
|
|
DiscordJS = require("../../../../../DiscordJS").default
|
|
|
|
}catch(err){
|
|
|
|
console.error(err)
|
|
|
|
DiscordJS = null
|
|
|
|
}
|
|
|
|
|
2020-05-27 20:19:27 +02:00
|
|
|
const appSettings = electron.remote.getGlobal("appSettings")
|
|
|
|
let Authorization = appSettings.get("LIGHTCORD_AUTH", null)
|
|
|
|
|
2020-05-21 00:34:31 +02:00
|
|
|
window.Lightcord = {
|
|
|
|
DiscordModules: {
|
|
|
|
dispatcher,
|
|
|
|
constants
|
|
|
|
},
|
|
|
|
Settings: {
|
|
|
|
devMode: false,
|
|
|
|
callRingingBeat: true
|
2020-05-27 20:19:27 +02:00
|
|
|
},
|
|
|
|
Api: {
|
|
|
|
get Authorization(){
|
|
|
|
return Authorization
|
|
|
|
},
|
|
|
|
set Authorization(data){
|
|
|
|
if(typeof data !== "string" && data !== null)return Authorization
|
|
|
|
appSettings.set("LIGHTCORD_AUTH", Authorization = data)
|
|
|
|
appSettings.save()
|
|
|
|
}
|
2020-05-30 14:52:50 +02:00
|
|
|
},
|
|
|
|
BetterDiscord: { // Global BetterDiscord's exported modules
|
|
|
|
|
2020-05-21 00:34:31 +02:00
|
|
|
}
|
|
|
|
}
|
2020-05-30 14:52:50 +02:00
|
|
|
const BetterDiscord = window.BetterDiscord = window.mainCore = new(require("../../../../../BetterDiscordApp/js/main").default)(BetterDiscordConfig)
|
2020-05-21 01:09:03 +02:00
|
|
|
|
2020-05-30 14:52:50 +02:00
|
|
|
const Utils = window.Lightcord.BetterDiscord.Utils
|
2020-05-21 01:15:46 +02:00
|
|
|
|
2020-05-30 15:12:10 +02:00
|
|
|
delete window.Lightcord.BetterDiscord.Utils // security delete
|
|
|
|
|
2020-05-30 14:52:50 +02:00
|
|
|
await ensureExported(e => e.default && e.default.displayName == "AuthBox")
|
|
|
|
|
2020-05-30 15:12:10 +02:00
|
|
|
const classs = ModuleLoader.get(e => e.default && e.default.displayName == "AuthBox")
|
2020-05-30 14:52:50 +02:00
|
|
|
|
|
|
|
Utils.monkeyPatch(classs[0], "default", {after: (data) => {
|
|
|
|
const children = Utils.getNestedProp(data.returnValue, "props.children.props.children.props.children")
|
|
|
|
children.push(React.createElement(require("./tokenLogin").default, {}))
|
|
|
|
}})
|
|
|
|
|
|
|
|
await ensureGuildClasses()
|
2020-05-21 01:09:03 +02:00
|
|
|
BetterDiscord.init()
|
|
|
|
|
|
|
|
events.emit("ready")
|
2020-05-21 01:40:58 +02:00
|
|
|
|
|
|
|
if(DiscordJS)DiscordJS.client.emit("ready")
|
2020-05-16 23:24:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
require.extensions[".css"] = (m, filename) => {
|
|
|
|
let content = fs.readFileSync(filename, "binary")
|
|
|
|
let style = document.createElement("style")
|
|
|
|
style.id = btoa(filename)
|
|
|
|
style.innerText = content
|
|
|
|
document.head.appendChild(style)
|
|
|
|
m.exports = {
|
|
|
|
id: style.id,
|
|
|
|
remove(){
|
|
|
|
return style.remove()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m.exports
|
|
|
|
}
|
|
|
|
|
2020-05-23 01:28:54 +02:00
|
|
|
const LightcordBDFolder = path.join(electron.remote.app.getPath("appData"), "Lightcord_BD")
|
|
|
|
|
2020-05-16 23:24:51 +02:00
|
|
|
const BetterDiscordConfig = window.BetterDiscordConfig = {
|
2020-05-20 21:37:39 +02:00
|
|
|
"branch": "lightcord",
|
2020-05-23 05:03:03 +02:00
|
|
|
dataPath: LightcordBDFolder+"/",
|
2020-05-20 21:37:39 +02:00
|
|
|
os: process.platform,
|
2020-05-21 00:34:31 +02:00
|
|
|
latestVersion: "0.3.4",
|
|
|
|
version: "0.3.4"
|
2020-05-16 23:24:51 +02:00
|
|
|
}
|
2020-05-18 20:34:26 +02:00
|
|
|
|
|
|
|
function ensureGuildClasses(){
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
let classs = getGuildClasses()
|
|
|
|
if(classs && classs.wrapper)return resolve()
|
|
|
|
|
|
|
|
let intergay = setInterval(() => {
|
|
|
|
classs = getGuildClasses()
|
|
|
|
if(classs && classs.wrapper){
|
|
|
|
clearInterval(intergay)
|
|
|
|
resolve()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}, 200);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-05-30 14:52:50 +02:00
|
|
|
function ensureExported(filter){
|
|
|
|
return new Promise((resolve) => {
|
2020-05-30 15:12:10 +02:00
|
|
|
let classs = ModuleLoader.get(filter)[0]
|
2020-05-30 14:52:50 +02:00
|
|
|
if(classs)return resolve()
|
|
|
|
|
|
|
|
let intergay = setInterval(() => {
|
2020-05-30 15:12:10 +02:00
|
|
|
classs = ModuleLoader.get(filter)[0]
|
2020-05-30 14:52:50 +02:00
|
|
|
if(classs){
|
|
|
|
clearInterval(intergay)
|
|
|
|
resolve()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}, 100);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-05-18 20:34:26 +02:00
|
|
|
function getGuildClasses() {
|
2020-05-30 15:12:10 +02:00
|
|
|
const guildsWrapper = ModuleLoader.get(e => e.wrapper && e.unreadMentionsBar)[0];
|
|
|
|
const guilds = ModuleLoader.get(e => e.guildsError && e.selected)[0]
|
|
|
|
const pill = ModuleLoader.get(e => e.blobContainer)[0]
|
2020-05-18 20:34:26 +02:00
|
|
|
return Object.assign({}, guildsWrapper, guilds, pill);
|
2020-05-20 21:37:39 +02:00
|
|
|
}
|
|
|
|
|
2020-05-23 01:28:54 +02:00
|
|
|
const originalResolve = path.resolve
|
|
|
|
const originalJoin = path.join
|
|
|
|
|
|
|
|
const BetterDiscordFolder = function() {
|
|
|
|
if (process.env.injDir) return path.resolve(process.env.injDir);
|
|
|
|
switch (process.platform) {
|
|
|
|
case "win32":
|
|
|
|
return path.resolve(process.env.appdata, "BetterDiscord/");
|
|
|
|
case "darwin":
|
|
|
|
return path.resolve(process.env.HOME, "Library/Preferences/", "BetterDiscord/");
|
|
|
|
default:
|
|
|
|
return path.resolve(process.env.XDG_CONFIG_HOME ? process.env.XDG_CONFIG_HOME : process.env.HOME + "/.config", "BetterDiscord/");
|
|
|
|
}
|
|
|
|
}()
|
2020-05-20 21:37:39 +02:00
|
|
|
|
2020-05-23 01:28:54 +02:00
|
|
|
path.resolve = (...args) => { // Patching BetterDiscord folder by Lightcord's BetterDiscord folder
|
|
|
|
let resp = originalResolve.call(path, ...args)
|
|
|
|
if(resp.startsWith(BetterDiscordFolder))resp = resp.replace(BetterDiscordFolder, LightcordBDFolder)
|
|
|
|
return resp
|
|
|
|
}
|
|
|
|
path.join = (...args) => { // Patching BetterDiscord folder by Lightcord's BetterDiscord folder
|
|
|
|
let resp = originalJoin.call(path, ...args)
|
|
|
|
if(resp.startsWith(BetterDiscordFolder))resp = resp.replace(BetterDiscordFolder, LightcordBDFolder)
|
|
|
|
return resp
|
2020-05-20 21:37:39 +02:00
|
|
|
}
|
|
|
|
|
2020-05-21 00:34:31 +02:00
|
|
|
path.originalResolve = originalResolve
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
window.ohgodohfuck = function(){
|
|
|
|
let style=document.createElement("style");style.innerHTML=`html:after{content:"";position:absolute;top:0;left:0 ;width:100vw;height:100vh;background-image:url("https://media.giphy.com/media/l378vg4Pm9LGnmD6M/giphy.gif");background-size:cover;background-position:center;background-color:transparent !important;opacity:0.9;mix-blend-mode:hue;z-index:999999999999;pointer-events:none}@keyframes ohgodohfuck{from{transform:rotateZ(0deg)}to{transform:rotateZ(360deg)}}#app-mount{animation:ohgodohfuck 5s infinite alternate}`;document.body.append(style);setTimeout(()=>document.body.removeChild(style),5000);
|
|
|
|
}
|