mirror of
https://github.com/smartfrigde/armcord.git
synced 2024-08-14 23:56:58 +00:00
Working setup + broken loading the actual app
This commit is contained in:
parent
28aac451bf
commit
c2c0e50fd3
8 changed files with 277 additions and 82 deletions
|
@ -2,24 +2,22 @@
|
|||
@import url("https://kckarnige.github.io/femboi_owo/discord-font.css");
|
||||
|
||||
:root {
|
||||
background-color: #2c2f33;
|
||||
--header-secondary: #b9bbbe;
|
||||
--header-primary: #fff;
|
||||
--background-tertiary: #202225;
|
||||
background-color: #2c2f33 !important;
|
||||
--header-secondary: #b9bbbe !important;
|
||||
--header-primary: #fff !important;
|
||||
--background-tertiary: #202225 !important;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #2c2f33;
|
||||
color: white;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #8e9297;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-weight: 100;
|
||||
transform: translateY(-185%);
|
||||
font-family: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
@ -64,22 +62,50 @@ span {
|
|||
color: #fff;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
button#express {
|
||||
margin-right: 84px;
|
||||
}
|
||||
button {
|
||||
background-color: #7289da;
|
||||
font-family: Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #ffffff;
|
||||
padding: 4px;
|
||||
border-radius: 5px;
|
||||
left: 0;
|
||||
margin-top: 5px;
|
||||
|
||||
text-align: center;
|
||||
border-style: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.setup-ask {
|
||||
font-size: 20px;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #687dc6;
|
||||
border-style: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
select {
|
||||
-webkit-appearance: button;
|
||||
-moz-appearance: button;
|
||||
-webkit-padding-end: 20px;
|
||||
-moz-padding-end: 20px;
|
||||
-webkit-padding-start: 2px;
|
||||
-moz-padding-start: 2px;
|
||||
background-color: #2c2f33;
|
||||
background-position: center right;
|
||||
background-repeat: no-repeat;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
|
||||
color: #fff;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
|
@ -1,24 +1,124 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<head>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css"
|
||||
/>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ArmCord Setup</title>
|
||||
<style>
|
||||
@import url("css/setup.css");
|
||||
</style>
|
||||
</head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="logo"></h1>
|
||||
<h2>Welcome to ArmCord!</h2>
|
||||
<div id="setup">
|
||||
<p>Select what kind of setup you want to perform:</p>
|
||||
<button id="express">Express setup</button>
|
||||
<button id="full">Full setup</button>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<button id="express" class="center">Express setup</button>
|
||||
<button id="full" class="center">Full setup</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function discord(){
|
||||
switch (window.armcord.channel) {
|
||||
case "stable":
|
||||
window.location.href = "https://discord.com/app";
|
||||
break;
|
||||
case "canary":
|
||||
window.location.href = "https://canary.discord.com/app";
|
||||
break;
|
||||
case "ptb":
|
||||
window.location.href = "https://ptb.discord.com/app";
|
||||
break;
|
||||
case "foss":
|
||||
window.location.href = "https://dev.fosscord.com/app";
|
||||
break;
|
||||
default:
|
||||
window.location.href = "https://discord.com/app";
|
||||
}
|
||||
}
|
||||
function fade(element) {
|
||||
var op = 1; // initial opacity
|
||||
var timer = setInterval(function () {
|
||||
if (op <= 0.1) {
|
||||
clearInterval(timer);
|
||||
element.style.display = "none";
|
||||
}
|
||||
element.style.opacity = op;
|
||||
element.style.filter = "alpha(opacity=" + op * 100 + ")";
|
||||
op -= op * 0.1;
|
||||
}, 50);
|
||||
}
|
||||
|
||||
if (window.navigator.onLine === false) {
|
||||
document.getElementById("setup").innerHTML =
|
||||
"You appear to be offline. Please connect to the internet and restart ArmCord Setup.";
|
||||
} else {
|
||||
console.log("Starting ArmCord Setup...");
|
||||
document.getElementById("full").addEventListener("click", function () {
|
||||
document.getElementById("setup").innerHTML = `
|
||||
<p class="text-center setup-ask">Choose your Discord channel/instance:</p>
|
||||
<div class="center">
|
||||
<select name="channel" id="channel" class="dropdown-button">
|
||||
<option value="stable">Stable</option>
|
||||
<option value="canary">Canary</option>
|
||||
<option value="ptb">PTB</option>
|
||||
<option value="foss">Fosscord</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="text-center setup-ask">Should ArmCord handle client mods installation?</p>
|
||||
<div class="center">
|
||||
<select name="csp" id="csp" class="dropdown-button">
|
||||
<option value="true">Yes</option>
|
||||
<option value="false">No</option>
|
||||
</select>
|
||||
</div>
|
||||
<button id="next" class="center">Next</button>
|
||||
`;
|
||||
document
|
||||
.getElementById("next")
|
||||
.addEventListener("click", function () {
|
||||
var branch = document.getElementById("channel").value;
|
||||
var csp = document.getElementById("csp").value;
|
||||
if (csp === "true") {
|
||||
document.getElementById("setup").innerHTML = `
|
||||
<p class="text-center setup-ask">Select a client mod you want to install:</p>
|
||||
<div class="center">
|
||||
<select name="mod" id="mod" class="dropdown-button">
|
||||
<option value="cumcord">Cumcord</option>
|
||||
<option value="goosemod">GooseMod</option>
|
||||
<option value="flicker">Flicker (WIP)</option>
|
||||
</select>
|
||||
</div>
|
||||
<p>Why not all of them? Having many client mods at the same time can cause issues. If you really want to do it though, check our documentation ;)</p>
|
||||
<button id="next" class="center">Next</button>
|
||||
`;
|
||||
document
|
||||
.getElementById("next")
|
||||
.addEventListener("click", function () {
|
||||
var mod = document.getElementById("mod").value;
|
||||
window.armcord.saveSettings(true, branch, true, mod);
|
||||
fade(document.getElementById("setup"));
|
||||
setTimeout(function () {
|
||||
window.armcord.splashEnd();
|
||||
discord();
|
||||
}, 5000);
|
||||
});
|
||||
} else {
|
||||
//saveSettings(customTitlebarSetting: boolean, channelSetting: string, armcordCSPSetting: boolean, modsSetting: string)
|
||||
window.armcord.saveSettings(true, branch, true, "none");
|
||||
fade(document.getElementById("setup"));
|
||||
setTimeout(function () {
|
||||
window.armcord.splashEnd();
|
||||
discord();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -8,36 +8,35 @@ The above copyright notice and this permission notice shall be included in all c
|
|||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import electron from 'electron';
|
||||
import * as storage from 'electron-json-storage';
|
||||
import electron from "electron";
|
||||
import * as storage from "electron-json-storage";
|
||||
const otherMods = {
|
||||
generic: {
|
||||
electronProxy: require('util').types.isProxy(electron) // Many modern mods overwrite electron with a proxy with a custom BrowserWindow (copied from PowerCord)
|
||||
}
|
||||
};
|
||||
const unstrictCSP = () => {
|
||||
console.log('Setting up CSP unstricter...');
|
||||
electronProxy: require("util").types.isProxy(electron), // Many modern mods overwrite electron with a proxy with a custom BrowserWindow (copied from PowerCord)
|
||||
},
|
||||
};
|
||||
|
||||
const cspAllowAll = [
|
||||
'connect-src',
|
||||
'style-src',
|
||||
'img-src',
|
||||
'font-src'
|
||||
];
|
||||
const unstrictCSP = () => {
|
||||
console.log("Setting up CSP unstricter...");
|
||||
|
||||
const cspAllowAll = ["connect-src", "style-src", "img-src", "font-src"];
|
||||
|
||||
const corsAllowUrls = [
|
||||
'https://github.com/GooseMod/GooseMod/releases/download/dev/index.js',
|
||||
'https://github-releases.githubusercontent.com/',
|
||||
'https://raw.githubusercontent.com/Cumcord/Cumcord/stable/dist/build.js',
|
||||
'https://raw.githubusercontent.com/Cumcord/Cumcord/master/dist/build.js',
|
||||
'https://raw.githubusercontent.com/FlickerMod/dist/main/build.js'
|
||||
"https://github.com/GooseMod/GooseMod/releases/download/dev/index.js",
|
||||
"https://github-releases.githubusercontent.com/",
|
||||
"https://api.goosemod.com/inject.js",
|
||||
"https://raw.githubusercontent.com/Cumcord/Cumcord/stable/dist/build.js",
|
||||
"https://raw.githubusercontent.com/Cumcord/Cumcord/master/dist/build.js",
|
||||
"https://raw.githubusercontent.com/FlickerMod/dist/main/build.js",
|
||||
];
|
||||
|
||||
electron.session.defaultSession.webRequest.onHeadersReceived(({ responseHeaders, url }, done) => {
|
||||
let csp = responseHeaders!['content-security-policy'];
|
||||
electron.session.defaultSession.webRequest.onHeadersReceived(
|
||||
({ responseHeaders, url }, done) => {
|
||||
let csp = responseHeaders!["content-security-policy"];
|
||||
|
||||
if (otherMods.generic.electronProxy) { // Since patch v16, override other mod's onHeadersRecieved (Electron only allows 1 listener); because they rely on 0 CSP at all (GM just unrestricts some areas), remove it fully if we detect other mods
|
||||
delete responseHeaders!['content-security-policy'];
|
||||
if (otherMods.generic.electronProxy) {
|
||||
// Since patch v16, override other mod's onHeadersRecieved (Electron only allows 1 listener); because they rely on 0 CSP at all (GM just unrestricts some areas), remove it fully if we detect other mods
|
||||
delete responseHeaders!["content-security-policy"];
|
||||
csp = [];
|
||||
}
|
||||
|
||||
|
@ -47,21 +46,24 @@ const unstrictCSP = () => {
|
|||
}
|
||||
|
||||
// Fix Discord's broken CSP which disallows unsafe-inline due to having a nonce (which they don't even use?)
|
||||
csp[0] = csp[0].replace(/'nonce-.*?' /, '');
|
||||
csp[0] = csp[0].replace(/'nonce-.*?' /, "");
|
||||
}
|
||||
|
||||
if (corsAllowUrls.some((x) => url.startsWith(x))) {
|
||||
responseHeaders!['access-control-allow-origin'] = ['*'];
|
||||
responseHeaders!["access-control-allow-origin"] = ["*"];
|
||||
}
|
||||
|
||||
done({ responseHeaders });
|
||||
});
|
||||
};
|
||||
storage.get('settings', function(error, data:any) {
|
||||
}
|
||||
);
|
||||
};
|
||||
storage.get("settings", function (error, data: any) {
|
||||
if (error) throw error;
|
||||
if (data.armcordCSP) {
|
||||
unstrictCSP();
|
||||
} else {
|
||||
console.log('ArmCord CSP is disabled. The CSP should be managed by third-party plugin.');
|
||||
console.log(
|
||||
"ArmCord CSP is disabled. The CSP should be managed by third-party plugin."
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
35
src/main.ts
35
src/main.ts
|
@ -3,13 +3,15 @@ import { app, BrowserWindow, ipcMain, shell, desktopCapturer } from "electron";
|
|||
import * as path from "path";
|
||||
import "v8-compile-cache";
|
||||
import * as storage from "electron-json-storage";
|
||||
import { setup } from "./utils";
|
||||
import { saveSettings } from "./utils";
|
||||
import "./extensions/mods";
|
||||
import "./extensions/plugin";
|
||||
import "./tray";
|
||||
var isSetup = null;
|
||||
var contentPath: string = "null";
|
||||
var frame: boolean;
|
||||
export var mainWindow: BrowserWindow;
|
||||
|
||||
storage.keys(function (error, keys) {
|
||||
if (error) throw error;
|
||||
|
||||
|
@ -17,18 +19,18 @@ storage.keys(function (error, keys) {
|
|||
console.log("There is a key called: " + key);
|
||||
}
|
||||
});
|
||||
storage.has("firstRun", function (error, hasKey) {
|
||||
storage.has("settings", function (error, hasKey) {
|
||||
if (error) throw error;
|
||||
|
||||
if (!hasKey) {
|
||||
console.log("First run of the ArmCord. Starting setup.");
|
||||
isSetup = true;
|
||||
setup();
|
||||
// setup(); will be done at setup
|
||||
contentPath = __dirname + "/content/setup.html";
|
||||
} else {
|
||||
console.log("ArmCord has been run before. Skipping setup.");
|
||||
isSetup = false;
|
||||
contentPath = __dirname + "/content/index.html";
|
||||
contentPath = __dirname + "/content/splash.html";
|
||||
}
|
||||
});
|
||||
storage.get("settings", function (error, data: any) {
|
||||
|
@ -78,7 +80,30 @@ function createWindow() {
|
|||
mainWindow.setSize(800, 600);
|
||||
});
|
||||
ipcMain.on("channel", (event) => {
|
||||
event.returnValue = storage.getSync("channel");
|
||||
storage.get("settings", function (error, data: any) {
|
||||
if (error) throw error;
|
||||
event.returnValue = data.channel;
|
||||
});
|
||||
});
|
||||
ipcMain.on("saveSettings", (event, ...args) => {
|
||||
//@ts-ignore
|
||||
saveSettings(...args);
|
||||
});
|
||||
ipcMain.on('clientmod' , (event, arg) => {
|
||||
storage.get("settings", function (error, data: any) {
|
||||
if (error) throw error;
|
||||
event.returnValue = data.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)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
import {getDisplayMediaSelector} from './capturer';
|
||||
|
||||
console.log(ipcRenderer.send('channel'))
|
||||
|
||||
contextBridge.exposeInMainWorld("armcord", {
|
||||
window: {
|
||||
show: () => ipcRenderer.send('win-show'),
|
||||
|
@ -12,6 +13,8 @@ contextBridge.exposeInMainWorld("armcord", {
|
|||
electron: process.versions.electron,
|
||||
version: ipcRenderer.send('get-app-version', 'app-version'),
|
||||
getDisplayMediaSelector: getDisplayMediaSelector,
|
||||
saveSettings: (...args: any) => ipcRenderer.send('saveSettings', ...args),
|
||||
splashEnd: () => ipcRenderer.send('splashEnd'),
|
||||
channel: ipcRenderer.send('channel')
|
||||
});
|
||||
contextBridge.exposeInMainWorld("electron", {}) //deprecated, used for legacy purposes, will be removed in future versions
|
|
@ -1,6 +1,46 @@
|
|||
import "./capturer";
|
||||
import "./bridge";
|
||||
import { injectTitlebar } from "./titlebar";
|
||||
import { ipcRenderer } from "electron";
|
||||
declare global {
|
||||
interface Window {
|
||||
splash: any;
|
||||
}
|
||||
}
|
||||
|
||||
const clientMods = {
|
||||
goosemod: "https://api.goosemod.com/inject.js",
|
||||
cumcord:
|
||||
"https://raw.githubusercontent.com/Cumcord/Cumcord/stable/dist/build.js",
|
||||
flicker: "https://raw.githubusercontent.com/FlickerMod/dist/main/build.js",
|
||||
};
|
||||
async function injectJS(inject: string) {
|
||||
const js = await (await fetch(`${inject}`)).text();
|
||||
|
||||
const el = document.createElement("script");
|
||||
|
||||
el.appendChild(document.createTextNode(js));
|
||||
|
||||
document.body.appendChild(el);
|
||||
}
|
||||
|
||||
injectTitlebar();
|
||||
console.log("ArmCord");
|
||||
if (window.location.href.indexOf("splash.html") > -1) {
|
||||
console.log("Skipping titlebar injection and client mod injection.");
|
||||
} else {
|
||||
injectTitlebar();
|
||||
switch (ipcRenderer.sendSync("clientmod")) {
|
||||
case "goosemod":
|
||||
injectJS(clientMods.goosemod);
|
||||
console.log("Loading GooseMod...");
|
||||
break;
|
||||
case "cumcord":
|
||||
injectJS(clientMods.cumcord);
|
||||
console.log("Loading Cumcord...");
|
||||
break;
|
||||
case "flicker":
|
||||
injectJS(clientMods.flicker);
|
||||
console.log("Loading FlickerMod...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
15
src/utils.ts
15
src/utils.ts
|
@ -1,7 +1,4 @@
|
|||
/*--------------------------------------------------------------------------------------------------------
|
||||
* This file has parts of one or more project files (VS Code) from Microsoft
|
||||
* You can check your respective license and the original file in https://github.com/Microsoft/vscode/
|
||||
*-------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as storage from 'electron-json-storage';
|
||||
//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,10 +18,12 @@ export function setup(){
|
|||
if (error) throw error;
|
||||
});
|
||||
}
|
||||
export function append<T extends Node>(parent: HTMLElement, ...children: T[]): T {
|
||||
children.forEach(child => parent.appendChild(child));
|
||||
return children[children.length - 1];
|
||||
}
|
||||
export async function sleep(ms:number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
export function saveSettings(customTitlebarSetting: boolean, channelSetting: string, armcordCSPSetting: boolean, modsSetting: string) {
|
||||
console.log("Setting up ArmCord settings.");
|
||||
storage.set('settings', { customTitlebar: customTitlebarSetting, channel: channelSetting, firstRun: 'done', armcordCSP: armcordCSPSetting, mods: modsSetting }, function(error) {
|
||||
if (error) throw error;
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue