From da7bf3948cfeabda541e644d31f232a7ab557ab4 Mon Sep 17 00:00:00 2001 From: smartfrigde <37928912+smartfrigde@users.noreply.github.com> Date: Sun, 30 Jan 2022 20:48:32 +0100 Subject: [PATCH] Too many bug fixes to list here --- package-lock.json | 8 +- package.json | 7 +- src/content/css/discord.css | 4 +- src/content/settings.html | 1 + src/content/setup.html | 12 +-- src/content/splash.html | 2 +- src/ipc.ts | 70 ++++++++++++++++ src/main.ts | 161 +++++++++--------------------------- src/preload/bridge.ts | 28 +++---- src/preload/preload.ts | 9 +- src/settings/main.ts | 25 ++++++ src/settings/preload.ts | 1 + src/shortcuts.ts | 53 ++++-------- src/tray.ts | 2 +- src/utils.ts | 29 ++++--- src/window.ts | 73 ++++++++++++++++ 16 files changed, 284 insertions(+), 201 deletions(-) create mode 100644 src/content/settings.html create mode 100644 src/ipc.ts create mode 100644 src/settings/main.ts create mode 100644 src/settings/preload.ts create mode 100644 src/window.ts diff --git a/package-lock.json b/package-lock.json index a82d83c..6904b1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "armcord", - "version": "3.0.0", + "name": "ArmCord", + "version": "3.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "armcord", - "version": "3.0.0", + "name": "ArmCord", + "version": "3.1.0", "license": "OSL-3.0", "dependencies": { "electron-json-storage": "^4.5.0", diff --git a/package.json b/package.json index 7d14046..f8342be 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "watch": "tsc -w", "start": "npm run build && electron ./ts-out/main.js", "package": "npm run build && electron-builder" - }, "repository": { "type": "git", @@ -21,12 +20,12 @@ }, "homepage": "https://github.com/armcord/armcord#readme", "devDependencies": { - "electron": "^16.0.7", "@types/electron-json-storage": "^4.5.0", "@types/node": "^14.18.2", - "typescript": "^4.5.4", "copyfiles": "^2.4.1", - "electron-builder": "^22.14.5" + "electron": "^16.0.7", + "electron-builder": "^22.14.5", + "typescript": "^4.5.4" }, "dependencies": { "electron-json-storage": "^4.5.0", diff --git a/src/content/css/discord.css b/src/content/css/discord.css index 5d9fdfa..2d3bdac 100644 --- a/src/content/css/discord.css +++ b/src/content/css/discord.css @@ -1,5 +1,5 @@ -.info-1VyQPT:last-child:before { - content: "ArmCord Version: 3.0.0"!important; +.info-1sUqUG:last-child:before { + content: "ArmCord Version: 3.1.0"!important; height: auto; line-height: 16px; text-align: center; diff --git a/src/content/settings.html b/src/content/settings.html new file mode 100644 index 0000000..6fe5ab8 --- /dev/null +++ b/src/content/settings.html @@ -0,0 +1 @@ +

settings, really cool

\ No newline at end of file diff --git a/src/content/setup.html b/src/content/setup.html index e83844a..f805f89 100644 --- a/src/content/setup.html +++ b/src/content/setup.html @@ -42,10 +42,10 @@ } else { console.log("Starting ArmCord Setup..."); document.getElementById("express").addEventListener("click", function () { - window.armcord.saveSettings(true, "stable", true, "cumcord"); + window.armcordinternal.saveSettings(true, "stable", true, "cumcord"); fade(document.getElementById("setup")); setTimeout(function () { - window.armcord.restart() + window.armcordinternal.restart() }, 5000); }) document.getElementById("full").addEventListener("click", function () { @@ -90,18 +90,18 @@ .getElementById("next") .addEventListener("click", function () { var mod = document.getElementById("mod").value; - window.armcord.saveSettings(true, branch, true, mod); + window.armcordinternal.saveSettings(true, branch, true, mod); fade(document.getElementById("setup")); setTimeout(function () { - window.armcord.restart(); + window.armcordinternal.restart(); }, 5000); }); } else { //saveSettings(customTitlebarSetting: boolean, channelSetting: string, armcordCSPSetting: boolean, modsSetting: string) - window.armcord.saveSettings(true, branch, true, "none"); + window.armcordinternal.saveSettings(true, branch, true, "none"); fade(document.getElementById("setup")); setTimeout(function () { - window.armcord.restart() + window.armcordinternal.restart() }, 5000); } }); diff --git a/src/content/splash.html b/src/content/splash.html index 7c5c856..ba0327d 100644 --- a/src/content/splash.html +++ b/src/content/splash.html @@ -42,7 +42,7 @@ } }); setTimeout(() => { - window.armcord.splashEnd(); + window.armcordinternal.splashEnd(); switch (window.armcord.channel) { case "stable": window.location.replace("https://discord.com/app"); diff --git a/src/ipc.ts b/src/ipc.ts new file mode 100644 index 0000000..9b62ac0 --- /dev/null +++ b/src/ipc.ts @@ -0,0 +1,70 @@ +//ipc stuff +import { app, ipcMain, shell, desktopCapturer } from "electron"; +import { mainWindow } from "./window"; +import { saveSettings, getVersion } from "./utils"; +import { settings, customTitlebar } from "./main"; +import { createSettingsWindow } from "./settings/main"; +export function registerIpc() { + ipcMain.on("get-app-path", (event, arg) => { + event.reply("app-path", app.getAppPath()); + }); + ipcMain.on("open-external-link", (event, href: string) => { + shell.openExternal(href); + }); + ipcMain.on("win-maximize", (event, arg) => { + mainWindow.maximize(); + }); + ipcMain.on("win-isMaximized", (event, arg) => { + event.returnValue = mainWindow.isMaximized(); + }); + ipcMain.on("win-minimize", (event, arg) => { + mainWindow.minimize(); + }); + ipcMain.on("win-unmaximize", (event, arg) => { + mainWindow.unmaximize(); + }); + ipcMain.on("win-show", (event, arg) => { + mainWindow.show(); + }); + ipcMain.on("win-hide", (event, arg) => { + mainWindow.hide(); + }); + ipcMain.on("get-app-version", (event) => { + event.returnValue = getVersion(); + }); + ipcMain.on("splashEnd", (event, arg) => { + mainWindow.setSize(800, 600); + }); + ipcMain.on("restart", (event, arg) => { + app.relaunch(); + app.exit(); + }); + + ipcMain.on("saveSettings", (event, ...args) => { + //@ts-ignore + saveSettings(...args); + }); + ipcMain.on("channel", (event) => { + event.returnValue = settings.channel; + }); + ipcMain.on("clientmod", (event, arg) => { + event.returnValue = settings.mods; + }); + ipcMain.on("titlebar", (event, arg) => { + event.returnValue = customTitlebar; + }); + ipcMain.on("openSettingsWindow", (event, arg) => { + createSettingsWindow(); + }); + ipcMain.on("setting-armcordCSP", (event) => { + if (settings.armcordCSP) { + event.returnValue = true; + } else { + event.returnValue = false; + } + }); + ipcMain.handle("DESKTOP_CAPTURER_GET_SOURCES", (event, opts) => + desktopCapturer.getSources(opts) + ); + +} diff --git a/src/main.ts b/src/main.ts index 16730e9..de8e4db 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,24 +2,21 @@ import { app, BrowserWindow, - ipcMain, - shell, - desktopCapturer, session, } from "electron"; import * as path from "path"; import "v8-compile-cache"; import * as storage from "electron-json-storage"; -import { saveSettings, getVersion, setup, getConfigUnsafe } from "./utils"; +import { getConfigUnsafe, setup } from "./utils"; import "./extensions/mods"; import "./extensions/plugin"; import "./tray"; +import { mainWindow, createCustomWindow, createNativeWindow } from "./window"; import "./shortcuts"; -var contentPath: string; +export var contentPath: string; var channel: string; -export var mainWindow: BrowserWindow; -var settings: any; - +export var settings: any; +export var customTitlebar: boolean; storage.has("settings", function (error, hasKey) { if (error) throw error; @@ -27,119 +24,41 @@ storage.has("settings", function (error, hasKey) { console.log("First run of the ArmCord. Starting setup."); setup(); contentPath = path.join(__dirname, "/content/setup.html"); - if(!contentPath.includes("ts-out")) { - contentPath = path.join(__dirname,"/ts-out/content/setup.html"); - } + if (!contentPath.includes("ts-out")) { + contentPath = path.join(__dirname, "/ts-out/content/setup.html"); + } } else { console.log("ArmCord has been run before. Skipping setup."); - contentPath = path.join(__dirname,"/content/splash.html"); - if(!contentPath.includes("ts-out")) { - contentPath = path.join(__dirname,"/ts-out/content/splash.html"); + contentPath = path.join(__dirname, "/content/splash.html"); + if (!contentPath.includes("ts-out")) { + contentPath = path.join(__dirname, "/ts-out/content/splash.html"); + } } -}}); +}); storage.get("settings", function (error, data: any) { if (error) throw error; console.log(data); channel = data.channel; settings = data; - }); -var titlebar:any = getConfigUnsafe("customTitlebar") -console.log(!titlebar) -function createWindow() { - mainWindow = new BrowserWindow({ - width: 300, - height: 350, - title: "ArmCord", - darkTheme: true, - icon: path.join(__dirname, "/assets/icon_transparent.png"), - frame: !titlebar, - autoHideMenuBar: true, - webPreferences: { - preload: path.join(__dirname, "preload/preload.js"), - }, - }); - ipcMain.on("get-app-path", (event, arg) => { - event.reply("app-path", app.getAppPath()); - }); - ipcMain.on("open-external-link", (event, href: string) => { - shell.openExternal(href); - }); - ipcMain.on("win-maximize", (event, arg) => { - mainWindow.maximize(); - }); - ipcMain.on("win-isMaximized", (event, arg) => { - event.returnValue = mainWindow.isMaximized(); - }); - ipcMain.on("win-minimize", (event, arg) => { - mainWindow.minimize(); - }); - ipcMain.on("win-unmaximize", (event, arg) => { - mainWindow.unmaximize(); - }); - ipcMain.on("win-show", (event, arg) => { - mainWindow.show(); - }); - ipcMain.on("win-hide", (event, arg) => { - mainWindow.hide(); - }); - ipcMain.on("get-app-version", (event) => { - event.returnValue = getVersion(); - }); - ipcMain.on("splashEnd", (event, arg) => { - mainWindow.setSize(800, 600); - }); - ipcMain.on("restart", (event, arg) => { - app.relaunch(); - app.exit(); - }); - - ipcMain.on("saveSettings", (event, ...args) => { - //@ts-ignore - saveSettings(...args); - }); - ipcMain.on("channel", (event) => { - event.returnValue = channel; - }); - ipcMain.on("clientmod", (event, arg) => { - event.returnValue = settings.mods; - }); - - ipcMain.on("setting-armcordCSP", (event) => { - storage.get("settings", function (error, data: any) { - if (error) throw error; - if (data.armcordCSP) { - event.returnValue = true; - } else { - event.returnValue = false; - } - }); - }); - ipcMain.handle("DESKTOP_CAPTURER_GET_SOURCES", (event, opts) => - desktopCapturer.getSources(opts) - ); - mainWindow.webContents.userAgent = - "Mozilla/5.0 (X11; Linux x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"; //fake useragent for screenshare to work - mainWindow.webContents.setWindowOpenHandler(({ url }) => { - shell.openExternal(url); - return { action: "deny" }; - }); - console.log(contentPath) - try { - mainWindow.loadFile(contentPath); - } catch(e) { - console.log("Major error detected while starting up. User is most likely on Windows platform. Fallback to alternative startup.") - mainWindow.loadURL(`file://${__dirname}/ts-out/content/splash.html`); +app.whenReady().then(async () => { + if (await getConfigUnsafe("customTitlebar") == true) { + console.log("Creating custom titlebar window."); + customTitlebar = true; + createCustomWindow(); + } else if (await getConfigUnsafe("customTitlebar") == "setup") { + //rare case of setup window + console.log("Creating setup window."); + customTitlebar = true; + createCustomWindow(); + } else { + console.log("Creating native titlebar window."); + customTitlebar = false; + createNativeWindow(); } -} - -app.whenReady().then(() => { - createWindow(); session .fromPartition("some-partition") .setPermissionRequestHandler((webContents, permission, callback) => { - const url = webContents.getURL(); //unused? - if (permission === "notifications") { // Approves the permissions request callback(true); @@ -148,21 +67,21 @@ app.whenReady().then(() => { // Approves the permissions request callback(true); } - if (url.startsWith("discord://")) { - // Denies the permissions request - return callback(false); - } - if (url.startsWith("discord.com/science")) { - // Denies the permissions request - return callback(false); - } - if (url.startsWith("discord.com/tracing")) { - // Denies the permissions request - return callback(false); - } }); + mainWindow.webContents.session.webRequest.onBeforeRequest( + (details, callback) => { + if (/api\/v\d\/science$/g.test(details.url)) + return callback({ cancel: true }); + return callback({}); + } + ); app.on("activate", function () { - if (BrowserWindow.getAllWindows().length === 0) createWindow(); + if (BrowserWindow.getAllWindows().length === 0) + if (!settings.customTitlebar) { + createNativeWindow(); + } else { + createCustomWindow(); + } }); }); diff --git a/src/preload/bridge.ts b/src/preload/bridge.ts index 5916881..c65300f 100644 --- a/src/preload/bridge.ts +++ b/src/preload/bridge.ts @@ -11,24 +11,22 @@ contextBridge.exposeInMainWorld("armcord", { }, titlebar: { injectTitlebar: () => injectTitlebar(), + isTitlebar: ipcRenderer.sendSync("titlebar"), }, electron: process.versions.electron, channel: ipcRenderer.sendSync("channel"), version: ipcRenderer.sendSync("get-app-version", "app-version"), getDisplayMediaSelector: getDisplayMediaSelector, - restart: () => ipcRenderer.send("restart"), - saveSettings: (...args: any) => ipcRenderer.send("saveSettings", ...args), - splashEnd: () => ipcRenderer.send("splashEnd"), + openSettingsWindow: () => ipcRenderer.send("openSettingsWindow"), }); -contextBridge.exposeInMainWorld("electron", { - //deprecated, used for legacy purposes, will be removed in future versions - window: { - show: () => ipcRenderer.send("win-show"), - hide: () => ipcRenderer.send("win-hide"), - minimize: () => ipcRenderer.send("win-minimize"), - maximize: () => ipcRenderer.send("win-maximize"), - }, - electron: process.versions.electron, - warning: 'This is a deprecated API and will be removed in future versions (3.0.0 --> 3.1.0).', - version: ipcRenderer.sendSync("get-app-version", "app-version"), -}); +//to be only used inside armcord internal setup/splash etc +if ( + window.location.href.indexOf("splash.html") > -1 || + window.location.href.indexOf("setup.html") > -1 +) { + contextBridge.exposeInMainWorld("armcordinternal", { + restart: () => ipcRenderer.send("restart"), + saveSettings: (...args: any) => ipcRenderer.send("saveSettings", ...args), + splashEnd: () => ipcRenderer.send("splashEnd"), + }); +} \ No newline at end of file diff --git a/src/preload/preload.ts b/src/preload/preload.ts index 3551d62..ceea49a 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -6,6 +6,11 @@ import { injectTitlebar } from "./titlebar"; import { sleep, addStyle } from "../utils"; import { ipcRenderer } from "electron"; +declare global { + interface Window { + armcord: any; + } +} const clientMods = { goosemod: "https://api.goosemod.com/inject.js", cumcord: @@ -26,7 +31,9 @@ console.log("ArmCord"); if (window.location.href.indexOf("splash.html") > -1) { console.log("Skipping titlebar injection and client mod injection."); } else { - injectTitlebar(); + if (ipcRenderer.sendSync("titlebar")) { + injectTitlebar(); + } sleep(5000).then(() => { const cssPath = path.join(__dirname, "../", "/content/css/discord.css"); addStyle(fs.readFileSync(cssPath, "utf8")); diff --git a/src/settings/main.ts b/src/settings/main.ts new file mode 100644 index 0000000..3c503b0 --- /dev/null +++ b/src/settings/main.ts @@ -0,0 +1,25 @@ +import { BrowserWindow, shell } from "electron"; +import path from "path"; + +var settingsWindow; +export function createSettingsWindow() { + settingsWindow = new BrowserWindow({ + width: 500, + height: 600, + title: "ArmCord Settings", + darkTheme: true, + icon: path.join(__dirname, "/assets/icon_transparent.png"), + frame: false, + autoHideMenuBar: true, + webPreferences: { + preload: path.join(__dirname, "preload/preload.js"), + }, + }); + + settingsWindow.webContents.setWindowOpenHandler(({ url }) => { + shell.openExternal(url); + return { action: "deny" }; + }); + + settingsWindow.loadFile("settings.html"); +} diff --git a/src/settings/preload.ts b/src/settings/preload.ts new file mode 100644 index 0000000..d8ec246 --- /dev/null +++ b/src/settings/preload.ts @@ -0,0 +1 @@ +console.log("test") \ No newline at end of file diff --git a/src/shortcuts.ts b/src/shortcuts.ts index 6cf522e..74221bd 100644 --- a/src/shortcuts.ts +++ b/src/shortcuts.ts @@ -1,35 +1,18 @@ - -import { Menu, MenuItem } from "electron"; -import { mainWindow } from "./main"; -const menu = new Menu(); -menu.append( - new MenuItem({ - label: "ArmCord" + process.env.npm_package_version, - submenu: [ - { - role: "toggleDevTools", - accelerator: - process.platform === "darwin" ? "Ctrl+Cmd+I" : "Ctrl+Shift+I", - click: () => { - mainWindow.webContents.toggleDevTools(); - }, - }, - { - role: "toggleDevTools", - accelerator: "F12", - click: () => { - mainWindow.webContents.toggleDevTools(); - }, - }, - { - role: "reload", - accelerator: - "Ctrl+F5", - click: () => { - mainWindow.webContents.reload(); - }, - }, - ], - }) -); -Menu.setApplicationMenu(menu); \ No newline at end of file +import { app } from "electron"; +import {mainWindow} from './window'; +//https://github.com/electron/electron/issues/1334#issuecomment-716080005 +// TO-DO add more +app.on("web-contents-created", (webContentsCreatedEvent, webContents) => { + webContents.on("before-input-event", (beforeInputEvent, input) => { + // console.log('Main console::', input) + const { code, alt, control, shift, meta } = input; + // Shortcut: toggle devTools + if (shift && control && !alt && !meta && code === "KeyI") { + mainWindow.webContents.toggleDevTools(); + } + // Shortcut: window reload + if (shift && control && !alt && !meta && code === "KeyR") { + mainWindow.reload(); + } + }); +}); diff --git a/src/tray.ts b/src/tray.ts index 8bd4057..f6de5af 100644 --- a/src/tray.ts +++ b/src/tray.ts @@ -1,5 +1,5 @@ import { app, Menu, Tray } from 'electron'; -import {mainWindow} from './main'; +import {mainWindow} from './window'; import * as path from 'path' let tray = null app.whenReady().then(() => { diff --git a/src/utils.ts b/src/utils.ts index 902a2d1..778284e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,8 @@ import * as storage from "electron-json-storage"; import * as fs from "fs"; import { app } from "electron"; +import path from "path"; +export var firstRun: boolean; //utillity functions that are used all over the codebase or just too obscure to be put in the file used in export function addStyle(styleString: string) { @@ -21,9 +23,9 @@ export function setup() { { customTitlebar: true, channel: "stable", - firstRun: "done", + doneSetup: true, armcordCSP: true, - mods: "cumcord" + mods: "cumcord", }, function (error) { if (error) throw error; @@ -45,7 +47,7 @@ export function saveSettings( { customTitlebar: customTitlebarSetting, channel: channelSetting, - firstRun: "done", + doneSetup: true, armcordCSP: armcordCSPSetting, mods: modsSetting, }, @@ -55,15 +57,20 @@ export function saveSettings( ); } export async function getConfigUnsafe(object: string) { - const userDataPath = app.getPath("userData"); - const storagePath = userDataPath + "/storage/"; - let rawdata = fs.readFileSync(storagePath + "settings.json", "utf-8"); - let returndata = JSON.parse(rawdata); - console.log(returndata[object]); - return returndata[object] + try { + const userDataPath = app.getPath("userData"); + const storagePath = path.join(userDataPath, "/storage/"); + let rawdata = fs.readFileSync(storagePath + "settings.json", "utf-8"); + let returndata = JSON.parse(rawdata); + console.log(returndata[object]); + return returndata[object]; + } catch (e) { + console.log("Config probably doesn't exist yet. Returning setup value."); + firstRun = true; + return "setup"; + } } export function getVersion() { //to-do better way of doing this - return '3.0.1'; + return "3.1.0"; } - \ No newline at end of file diff --git a/src/window.ts b/src/window.ts new file mode 100644 index 0000000..13a60fa --- /dev/null +++ b/src/window.ts @@ -0,0 +1,73 @@ +// To allow seamless switching between custom titlebar and native os titlebar, +// I had to add most of the window creation code here to split both into seperete functions +// WHY? Because I can't use the same code for both due to annoying bug with value `frame` not responding to variables +// I'm sorry for this mess but I'm not sure how to fix it. +import { BrowserWindow, shell } from "electron"; +import path from "path"; +import { contentPath } from "./main"; +import { firstRun } from "./utils"; +import { registerIpc } from "./ipc"; +export let mainWindow: BrowserWindow; + +function doAfterDefiningTheWindow() { + registerIpc(); + mainWindow.webContents.userAgent = + "Mozilla/5.0 (X11; Linux x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"; //fake useragent for screenshare to work + mainWindow.webContents.setWindowOpenHandler(({ url }) => { + shell.openExternal(url); + return { action: "deny" }; + }); + + console.log(contentPath); + try { + mainWindow.loadFile(contentPath); + } catch (e) { + console.log( + "Major error detected while starting up. User is most likely on Windows platform. Fallback to alternative startup." + ); + console.log(process.platform); + if (process.platform === "win32") { + if (firstRun) { + mainWindow.loadURL(`file://${__dirname}/content/setup.html`); + } else { + mainWindow.loadURL(`file://${__dirname}/content/splash.html`); + } + } else { + if (firstRun) { + mainWindow.loadURL(`file://${__dirname}/ts-out/content/setup.html`); + } else { + mainWindow.loadURL(`file://${__dirname}/ts-out/content/splash.html`); + } + } + } +} +export function createCustomWindow() { + mainWindow = new BrowserWindow({ + width: 300, + height: 350, + title: "ArmCord", + darkTheme: true, + icon: path.join(__dirname, "/assets/icon_transparent.png"), + frame: false, + autoHideMenuBar: true, + webPreferences: { + preload: path.join(__dirname, "preload/preload.js"), + }, + }); + doAfterDefiningTheWindow(); +} +export function createNativeWindow() { + mainWindow = new BrowserWindow({ + width: 300, + height: 350, + title: "ArmCord", + darkTheme: true, + icon: path.join(__dirname, "/assets/icon_transparent.png"), + frame: true, + autoHideMenuBar: true, + webPreferences: { + preload: path.join(__dirname, "preload/preload.js"), + }, + }); + doAfterDefiningTheWindow(); +}