diff --git a/afterbuild.js b/afterbuild.js new file mode 100644 index 0000000..539d04a --- /dev/null +++ b/afterbuild.js @@ -0,0 +1,47 @@ +const fs = require("fs") +const fsAsync = fs.promises +const yazl = require("yazl") +const __path = require("path") + +fs.unlinkSync(__path.join(__dirname, "builds", "lightcord-win32-ia32.zip")) +fs.unlinkSync(__path.join(__dirname, "builds", "lightcord-linux-x64.zip")) + +const winZip = new yazl.ZipFile() +winZip.outputStream.pipe(fs.createWriteStream(__path.join(__dirname, "builds", "lightcord-win32-ia32.zip"))) + +const linuxZip = new yazl.ZipFile() +linuxZip.outputStream.pipe(fs.createWriteStream(__path.join(__dirname, "builds", "lightcord-linux-x64.zip"))) + +async function processNextDir(dir, zip, bpath, platform){ + if(!bpath)bpath = dir + if(dir.replace(bpath, ""))zip.addEmptyDirectory(dir.replace(bpath, "").slice(1)) + await Promise.all(fs.readdirSync(dir, {withFileTypes: true}) + .map(async file => { + let path = __path.join(dir, file.name) + if(file.isDirectory()){ + return await processNextDir(path, zip, bpath) + }else if(file.isFile()){ + console.log(file.name) + if((file.name.endsWith("_linux.node") && platform === "win") || (file.name.endsWith(".node") && !file.name.endsWith("_linux.node") && platform === "lin")){ + return + } + let stat = fs.statSync(path) + zip.addBuffer(await fsAsync.readFile(path), __path.relative(bpath, path), { + mode: stat.mode, + mtime: stat.mtime + }) + } + })) +} + +processNextDir(__path.join(__dirname, "builds", "lightcord-win32-ia32"), winZip, undefined, "win") +.then(() => { + console.log(`Zipped win32.`) + winZip.end() +}) + +processNextDir(__path.join(__dirname, "builds", "lightcord-linux-x64"), linuxZip, undefined, "lin") +.then(() => { + console.log(`Zipped linux.`) + linuxZip.end() +}) \ No newline at end of file diff --git a/build.js b/build.js index 834a501..ecd7d68 100644 --- a/build.js +++ b/build.js @@ -1,145 +1,145 @@ -const child_process = require("child_process") -const path = require("path") -const terser = require("terser") -const util = require("util") - -/** Super noisy if production is on. */ -const production = true - -let fs = require("fs") - -console.log = (...args) => { - process.stdout.write(Buffer.from(util.formatWithOptions({colors: true}, ...args)+"\n", "binary").toString("utf8")) -} -console.info = (...args) => { - console.log(`\x1b[34m[INFO]\x1b[0m`, ...args) -} - -async function main(){ - console.log(__dirname, process.cwd()) - - console.info("Reseting existent directory...") - await fs.promises.rmdir("./distApp", {"recursive": true}) - await fs.promises.mkdir(__dirname+"/distApp/dist", {"recursive": true}) - - console.info("Executing command `npm run compile`") - //console.log(child_process.execSync("npm run compile", {encoding: "binary"})) - - let startDir = path.join(__dirname, "./dist") - let newDir = path.join(__dirname, "./distApp/dist") - console.info("No error detected. Copying files from "+startDir+".") - await fs.promises.mkdir(startDir, {recursive: true}) - - async function processNextDir(folder, folders, predicate, compile){ - for(let file of fs.readdirSync(folder, {withFileTypes: true})){ - if(file.isFile()){ - let filepath = path.join(folder, file.name) - if(predicate(filepath) && filepath.split(/[\\/]+/).reverse()[1] !== "js"){ - await compile(filepath, path.join(filepath.replace(folders.startDir, folders.newDir)), "..") - }else{ - await fs.promises.copyFile(filepath, filepath.replace(folders.startDir, folders.newDir)) - } - }else if(file.isDirectory()){ - await fs.promises.mkdir(path.join(folder, file.name).replace(folders.startDir, folders.newDir), {recursive: true}) - await processNextDir(path.join(folder, file.name), ...Array.from(arguments).slice(1)) - } - } - } - await processNextDir(startDir, { - startDir, - newDir - }, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => { - console.info(`Minifying ${filepath} to ${newpath}`) - - if(filepath.endsWith("git.js")){ - let commit = child_process.execSync("git rev-parse HEAD").toString().split("\n")[0].trim() - console.info(`Obtained commit ${commit} for the build`) - await fs.promises.writeFile(newpath, terser.minify(fs.readFileSync(filepath, "utf8").replace(/"{commit}"/g, `"${commit}"`)).code, "utf8") - }else{ - await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") - } - }).then(() => { - console.info(`Copied files and minified them from ${startDir}.`) - }).catch(console.error) - - await processNextDir(path.join(__dirname, "modules"), { - startDir: path.join(__dirname, "modules"), - newDir: path.join(__dirname, "distApp", "modules") - }, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => { - console.info(`Minifying ${filepath} to ${newpath}`) - await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") - }).then(() => { - console.info(`Copied files and minified them from ${path.join(__dirname, "modules")}.`) - }) - - await processNextDir(path.join(__dirname, "LightcordApi"), { - startDir: path.join(__dirname, "LightcordApi"), - newDir: path.join(__dirname, "distApp", "LightcordApi") - }, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => { - console.info(`Minifying ${filepath} to ${newpath}`) - await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") - }).then(() => { - console.info(`Copied files and minified them from ${path.join(__dirname, "LightcordApi")}.`) - }) - - await fs.promises.rmdir(path.join(__dirname, "distApp", "LightcordApi", "src"), {"recursive": true}) - await fs.promises.unlink(path.join(__dirname, "distApp", "LightcordApi", "webpack.config.js")) - await fs.promises.unlink(path.join(__dirname, "distApp", "LightcordApi", "tsconfig.json")) - - await processNextDir(path.join(__dirname, "DiscordJS"), { - startDir: path.join(__dirname, "DiscordJS"), - newDir: path.join(__dirname, "distApp", "DiscordJS") - }, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => { - console.info(`Minifying ${filepath} to ${newpath}`) - await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") - }).then(() => { - console.info(`Copied files and minified them from ${path.join(__dirname, "DiscordJS")}.`) - }) - - await fs.promises.rmdir(path.join(__dirname, "distApp", "DiscordJS", "src"), {"recursive": true}) - await fs.promises.unlink(path.join(__dirname, "distApp", "DiscordJS", "webpack.config.js")) - await fs.promises.unlink(path.join(__dirname, "distApp", "DiscordJS", "tsconfig.json")) - - fs.mkdirSync(path.join(__dirname, "distApp", "BetterDiscordApp", "js"), {recursive: true}) - fs.mkdirSync(path.join(__dirname, "distApp", "BetterDiscordApp", "css"), {recursive: true}) - const BDPackageJSON = require("./BetterDiscordApp/package.json") - fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "package.json"), JSON.stringify(BDPackageJSON), "utf8") - fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "css", "main.css"), fs.readFileSync(path.join(__dirname, "BetterDiscordApp", "css", "main.css"))) - fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "css", "main.min.css"), fs.readFileSync(path.join(__dirname, "BetterDiscordApp", "css", "main.min.css"))) - fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "js", "main.js"), fs.readFileSync(path.join(__dirname, "BetterDiscordApp", "js", "main.js"))) - fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "js", "main.min.js"), fs.readFileSync(path.join(__dirname, "BetterDiscordApp", "js", "main.min.js"))) - - await fs.promises.mkdir(path.join(__dirname, "distApp", "splash", "videos"), {recursive: true}) - await processNextDir(path.join(__dirname, "splash"), { - startDir: path.join(__dirname, "splash"), - newDir: path.join(__dirname, "distApp", "splash") - }, (filepath) => { - if(filepath.endsWith(".js"))return true - return false - }, async (filepath, newpath) => { - console.info(`Minifying ${filepath} to ${newpath}`) - await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") - }).then(() => { - console.info(`Copied files and minified them from ${path.join(__dirname, "splash")}.`) - }) - - /* - await processNextDir(startDir, { - startDir, - newDir - }, ((filepath) => false), ()=>{}).then(() => { - console.info(`Copied files and minified them from ${startDir}.`) - }).catch(console.error)*/ - - let packageJSON = require("./package.json") - packageJSON.scripts.build = packageJSON.scripts.build.replace("./distApp", ".") - - fs.writeFileSync(path.join(__dirname, "distApp", "package.json"), JSON.stringify(packageJSON), "utf8") - - console.info(`Installing ${Object.keys(packageJSON.dependencies).length + Object.keys(packageJSON.devDependencies).length} packages...`) - console.log(child_process.execSync("npm i", { - encoding: "binary", - cwd: path.join(__dirname, "distApp") - })) -} +const child_process = require("child_process") +const path = require("path") +const terser = require("terser") +const util = require("util") + +/** Super noisy if production is on. */ +const production = true + +let fs = require("fs") + +console.log = (...args) => { + process.stdout.write(Buffer.from(util.formatWithOptions({colors: true}, ...args)+"\n", "binary").toString("utf8")) +} +console.info = (...args) => { + console.log(`\x1b[34m[INFO]\x1b[0m`, ...args) +} + +async function main(){ + console.log(__dirname, process.cwd()) + + console.info("Reseting existent directory...") + await fs.promises.rmdir("./distApp", {"recursive": true}) + await fs.promises.mkdir(__dirname+"/distApp/dist", {"recursive": true}) + + console.info("Executing command `npm run compile`") + //console.log(child_process.execSync("npm run compile", {encoding: "binary"})) + + let startDir = path.join(__dirname, "./dist") + let newDir = path.join(__dirname, "./distApp/dist") + console.info("No error detected. Copying files from "+startDir+".") + await fs.promises.mkdir(startDir, {recursive: true}) + + async function processNextDir(folder, folders, predicate, compile){ + for(let file of fs.readdirSync(folder, {withFileTypes: true})){ + if(file.isFile()){ + let filepath = path.join(folder, file.name) + if(predicate(filepath) && filepath.split(/[\\/]+/).reverse()[1] !== "js"){ + await compile(filepath, path.join(filepath.replace(folders.startDir, folders.newDir)), "..") + }else{ + await fs.promises.copyFile(filepath, filepath.replace(folders.startDir, folders.newDir)) + } + }else if(file.isDirectory()){ + await fs.promises.mkdir(path.join(folder, file.name).replace(folders.startDir, folders.newDir), {recursive: true}) + await processNextDir(path.join(folder, file.name), ...Array.from(arguments).slice(1)) + } + } + } + await processNextDir(startDir, { + startDir, + newDir + }, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => { + console.info(`Minifying ${filepath} to ${newpath}`) + + if(filepath.endsWith("git.js")){ + let commit = child_process.execSync("git rev-parse HEAD").toString().split("\n")[0].trim() + console.info(`Obtained commit ${commit} for the build`) + await fs.promises.writeFile(newpath, terser.minify(fs.readFileSync(filepath, "utf8").replace(/"{commit}"/g, `"${commit}"`)).code, "utf8") + }else{ + await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") + } + }).then(() => { + console.info(`Copied files and minified them from ${startDir}.`) + }).catch(console.error) + + await processNextDir(path.join(__dirname, "modules"), { + startDir: path.join(__dirname, "modules"), + newDir: path.join(__dirname, "distApp", "modules") + }, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => { + console.info(`Minifying ${filepath} to ${newpath}`) + await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") + }).then(() => { + console.info(`Copied files and minified them from ${path.join(__dirname, "modules")}.`) + }) + + await processNextDir(path.join(__dirname, "LightcordApi"), { + startDir: path.join(__dirname, "LightcordApi"), + newDir: path.join(__dirname, "distApp", "LightcordApi") + }, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => { + console.info(`Minifying ${filepath} to ${newpath}`) + await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") + }).then(() => { + console.info(`Copied files and minified them from ${path.join(__dirname, "LightcordApi")}.`) + }) + + await fs.promises.rmdir(path.join(__dirname, "distApp", "LightcordApi", "src"), {"recursive": true}) + await fs.promises.unlink(path.join(__dirname, "distApp", "LightcordApi", "webpack.config.js")) + await fs.promises.unlink(path.join(__dirname, "distApp", "LightcordApi", "tsconfig.json")) + + await processNextDir(path.join(__dirname, "DiscordJS"), { + startDir: path.join(__dirname, "DiscordJS"), + newDir: path.join(__dirname, "distApp", "DiscordJS") + }, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => { + console.info(`Minifying ${filepath} to ${newpath}`) + await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") + }).then(() => { + console.info(`Copied files and minified them from ${path.join(__dirname, "DiscordJS")}.`) + }) + + await fs.promises.rmdir(path.join(__dirname, "distApp", "DiscordJS", "src"), {"recursive": true}) + await fs.promises.unlink(path.join(__dirname, "distApp", "DiscordJS", "webpack.config.js")) + await fs.promises.unlink(path.join(__dirname, "distApp", "DiscordJS", "tsconfig.json")) + + fs.mkdirSync(path.join(__dirname, "distApp", "BetterDiscordApp", "js"), {recursive: true}) + fs.mkdirSync(path.join(__dirname, "distApp", "BetterDiscordApp", "css"), {recursive: true}) + const BDPackageJSON = require("./BetterDiscordApp/package.json") + fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "package.json"), JSON.stringify(BDPackageJSON), "utf8") + fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "css", "main.css"), fs.readFileSync(path.join(__dirname, "BetterDiscordApp", "css", "main.css"))) + fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "css", "main.min.css"), fs.readFileSync(path.join(__dirname, "BetterDiscordApp", "css", "main.min.css"))) + fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "js", "main.js"), fs.readFileSync(path.join(__dirname, "BetterDiscordApp", "js", "main.js"))) + fs.writeFileSync(path.join(__dirname, "distApp", "BetterDiscordApp", "js", "main.min.js"), fs.readFileSync(path.join(__dirname, "BetterDiscordApp", "js", "main.min.js"))) + + await fs.promises.mkdir(path.join(__dirname, "distApp", "splash", "videos"), {recursive: true}) + await processNextDir(path.join(__dirname, "splash"), { + startDir: path.join(__dirname, "splash"), + newDir: path.join(__dirname, "distApp", "splash") + }, (filepath) => { + if(filepath.endsWith(".js"))return true + return false + }, async (filepath, newpath) => { + console.info(`Minifying ${filepath} to ${newpath}`) + await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8") + }).then(() => { + console.info(`Copied files and minified them from ${path.join(__dirname, "splash")}.`) + }) + + /* + await processNextDir(startDir, { + startDir, + newDir + }, ((filepath) => false), ()=>{}).then(() => { + console.info(`Copied files and minified them from ${startDir}.`) + }).catch(console.error)*/ + + let packageJSON = require("./package.json") + packageJSON.scripts.build = packageJSON.scripts.build.replace("./distApp", ".") + + fs.writeFileSync(path.join(__dirname, "distApp", "package.json"), JSON.stringify(packageJSON), "utf8") + + console.info(`Installing ${Object.keys(packageJSON.dependencies).length + Object.keys(packageJSON.devDependencies).length} packages...`) + console.log(child_process.execSync("npm i", { + encoding: "binary", + cwd: path.join(__dirname, "distApp") + })) +} main() \ No newline at end of file diff --git a/modules/discord_cloudsync/discord_cloudsync_linux.node b/modules/discord_cloudsync/discord_cloudsync_linux.node new file mode 100644 index 0000000..f56aa82 Binary files /dev/null and b/modules/discord_cloudsync/discord_cloudsync_linux.node differ diff --git a/modules/discord_cloudsync/index.js b/modules/discord_cloudsync/index.js index af7f1c1..8db5585 100644 --- a/modules/discord_cloudsync/index.js +++ b/modules/discord_cloudsync/index.js @@ -1,28 +1,32 @@ -const EventEmitter = require('events'); -const {CloudSync: CloudSyncNative} = require('./discord_cloudsync.node'); - -function makeCallback(resolve, reject) { - return (err, result) => { - if (err != null && err !== '') { - reject(new Error(JSON.parse(err))); - } else { - resolve(result != null && result !== '' ? JSON.parse(result) : null); - } - }; -} - -class CloudSync extends EventEmitter { - constructor() { - super(); - - this._cloudSync = new CloudSyncNative(state => this.emit('state', JSON.parse(state))); - } - - sync(id, config) { - return new Promise((resolve, reject) => - this._cloudSync.command(JSON.stringify({type: 'SYNC', id, config}), makeCallback(resolve, reject)) - ); - } -} - -module.exports = CloudSync; +const EventEmitter = require('events'); +let addon = './discord_cloudsync.node' +if(process.platform === "linux"){ + addon = './discord_cloudsync_linux.node' +} +const {CloudSync: CloudSyncNative} = require(addon); + +function makeCallback(resolve, reject) { + return (err, result) => { + if (err != null && err !== '') { + reject(new Error(JSON.parse(err))); + } else { + resolve(result != null && result !== '' ? JSON.parse(result) : null); + } + }; +} + +class CloudSync extends EventEmitter { + constructor() { + super(); + + this._cloudSync = new CloudSyncNative(state => this.emit('state', JSON.parse(state))); + } + + sync(id, config) { + return new Promise((resolve, reject) => + this._cloudSync.command(JSON.stringify({type: 'SYNC', id, config}), makeCallback(resolve, reject)) + ); + } +} + +module.exports = CloudSync; diff --git a/modules/discord_desktop_core/core/app/BetterDiscord/patchNotifications.js b/modules/discord_desktop_core/core/app/BetterDiscord/patchNotifications.js index aad89db..8b36b2c 100644 --- a/modules/discord_desktop_core/core/app/BetterDiscord/patchNotifications.js +++ b/modules/discord_desktop_core/core/app/BetterDiscord/patchNotifications.js @@ -87,6 +87,10 @@ if(process.platform === "win32"){ useShim = !!use } } +}else{ + module.exports = { + useShim(){} + } } let settingStore diff --git a/modules/discord_dispatch/discord_dispatch_linux.node b/modules/discord_dispatch/discord_dispatch_linux.node new file mode 100644 index 0000000..b4cc2f8 Binary files /dev/null and b/modules/discord_dispatch/discord_dispatch_linux.node differ diff --git a/modules/discord_dispatch/index.js b/modules/discord_dispatch/index.js index b921d77..312ef26 100644 --- a/modules/discord_dispatch/index.js +++ b/modules/discord_dispatch/index.js @@ -1 +1 @@ -module.exports = require('./discord_dispatch.node'); +module.exports = require(process.platform === "linux" ? './discord_dispatch_linux.node' : './discord_dispatch.node'); diff --git a/modules/discord_erlpack/discord_erlpack_linux.node b/modules/discord_erlpack/discord_erlpack_linux.node new file mode 100644 index 0000000..c7a5a96 Binary files /dev/null and b/modules/discord_erlpack/discord_erlpack_linux.node differ diff --git a/modules/discord_erlpack/index.js b/modules/discord_erlpack/index.js index 4cf33fb..c99a2bc 100644 --- a/modules/discord_erlpack/index.js +++ b/modules/discord_erlpack/index.js @@ -1 +1 @@ -module.exports = require('./discord_erlpack.node'); +module.exports = require(process.platform === "linux" ? './discord_erlpack_linux.node' : './discord_erlpack.node'); diff --git a/modules/discord_game_utils/discord_game_utils_linux.node b/modules/discord_game_utils/discord_game_utils_linux.node new file mode 100644 index 0000000..c481928 Binary files /dev/null and b/modules/discord_game_utils/discord_game_utils_linux.node differ diff --git a/modules/discord_game_utils/index.js b/modules/discord_game_utils/index.js index 342bf58..f032cb7 100644 --- a/modules/discord_game_utils/index.js +++ b/modules/discord_game_utils/index.js @@ -1 +1 @@ -module.exports = require('./discord_game_utils.node'); +module.exports = require(process.platform === "linux" ? './discord_game_utils_linux.node' : './discord_game_utils.node'); diff --git a/modules/discord_modules/discord_modules_linux.node b/modules/discord_modules/discord_modules_linux.node new file mode 100644 index 0000000..813f93e Binary files /dev/null and b/modules/discord_modules/discord_modules_linux.node differ diff --git a/modules/discord_modules/index.js b/modules/discord_modules/index.js index b1cfaa3..87d084d 100644 --- a/modules/discord_modules/index.js +++ b/modules/discord_modules/index.js @@ -1 +1 @@ -module.exports = require('./discord_modules.node'); +module.exports = require(process.platform === "linux" ? './discord_modules_linux.node' : './discord_modules.node'); diff --git a/modules/discord_utils/discord_utils_linux.node b/modules/discord_utils/discord_utils_linux.node new file mode 100644 index 0000000..e2e892e Binary files /dev/null and b/modules/discord_utils/discord_utils_linux.node differ diff --git a/modules/discord_utils/index.js b/modules/discord_utils/index.js index dc7fdb7..2ac18e8 100644 --- a/modules/discord_utils/index.js +++ b/modules/discord_utils/index.js @@ -1,50 +1,55 @@ -const execa = require('execa'); -const superagent = require('superagent'); - -module.exports = require('./discord_utils.node'); -module.exports.clearCandidateGamesCallback = module.exports.setCandidateGamesCallback; - -function parseNvidiaSmiOutput(result) { - if (!result || !result.stdout) { - return {error: 'nvidia-smi produced no output'}; - } - - const match = result.stdout.match(/Driver Version: (\d+)\.(\d+)/); - - if (match.length === 3) { - return {major: parseInt(match[1], 10), minor: parseInt(match[2], 10)}; - } else { - return {error: 'failed to parse nvidia-smi output'}; - } -} - -module.exports.getGPUDriverVersions = async () => { - if (process.platform !== 'win32') { - return {}; - } - - const result = {}; - const nvidiaSmiPath = `${process.env['ProgramW6432']}/NVIDIA Corporation/NVSMI/nvidia-smi.exe`; - - try { - result.nvidia = parseNvidiaSmiOutput(await execa(nvidiaSmiPath, [])); - } catch (e) { - result.nvidia = {error: e.toString()}; - } - - return result; -}; - -module.exports.submitLiveCrashReport = async (channel, sentryMetadata) => { - const path = module.exports._generateLiveMinidump(); - - if (!path) { - return null; - } - - await superagent - .post('https://sentry.io/api/146342/minidump/?sentry_key=f11e8c3e62cb46b5a006c339b2086ba3') - .attach('upload_file_minidump', path) - .field('channel', channel) - .field('sentry', JSON.stringify(sentryMetadata)); -}; +const execa = require('execa'); +const superagent = require('superagent'); + +let addon = './discord_utils.node' +if(process.platform === "linux"){ + addon = './discord_utils_linux.node' +} + +module.exports = require(addon); +module.exports.clearCandidateGamesCallback = module.exports.setCandidateGamesCallback; + +function parseNvidiaSmiOutput(result) { + if (!result || !result.stdout) { + return {error: 'nvidia-smi produced no output'}; + } + + const match = result.stdout.match(/Driver Version: (\d+)\.(\d+)/); + + if (match.length === 3) { + return {major: parseInt(match[1], 10), minor: parseInt(match[2], 10)}; + } else { + return {error: 'failed to parse nvidia-smi output'}; + } +} + +module.exports.getGPUDriverVersions = async () => { + if (process.platform !== 'win32') { + return {}; + } + + const result = {}; + const nvidiaSmiPath = `${process.env['ProgramW6432']}/NVIDIA Corporation/NVSMI/nvidia-smi.exe`; + + try { + result.nvidia = parseNvidiaSmiOutput(await execa(nvidiaSmiPath, [])); + } catch (e) { + result.nvidia = {error: e.toString()}; + } + + return result; +}; + +module.exports.submitLiveCrashReport = async (channel, sentryMetadata) => { + const path = module.exports._generateLiveMinidump(); + + if (!path) { + return null; + } + + await superagent + .post('https://sentry.io/api/146342/minidump/?sentry_key=f11e8c3e62cb46b5a006c339b2086ba3') + .attach('upload_file_minidump', path) + .field('channel', channel) + .field('sentry', JSON.stringify(sentryMetadata)); +}; diff --git a/modules/discord_voice/discord_voice_linux.node b/modules/discord_voice/discord_voice_linux.node new file mode 100644 index 0000000..4a0d524 Binary files /dev/null and b/modules/discord_voice/discord_voice_linux.node differ diff --git a/modules/discord_voice/index.js b/modules/discord_voice/index.js index 025c239..2ce9395 100644 --- a/modules/discord_voice/index.js +++ b/modules/discord_voice/index.js @@ -1,155 +1,155 @@ -const VoiceEngine = require('./discord_voice.node'); -const ChildProcess = require('child_process'); -const path = require('path'); -const yargs = require('yargs'); - -const isElectronRenderer = - typeof window !== 'undefined' && window != null && window.DiscordNative && window.DiscordNative.isRenderer; - -const appSettings = isElectronRenderer ? window.DiscordNative.settings : global.appSettings; -const features = isElectronRenderer ? window.DiscordNative.features : global.features; -const mainArgv = isElectronRenderer ? window.DiscordNative.processUtils.getMainArgvSync() : []; -const releaseChannel = isElectronRenderer ? window.DiscordNative.app.getReleaseChannel() : ''; -const useLegacyAudioDevice = appSettings ? appSettings.getSync('useLegacyAudioDevice') : false; -const audioSubsystemSelected = appSettings - ? appSettings.getSync('audioSubsystem') === 'legacy' - ? 'legacy' - : 'standard' - : 'standard'; -const audioSubsystem = useLegacyAudioDevice || audioSubsystemSelected; -const debugLogging = appSettings ? appSettings.getSync('debugLogging') : false; - -const argv = yargs(mainArgv.slice(1)) - .describe('log-level', 'Logging level.') - .default('log-level', -1) - .help('h') - .alias('h', 'help') - .exitProcess(false).argv; -const logLevel = argv['log-level'] == -1 ? (debugLogging ? 2 : -1) : argv['log-level']; - -if (debugLogging && console.discordVoiceHooked == null) { - console.discordVoiceHooked = true; - - for (const logFn of ['trace', 'debug', 'info', 'warn', 'error', 'log']) { - const originalLogFn = console[logFn]; - - if (originalLogFn != null) { - console[logFn] = function () { - originalLogFn.apply(this, arguments); - - try { - VoiceEngine.consoleLog( - logFn, - JSON.stringify(Array.from(arguments).map((v) => (v != null ? v.toString() : v))) - ); - } catch (e) { - // Drop errors from toString()/stringify. - } - }; - } - } -} - -features.declareSupported('voice_panning'); -features.declareSupported('voice_multiple_connections'); -features.declareSupported('media_devices'); -features.declareSupported('media_video'); -features.declareSupported('debug_logging'); -features.declareSupported('set_audio_device_by_id'); -features.declareSupported('set_video_device_by_id'); -features.declareSupported('loopback'); -features.declareSupported('experiment_config'); -features.declareSupported('remote_locus_network_control'); -features.declareSupported('connection_replay'); -features.declareSupported('simulcast'); - -if (process.platform === 'win32') { - features.declareSupported('voice_legacy_subsystem'); - features.declareSupported('soundshare'); - features.declareSupported('wumpus_video'); - features.declareSupported('hybrid_video'); - features.declareSupported('elevated_hook'); - features.declareSupported('soundshare_loopback'); - features.declareSupported('screen_previews'); - features.declareSupported('window_previews'); - features.declareSupported('audio_debug_state'); - // NOTE(jvass): currently there's no experimental encoders! Add this back if you - // add one and want to re-enable the UI for them. - // features.declareSupported('experimental_encoders'); -} - -const VoiceReplayConnection = VoiceEngine.VoiceReplayConnection; - -delete VoiceEngine.VoiceReplayConnection; - -VoiceEngine.createTransport = VoiceEngine._createTransport; - -if (isElectronRenderer) { - VoiceEngine.setImageDataAllocator((width, height) => new window.ImageData(width, height)); -} - -VoiceEngine.createReplayConnection = function (audioEngineId, callback, replayLog) { - if (replayLog == null) { - return null; - } - - return new VoiceReplayConnection(replayLog, audioEngineId, callback); -}; - -VoiceEngine.setAudioSubsystem = function (subsystem) { - if (appSettings == null) { - console.warn('Unable to access app settings.'); - return; - } - - // TODO: With experiment controlling ADM selection, this may be incorrect since - // audioSubsystem is read from settings (or default if does not exists) - // and not the actual ADM used. - if (subsystem === audioSubsystem) { - return; - } - - appSettings.set('audioSubsystem', subsystem); - appSettings.set('useLegacyAudioDevice', false); - - if (isElectronRenderer) { - window.DiscordNative.app.relaunch(); - } -}; - -VoiceEngine.setDebugLogging = function (enable) { - if (appSettings == null) { - console.warn('Unable to access app settings.'); - return; - } - - if (debugLogging === enable) { - return; - } - - appSettings.set('debugLogging', enable); - - if (isElectronRenderer) { - window.DiscordNative.app.relaunch(); - } -}; - -VoiceEngine.getDebugLogging = function () { - return debugLogging; -}; - -reloadElectronApp = function () { - if (isElectronRenderer) { - const app = require('electron').remote.app; - app.relaunch(); - app.exit(0); - } else { - ChildProcess.spawn(process.argv[0], process.argv.splice(1), {detached: true}); - process.exit(0); - } -}; - -console.log(`Initializing voice engine with audio subsystem: ${audioSubsystem}`); -VoiceEngine.initialize({audioSubsystem, logLevel}); - -module.exports = VoiceEngine; +const VoiceEngine = require(process.platform === "linux" ? './discord_voice_linux.node' : './discord_voice.node'); +const ChildProcess = require('child_process'); +const path = require('path'); +const yargs = require('yargs'); + +const isElectronRenderer = + typeof window !== 'undefined' && window != null && window.DiscordNative && window.DiscordNative.isRenderer; + +const appSettings = isElectronRenderer ? window.DiscordNative.settings : global.appSettings; +const features = isElectronRenderer ? window.DiscordNative.features : global.features; +const mainArgv = isElectronRenderer ? window.DiscordNative.processUtils.getMainArgvSync() : []; +const releaseChannel = isElectronRenderer ? window.DiscordNative.app.getReleaseChannel() : ''; +const useLegacyAudioDevice = appSettings ? appSettings.getSync('useLegacyAudioDevice') : false; +const audioSubsystemSelected = appSettings + ? appSettings.getSync('audioSubsystem') === 'legacy' + ? 'legacy' + : 'standard' + : 'standard'; +const audioSubsystem = useLegacyAudioDevice || audioSubsystemSelected; +const debugLogging = appSettings ? appSettings.getSync('debugLogging') : false; + +const argv = yargs(mainArgv.slice(1)) + .describe('log-level', 'Logging level.') + .default('log-level', -1) + .help('h') + .alias('h', 'help') + .exitProcess(false).argv; +const logLevel = argv['log-level'] == -1 ? (debugLogging ? 2 : -1) : argv['log-level']; + +if (debugLogging && console.discordVoiceHooked == null) { + console.discordVoiceHooked = true; + + for (const logFn of ['trace', 'debug', 'info', 'warn', 'error', 'log']) { + const originalLogFn = console[logFn]; + + if (originalLogFn != null) { + console[logFn] = function () { + originalLogFn.apply(this, arguments); + + try { + VoiceEngine.consoleLog( + logFn, + JSON.stringify(Array.from(arguments).map((v) => (v != null ? v.toString() : v))) + ); + } catch (e) { + // Drop errors from toString()/stringify. + } + }; + } + } +} + +features.declareSupported('voice_panning'); +features.declareSupported('voice_multiple_connections'); +features.declareSupported('media_devices'); +features.declareSupported('media_video'); +features.declareSupported('debug_logging'); +features.declareSupported('set_audio_device_by_id'); +features.declareSupported('set_video_device_by_id'); +features.declareSupported('loopback'); +features.declareSupported('experiment_config'); +features.declareSupported('remote_locus_network_control'); +features.declareSupported('connection_replay'); +features.declareSupported('simulcast'); + +if (process.platform === 'win32') { + features.declareSupported('voice_legacy_subsystem'); + features.declareSupported('soundshare'); + features.declareSupported('wumpus_video'); + features.declareSupported('hybrid_video'); + features.declareSupported('elevated_hook'); + features.declareSupported('soundshare_loopback'); + features.declareSupported('screen_previews'); + features.declareSupported('window_previews'); + features.declareSupported('audio_debug_state'); + // NOTE(jvass): currently there's no experimental encoders! Add this back if you + // add one and want to re-enable the UI for them. + // features.declareSupported('experimental_encoders'); +} + +const VoiceReplayConnection = VoiceEngine.VoiceReplayConnection; + +delete VoiceEngine.VoiceReplayConnection; + +VoiceEngine.createTransport = VoiceEngine._createTransport; + +if (isElectronRenderer) { + VoiceEngine.setImageDataAllocator((width, height) => new window.ImageData(width, height)); +} + +VoiceEngine.createReplayConnection = function (audioEngineId, callback, replayLog) { + if (replayLog == null) { + return null; + } + + return new VoiceReplayConnection(replayLog, audioEngineId, callback); +}; + +VoiceEngine.setAudioSubsystem = function (subsystem) { + if (appSettings == null) { + console.warn('Unable to access app settings.'); + return; + } + + // TODO: With experiment controlling ADM selection, this may be incorrect since + // audioSubsystem is read from settings (or default if does not exists) + // and not the actual ADM used. + if (subsystem === audioSubsystem) { + return; + } + + appSettings.set('audioSubsystem', subsystem); + appSettings.set('useLegacyAudioDevice', false); + + if (isElectronRenderer) { + window.DiscordNative.app.relaunch(); + } +}; + +VoiceEngine.setDebugLogging = function (enable) { + if (appSettings == null) { + console.warn('Unable to access app settings.'); + return; + } + + if (debugLogging === enable) { + return; + } + + appSettings.set('debugLogging', enable); + + if (isElectronRenderer) { + window.DiscordNative.app.relaunch(); + } +}; + +VoiceEngine.getDebugLogging = function () { + return debugLogging; +}; + +reloadElectronApp = function () { + if (isElectronRenderer) { + const app = require('electron').remote.app; + app.relaunch(); + app.exit(0); + } else { + ChildProcess.spawn(process.argv[0], process.argv.splice(1), {detached: true}); + process.exit(0); + } +}; + +console.log(`Initializing voice engine with audio subsystem: ${audioSubsystem}`); +VoiceEngine.initialize({audioSubsystem, logLevel}); + +module.exports = VoiceEngine; diff --git a/modules/discord_voice/libopenh264.so.4 b/modules/discord_voice/libopenh264.so.4 new file mode 100644 index 0000000..7395e27 Binary files /dev/null and b/modules/discord_voice/libopenh264.so.4 differ diff --git a/package-lock.json b/package-lock.json index fb32500..c215bb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lightcord", - "version": "0.1.0", + "version": "0.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -403,9 +403,9 @@ } }, "electron": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-8.3.0.tgz", - "integrity": "sha512-XRjiIJICZCgUr2vKSUI2PTkfP0gPFqCtqJUaTJSfCTuE3nTrxBKOUNeRMuCzEqspKkpFQU3SB3MdbMSHmZARlQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-8.4.0.tgz", + "integrity": "sha512-SpgyccM5rjDJSGcpQjiviUBT44fZlSyhcjy8RpKSnAad+co4xY1vYj6T25U1CfSk0PH/dhvcp63P2sdXHCwq/Q==", "dev": true, "requires": { "@electron/get": "^1.0.1", @@ -1399,6 +1399,15 @@ "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } + }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3" + } } } } diff --git a/package.json b/package.json index 2dceeb2..5f8aeaf 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,14 @@ "compile": "node compile.js", "test": "npm run compile && electron .", "run": "electron .", - "build": "npm run build:minify && npm run build:electron", - "build:electron": "electron-packager ./distApp --ignore=\"(distApp|builds|\\.ts)\" --arch=ia32 --win32metadata.ProductName=\"Lightcord\" --win32metadata.CompanyName=\"Lightcord\" --protocol=discord --platform=\"win32,linux\" --out=builds --icon=app.ico --executable-name=\"Lightcord\" --asar.unpack=*.{node,dll} --overwrite", + "build": "npm run build:minify && npm run build:electron && npm run build:after", + "build:electron": "npm run build:electron_win && npm run build:electron_linux", + "build:electron_win": "electron-packager ./distApp --ignore=\"(distApp|builds|\\.ts)\" --arch=ia32 --win32metadata.ProductName=\"Lightcord\" --win32metadata.CompanyName=\"Lightcord\" --protocol=discord --platform=\"win32\" --out=builds --icon=app.ico --executable-name=\"Lightcord\" --asar.unpack=*.{node,dll} --overwrite", + "build:electron_linux": "electron-packager ./distApp --ignore=\"(distApp|builds|\\.ts)\" --arch=x64 --protocol=discord --platform=\"linux\" --out=builds --icon=app.ico --executable-name=\"Lightcord\" --asar.unpack=*.{node,dll,so.4} --overwrite", "build:minify": "node build.js", - "devInstall": "npm i -g --arch=ia32 electron@8.3.0 && npm i -g typescript && npm i --save-dev @types/node@12.12.39 && npm i --save-dev --arch=ia32 electron@8.3.0 && node installSubModules.js && echo \"Everything is installed. You should be able to do `npm run test` to compile everything and launch.\"" + "build:after": "node afterbuild.js", + "devInstall": "npm i -g --arch=ia32 electron@8.4.0 && npm i -g typescript && npm i --save-dev @types/node@12.12.39 && npm i --save-dev --arch=ia32 electron@8.4.0 && node installSubModules.js && echo \"Everything is installed. You should be able to do `npm run test` to compile everything and launch.\"", + "devInstall:64": "npm i -g --arch=x64 electron@8.4.0 && npm i -g typescript && npm i --save-dev @types/node@12.12.39 && npm i --save-dev --arch=x64 electron@8.4.0 && node installSubModules.js && echo \"Everything is installed. You should be able to do `npm run test` to compile everything and launch.\"" }, "author": "", "license": "ISC", @@ -35,9 +39,10 @@ "@types/uuid": "^8.0.0", "@types/yauzl": "^2.9.1", "cross-spawn": "^7.0.3", - "electron": "^8.3.0", + "electron": "^8.4.0", "react": "^16.13.1", "react-dom": "^16.13.1", - "terser": "^4.7.0" + "terser": "^4.7.0", + "yazl": "^2.5.1" } }