Re-add client mods (vencord, shelter)

This commit is contained in:
smartfridge 2022-11-19 18:23:28 +01:00
parent 842b6e8c5d
commit 5d80d44fc8
14 changed files with 188 additions and 38 deletions

View File

@ -28,11 +28,12 @@
"homepage": "https://github.com/armcord/armcord#readme", "homepage": "https://github.com/armcord/armcord#readme",
"devDependencies": { "devDependencies": {
"@types/node": "^17.0.42", "@types/node": "^17.0.42",
"@types/node-fetch": "^2.6.2",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.3",
"chalk-cli": "^5.0.0", "chalk-cli": "^5.0.0",
"copyfiles": "^2.4.1", "copyfiles": "^2.4.1",
"electron": "^20.1.0", "electron": "^20.1.0",
"electron-builder": "^23.0.3", "electron-builder": "^23.6.0",
"husky": "^8.0.1", "husky": "^8.0.1",
"prettier": "^2.7.0", "prettier": "^2.7.0",
"typescript": "^4.7.3" "typescript": "^4.7.3"
@ -40,6 +41,8 @@
"dependencies": { "dependencies": {
"@pyke/vibe": "^0.3.1", "@pyke/vibe": "^0.3.1",
"electron-context-menu": "github:ArmCord/electron-context-menu", "electron-context-menu": "github:ArmCord/electron-context-menu",
"extract-zip": "^2.0.1",
"node-fetch": "v2",
"os-locale": "^6.0.2", "os-locale": "^6.0.2",
"v8-compile-cache": "^2.3.0", "v8-compile-cache": "^2.3.0",
"ws": "^8.8.0" "ws": "^8.8.0"

View File

@ -3,13 +3,16 @@ lockfileVersion: 5.4
specifiers: specifiers:
'@pyke/vibe': ^0.3.1 '@pyke/vibe': ^0.3.1
'@types/node': ^17.0.42 '@types/node': ^17.0.42
'@types/node-fetch': ^2.6.2
'@types/ws': ^8.5.3 '@types/ws': ^8.5.3
chalk-cli: ^5.0.0 chalk-cli: ^5.0.0
copyfiles: ^2.4.1 copyfiles: ^2.4.1
electron: ^20.1.0 electron: ^20.1.0
electron-builder: ^23.0.3 electron-builder: ^23.6.0
electron-context-menu: github:ArmCord/electron-context-menu electron-context-menu: github:ArmCord/electron-context-menu
extract-zip: ^2.0.1
husky: ^8.0.1 husky: ^8.0.1
node-fetch: v2
os-locale: ^6.0.2 os-locale: ^6.0.2
prettier: ^2.7.0 prettier: ^2.7.0
typescript: ^4.7.3 typescript: ^4.7.3
@ -19,12 +22,15 @@ specifiers:
dependencies: dependencies:
'@pyke/vibe': 0.3.1_electron@20.3.1 '@pyke/vibe': 0.3.1_electron@20.3.1
electron-context-menu: github.com/ArmCord/electron-context-menu/280c81398c02a063f46e3285a9708d8db1a7ce32 electron-context-menu: github.com/ArmCord/electron-context-menu/280c81398c02a063f46e3285a9708d8db1a7ce32
extract-zip: 2.0.1
node-fetch: 2.6.7
os-locale: 6.0.2 os-locale: 6.0.2
v8-compile-cache: 2.3.0 v8-compile-cache: 2.3.0
ws: 8.9.0 ws: 8.9.0
devDependencies: devDependencies:
'@types/node': 17.0.45 '@types/node': 17.0.45
'@types/node-fetch': 2.6.2
'@types/ws': 8.5.3 '@types/ws': 8.5.3
chalk-cli: 5.0.0 chalk-cli: 5.0.0
copyfiles: 2.4.1 copyfiles: 2.4.1
@ -184,6 +190,13 @@ packages:
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
dev: true dev: true
/@types/node-fetch/2.6.2:
resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==}
dependencies:
'@types/node': 17.0.45
form-data: 3.0.1
dev: true
/@types/node/16.11.64: /@types/node/16.11.64:
resolution: {integrity: sha512-z5hPTlVFzNwtJ2LNozTpJcD1Cu44c4LNuzaq1mwxmiHWQh2ULdR6Vjwo1UGldzRpzL0yUEdZddnfqGW2G70z6Q==} resolution: {integrity: sha512-z5hPTlVFzNwtJ2LNozTpJcD1Cu44c4LNuzaq1mwxmiHWQh2ULdR6Vjwo1UGldzRpzL0yUEdZddnfqGW2G70z6Q==}
@ -335,6 +348,7 @@ packages:
/asar/3.2.0: /asar/3.2.0:
resolution: {integrity: sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==} resolution: {integrity: sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==}
engines: {node: '>=10.12.0'} engines: {node: '>=10.12.0'}
deprecated: Please use @electron/asar moving forward. There is no API change, just a package name change
hasBin: true hasBin: true
dependencies: dependencies:
chromium-pickle-js: 0.2.0 chromium-pickle-js: 0.2.0
@ -380,6 +394,7 @@ packages:
/base64-js/1.5.1: /base64-js/1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
requiresBuild: true
dev: true dev: true
/bluebird-lst/1.0.9: /bluebird-lst/1.0.9:
@ -976,10 +991,12 @@ packages:
/fast-deep-equal/3.1.3: /fast-deep-equal/3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
requiresBuild: true
dev: true dev: true
/fast-json-stable-stringify/2.1.0: /fast-json-stable-stringify/2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
requiresBuild: true
dev: true dev: true
/fd-slicer/1.1.0: /fd-slicer/1.1.0:
@ -1001,6 +1018,15 @@ packages:
path-exists: 4.0.0 path-exists: 4.0.0
dev: true dev: true
/form-data/3.0.1:
resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
engines: {node: '>= 6'}
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
dev: true
/form-data/4.0.0: /form-data/4.0.0:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -1351,6 +1377,7 @@ packages:
/json-schema-traverse/0.4.1: /json-schema-traverse/0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
requiresBuild: true
dev: true dev: true
/json-stringify-safe/5.0.1: /json-stringify-safe/5.0.1:
@ -1557,6 +1584,18 @@ packages:
dev: true dev: true
optional: true optional: true
/node-fetch/2.6.7:
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
dependencies:
whatwg-url: 5.0.0
dev: false
/noms/0.0.0: /noms/0.0.0:
resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==}
dependencies: dependencies:
@ -1692,6 +1731,7 @@ packages:
/punycode/2.1.1: /punycode/2.1.1:
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
engines: {node: '>=6'} engines: {node: '>=6'}
requiresBuild: true
dev: true dev: true
/pupa/2.1.1: /pupa/2.1.1:
@ -2026,6 +2066,10 @@ packages:
resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==} resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==}
engines: {node: '>=6'} engines: {node: '>=6'}
/tr46/0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
dev: false
/trim-newlines/4.0.2: /trim-newlines/4.0.2:
resolution: {integrity: sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==} resolution: {integrity: sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -2082,6 +2126,7 @@ packages:
/uri-js/4.4.1: /uri-js/4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
requiresBuild: true
dependencies: dependencies:
punycode: 2.1.1 punycode: 2.1.1
dev: true dev: true
@ -2122,6 +2167,17 @@ packages:
dev: true dev: true
optional: true optional: true
/webidl-conversions/3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
dev: false
/whatwg-url/5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
dev: false
/which/2.0.2: /which/2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -2158,6 +2214,7 @@ packages:
/xmlbuilder/15.1.1: /xmlbuilder/15.1.1:
resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==}
engines: {node: '>=8.0'} engines: {node: '>=8.0'}
requiresBuild: true
dev: true dev: true
/xtend/4.0.2: /xtend/4.0.2:

3
src/.npmrc Normal file
View File

@ -0,0 +1,3 @@
node-linker=hoisted
public-hoist-pattern=*
shamefully-hoist=true

View File

@ -53,7 +53,9 @@
<p class="text-center setup-ask" id="setup_question4">Select a client mod you want to install:</p> <p class="text-center setup-ask" id="setup_question4">Select a client mod you want to install:</p>
<div class="center"> <div class="center">
<select name="mod" id="mod" class="dropdown-button"> <select name="mod" id="mod" class="dropdown-button">
<option value="none">None (check Discord)</option> <option value="vencord">Vencord</option>
<option value="shelter">Shelter</option>
<option value="none">None</option>
</select> </select>
</div> </div>
<p class="text-center" id="setup_question4_clientmodnotice"> <p class="text-center" id="setup_question4_clientmodnotice">

View File

@ -47,6 +47,25 @@
console.log("ArmCord is up to date."); console.log("ArmCord is up to date.");
} }
} }
function check() {
if (armcordinternal.installState === "installing") {
text.innerHTML = "Installing mods";
} else if (armcordinternal.installState === "done") {
return true;
} else if (armcordinternal.installState === "modDownload") {
text.innerHTML = "Updating " + armcord.mods;
} else if (armcordinternal.installState === "none") {
text.innerHTML = "Nothing to install. Starting ArmCord";
return true;
} else {
return true;
}
}
while (check() == false) {
console.log("Installing");
}
setTimeout(() => { setTimeout(() => {
window.armcord.splashEnd(); window.armcord.splashEnd();
switch (window.armcord.channel) { switch (window.armcord.channel) {
@ -68,7 +87,7 @@
default: default:
window.location.replace("https://discord.com/app"); window.location.replace("https://discord.com/app");
} }
}, 5000); }, 3000);
} }
} }

View File

@ -21,7 +21,11 @@ const unstrictCSP = () => {
const cspAllowAll = ["connect-src", "style-src", "img-src", "font-src"]; const cspAllowAll = ["connect-src", "style-src", "img-src", "font-src"];
const corsAllowUrls = ["https://raw.githubusercontent.com/Cordwood/builds/master/index.js"]; const corsAllowUrls = [
"https://raw.githubusercontent.com/Cordwood/builds/master/index.js",
"https://github.com/Vendicated/Vencord/releases/download/devbuild/browser.js",
"https://cors.armcord.xyz/raw.githubusercontent.com/uwu/shelter-builds/main/shelter.js"
];
electron.session.defaultSession.webRequest.onHeadersReceived(({responseHeaders, url}, done) => { electron.session.defaultSession.webRequest.onHeadersReceived(({responseHeaders, url}, done) => {
let csp = responseHeaders!["content-security-policy"]; let csp = responseHeaders!["content-security-policy"];

View File

@ -12,7 +12,7 @@ app.whenReady().then(() => {
const manifest = fs.readFileSync(`${userDataPath}/plugins/${file}/manifest.json`, "utf8"); const manifest = fs.readFileSync(`${userDataPath}/plugins/${file}/manifest.json`, "utf8");
var pluginFile = JSON.parse(manifest); var pluginFile = JSON.parse(manifest);
session.defaultSession.loadExtension(`${userDataPath}/plugins/${file}`); session.defaultSession.loadExtension(`${userDataPath}/plugins/${file}`);
console.log(`%cLoaded ${pluginFile.name} made by ${pluginFile.author}`, "color:red"); console.log(`[Mod loader] Loaded ${pluginFile.name} made by ${pluginFile.author}`);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }

View File

@ -9,11 +9,14 @@ import {
getLang, getLang,
getWindowState, getWindowState,
packageVersion, packageVersion,
getDisplayVersion getDisplayVersion,
modInstallState,
installModLoader
} from "./utils"; } from "./utils";
import {customTitlebar} from "./main"; import {customTitlebar} from "./main";
import {createSettingsWindow} from "./settings/main"; import {createSettingsWindow} from "./settings/main";
import os from "os"; import os from "os";
import fs from "fs"
import path from "path"; import path from "path";
export function registerIpc() { export function registerIpc() {
ipcMain.on("get-app-path", (event, arg) => { ipcMain.on("get-app-path", (event, arg) => {
@ -73,6 +76,9 @@ export function registerIpc() {
ipcMain.on("displayVersion", (event) => { ipcMain.on("displayVersion", (event) => {
event.returnValue = getDisplayVersion(); event.returnValue = getDisplayVersion();
}); });
ipcMain.on("modInstallState", (event) => {
event.returnValue = modInstallState;
});
ipcMain.on("get-package-version", (event) => { ipcMain.on("get-package-version", (event) => {
event.returnValue = packageVersion; event.returnValue = packageVersion;
}); });

View File

@ -1,11 +1,10 @@
// Modules to control application life and create native browser window // Modules to control application life and create native browser window
import {app, BrowserWindow, session} from "electron"; import {app, BrowserWindow, session} from "electron";
import "v8-compile-cache"; import "v8-compile-cache";
import {getConfig, checkIfConfigExists, injectElectronFlags} from "./utils"; import {getConfig, checkIfConfigExists, injectElectronFlags, installModLoader} from "./utils";
import "./extensions/mods"; import "./extensions/mods";
import "./extensions/plugin";
import "./tray"; import "./tray";
import {createCustomWindow, createNativeWindow, createTransparentWindow} from "./window"; import {createCustomWindow, createNativeWindow, createTransparentWindow, mainWindow} from "./window";
import path from "path"; import path from "path";
export var iconPath: string; export var iconPath: string;
export var settings: any; export var settings: any;
@ -53,6 +52,7 @@ app.whenReady().then(async () => {
} }
} }
await init(); await init();
await installModLoader()
session.fromPartition("some-partition").setPermissionRequestHandler((webContents, permission, callback) => { session.fromPartition("some-partition").setPermissionRequestHandler((webContents, permission, callback) => {
if (permission === "notifications") { if (permission === "notifications") {
// Approves the permissions request // Approves the permissions request

View File

@ -22,6 +22,7 @@ contextBridge.exposeInMainWorld("armcord", {
return result; return result;
}), }),
version: ipcRenderer.sendSync("get-app-version", "app-version"), version: ipcRenderer.sendSync("get-app-version", "app-version"),
mods: ipcRenderer.sendSync("clientmod"),
packageVersion: ipcRenderer.sendSync("get-package-version", "app-version"), packageVersion: ipcRenderer.sendSync("get-package-version", "app-version"),
getDisplayMediaSelector: getDisplayMediaSelector, getDisplayMediaSelector: getDisplayMediaSelector,
splashEnd: () => ipcRenderer.send("splashEnd"), splashEnd: () => ipcRenderer.send("splashEnd"),
@ -31,6 +32,7 @@ contextBridge.exposeInMainWorld("armcord", {
if (window.location.href.indexOf("splash.html") > -1 || window.location.href.indexOf("setup.html") > -1) { if (window.location.href.indexOf("splash.html") > -1 || window.location.href.indexOf("setup.html") > -1) {
contextBridge.exposeInMainWorld("armcordinternal", { contextBridge.exposeInMainWorld("armcordinternal", {
restart: () => ipcRenderer.send("restart"), restart: () => ipcRenderer.send("restart"),
installState: ipcRenderer.sendSync("modInstallState"),
saveSettings: (...args: any) => ipcRenderer.send("saveSettings", ...args) saveSettings: (...args: any) => ipcRenderer.send("saveSettings", ...args)
}); });
} }

View File

@ -1,11 +1,11 @@
import {ipcRenderer} from "electron";
import "./bridge"; import "./bridge";
import "./capturer"; import "./capturer";
import "./patch"; import "./patch";
import * as fs from "fs"; import * as fs from "fs";
import * as path from "path"; import * as path from "path";
import {injectHummusTitlebar, injectTitlebar} from "./titlebar"; import {injectHummusTitlebar, injectTitlebar} from "./titlebar";
import {sleep, addStyle, injectJS} from "../utils"; import {sleep, addStyle} from "../utils";
import {ipcRenderer} from "electron";
import {injectMobileStuff} from "./mobile"; import {injectMobileStuff} from "./mobile";
var version = ipcRenderer.sendSync("displayVersion"); var version = ipcRenderer.sendSync("displayVersion");
var channel = ipcRenderer.sendSync("channel"); var channel = ipcRenderer.sendSync("channel");
@ -23,10 +23,6 @@ declare global {
armcord: any; armcord: any;
} }
} }
const clientMods = {
goosemod: "https://api.goosemod.com/inject.js",
cordwood: "https://raw.githubusercontent.com/Cordwood/builds/master/index.js"
};
console.log("ArmCord " + version); console.log("ArmCord " + version);
ipcRenderer.on("themeLoader", (event, message) => { ipcRenderer.on("themeLoader", (event, message) => {
@ -48,19 +44,7 @@ if (window.location.href.indexOf("splash.html") > -1) {
sleep(5000).then(async () => { sleep(5000).then(async () => {
const cssPath = path.join(__dirname, "../", "/content/css/discord.css"); const cssPath = path.join(__dirname, "../", "/content/css/discord.css");
addStyle(fs.readFileSync(cssPath, "utf8")); addStyle(fs.readFileSync(cssPath, "utf8"));
await updateLang();
switch (ipcRenderer.sendSync("clientmod")) {
case "goosemod":
injectJS(clientMods.goosemod);
console.log("Loading GooseMod...");
await updateLang();
break;
case "cordwood":
injectJS(clientMods.cordwood);
console.log("Loading Cordwood...");
await updateLang();
break;
}
}); });
} }
/* /*

View File

@ -123,7 +123,8 @@
<br /> <br />
<div class="switch acClientMod"> <div class="switch acClientMod">
<select name="mod" id="mod" class="left dropdown"> <select name="mod" id="mod" class="left dropdown">
<option value="goosemod">GooseMod</option> <option value="vencord">Vencord</option>
<option value="shelter">Shelter</option>
<option value="none">None</option> <option value="none">None</option>
</select> </select>
<p class="header" id="settings-mod">Client mod</p> <p class="header" id="settings-mod">Client mod</p>
@ -131,8 +132,9 @@
Client mods are programs that allow you customize your Discord experience. They can change appearance of Client mods are programs that allow you customize your Discord experience. They can change appearance of
the client, modify behaviours or add new features! the client, modify behaviours or add new features!
<br /> <br />
<b>GooseMod</b> - light, secure, and easy to use, with out of the box experience. Features a built-in <b>Vencord</b> - lightweight, and easy to use client mod. Features a built-in store for plugins.
store for plugins. <br />
<b>Shelter</b> - is a new generation client mod built to be essentially bulletproof.
</p> </p>
</div> </div>
<br /> <br />

View File

@ -1,6 +1,10 @@
import * as fs from "fs"; import * as fs from "fs";
import {app, dialog} from "electron"; import {app, dialog, session} from "electron";
import path from "path"; import path from "path";
import fetch from "node-fetch"
import extract from "extract-zip"
import util from "util"
const streamPipeline = util.promisify(require('stream').pipeline)
export var firstRun: boolean; export var firstRun: boolean;
export var contentPath: string; export var contentPath: string;
export var transparency: boolean; export var transparency: boolean;
@ -73,6 +77,7 @@ export function getDisplayVersion() {
} }
} }
export async function injectJS(inject: string) { export async function injectJS(inject: string) {
const js = await (await fetch(`${inject}`)).text(); const js = await (await fetch(`${inject}`)).text();
const el = document.createElement("script"); const el = document.createElement("script");
@ -252,11 +257,8 @@ export async function setConfig(object: string, toSet: any) {
fs.writeFileSync(getConfigLocation(), toSave, "utf-8"); fs.writeFileSync(getConfigLocation(), toSave, "utf-8");
} }
export async function setConfigBulk(object: Settings) { export async function setConfigBulk(object: Settings) {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const settingsFile = storagePath + "settings.json";
let toSave = JSON.stringify(object); let toSave = JSON.stringify(object);
fs.writeFileSync(settingsFile, toSave, "utf-8"); fs.writeFileSync(getConfigLocation(), toSave, "utf-8");
} }
export async function checkIfConfigExists() { export async function checkIfConfigExists() {
const userDataPath = app.getPath("userData"); const userDataPath = app.getPath("userData");
@ -281,3 +283,69 @@ export async function checkIfConfigExists() {
} }
} }
} }
// Mods
async function updateModBundle() {
try {
console.log("Downloading mod bundle")
const distFolder = app.getPath("userData") + "/plugins/loader/dist/";
while (!fs.existsSync(distFolder)){
//waiting
}
var name: string = await getConfig("mods")
const clientMods = {
vencord: "https://github.com/Vendicated/Vencord/releases/download/devbuild/browser.js",
cordwood: "https://raw.githubusercontent.com/Cordwood/builds/master/index.js",
shelter: "https://raw.githubusercontent.com/uwu/shelter-builds/main/shelter.js"
};
var bundle: string = await (await fetch(clientMods[name as keyof typeof clientMods])).text()
fs.writeFileSync(distFolder + "bundle.js", bundle, "utf-8");
} catch (e) {
console.log("[Mod loader] Failed to install mods")
console.error(e)
dialog.showErrorBox(
"Oops, something went wrong.",
"ArmCord couldn't install mods, please check if you have stable internet connection and restart the app. If this issue persists, report it on the support server/Github issues."
);
}
}
export var modInstallState: string;
export async function installModLoader() {
if (await getConfig("mods") == "none") {
modInstallState = "none"
import("./extensions/plugin");
console.log("[Mod loader] Skipping")
} else {
const pluginFolder = app.getPath("userData") + "/plugins/";
if (!fs.existsSync(pluginFolder + "loader")) {
try {
modInstallState = "installing"
var zipPath = app.getPath("temp") + "/" + "loader.zip";
if (!fs.existsSync(pluginFolder)) {
fs.mkdirSync(pluginFolder);
console.log("[Mod loader] Created missing plugin folder");
}
var loaderZip = await fetch("https://armcord.xyz/loader.zip")
if (!loaderZip.ok) throw new Error(`unexpected response ${loaderZip.statusText}`)
await streamPipeline(loaderZip.body, fs.createWriteStream(zipPath))
await extract(zipPath, { dir: path.join(app.getPath("userData"), "plugins") })
modInstallState = "modDownload"
updateModBundle()
import("./extensions/plugin");
modInstallState = "done"
} catch(e) {
console.log("[Mod loader] Failed to install modloader")
console.error(e)
dialog.showErrorBox(
"Oops, something went wrong.",
"ArmCord couldn't install internal mod loader, please check if you have stable internet connection and restart the app. If this issue persists, report it on the support server/Github issues."
);
}
} else {
modInstallState = "modDownload"
updateModBundle()
import("./extensions/plugin");
modInstallState = "done"
}
}
}

View File

@ -12,7 +12,7 @@ import {
setConfig, setConfig,
setLang, setLang,
setWindowState, setWindowState,
transparency transparency,
} from "./utils"; } from "./utils";
import {registerIpc} from "./ipc"; import {registerIpc} from "./ipc";
import {setMenu} from "./menu"; import {setMenu} from "./menu";