Compare commits

...

6 commits

Author SHA1 Message Date
smartfridge
33c2c1b81f
Merge branch 'main' into rewrite 2022-01-15 22:23:20 +01:00
smartfrigde
1debbe60fe Getting ready for 3.0 2022-01-15 22:21:51 +01:00
smartfrigde
521278cf00 Titlebar, client mod, Discord, everything loads 2022-01-15 19:31:51 +01:00
smartfridge
b54df99c86
Merge pull request #65 from hanatic/patch-1
Fixed broken link in README
2021-12-22 15:09:28 +01:00
hanatic
d0aef2f7a9
Fixed broken link in README
All it needed was a line break, for some reason. The more you know.
2021-12-22 13:38:45 +00:00
KayoticCarnige
4adfb6998c
Update README.md 2021-11-14 14:19:26 -05:00
17 changed files with 4247 additions and 335 deletions

4
.gitignore vendored
View file

@ -1,3 +1,5 @@
node_modules node_modules
out/ out/
dist dist
ts-out/
ts-out

View file

@ -1,37 +1,43 @@
### THIS IS EXPERIMENTAL REWRITE CODE
<h1 align="center"> <h1 align="center">
<img src="https://armcord.vercel.app/armcord_full_logo.png" width="720"> <img src="https://armcord.vercel.app/armcord_full_logo.png" width="720">
</h1> </h1>
ArmCord is a custom alternative Discord client made for people on lower-end devices and ARM architecture that want custom Discord experience. It uses [Cumcord](https://cumcord.com) for custom themes and plugins! ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.
# Features
* **Standalone client** - ArmCord is built as standalone client, it doesn't rely on original Discord client.
* **Various mods built in** - Explore Cumcord/GooseMod/Flicker plugins and their features!
* **Made for Privacy** - ArmCord automatically blocks Discord's trackers.
* **Faster than normal Discord app** - ArmCord is using newer Electron than stock Discord app. This usually means increased performance and more stable experience.
* **Designed to work anywhere** - ArmCord was initially created in mind to run on Arm64 Linux devices. We soon expanded our support to more platforms. We plan to support every platform that [Electron supports](https://www.electronjs.org/docs/latest/tutorial/support#supported-platforms).
# How to run/install it? # How to run/install it?
Check releases tab for precompiled packages for Linux, Windows and Mac OS (experimental). ### Recommended:
Alternatively you can run ArmCord from source (npm, nodejs required): Check releases tab for precompiled packages for Linux, Windows and Mac OS (experimental).
1.Run `npm install` ### Manual:
2.Run `npm start` Alternatively you can run ArmCord from source (npm, nodejs required):
3.Compile/Package with `npm run make` 1.Clone ArmCord repo: `git clonehttps://github.com/ArmCord/ArmCord.git`
2.Run `npm install` to install dependencies
3.Compile/Package with `npm run package`
# FAQ # FAQ
## 1.Will I get banned from using it? ## 1.Will I get banned from using it?
-You are breaking Discord ToS since we are using Cumcord for themes and plugins. But no one ever got banned from using ArmCord or Cumcord. If you wish to remove Cumcord, you can find it in your mods folder. -You are breaking Discord ToS if you decided to use client mods. But no one ever got banned from using ArmCord or any of the client mods included. If you wish to remove mods, check our documentation.
## 2.How does this work? ## 2.How does this work?
-We are using official web app and adding Cumcord it with some other tweaks. -We are using official web app and adding some magic powder to make it all work!
## 3.Can I use this on other architectures or operating systems? ## 3.Can I use this on other architectures or operating systems?
-Yes! ArmCord should work normally under Windows, ~~Mac OS~~ (Mac OS is broken see [#48](https://github.com/ArmCord/ArmCord/issues/48)), Linux as long as it has NodeJS, npm and Electron support. -Yes! ArmCord should work normally under Windows, ~~Mac OS~~ (Mac OS is broken see [#48](https://github.com/ArmCord/ArmCord/issues/48)), Linux as long as it has NodeJS, npm and Electron support.
## 4.Code is big spaghetti.
-I'm aware. I'm slowly rewriting everything.
# Credits # Credits
[ArmCord UI Elements and few features](https://github.com/kckarnige) [ArmCord UI Elements and few features](https://github.com/kckarnige)
[Cumcord](https://github.com/Cumcord/Cumcord) [Cumcord](https://github.com/Cumcord/Cumcord)
[GooseMod](https://github.com/GooseMod/GooseMod)
[GooseMod Extension](https://github.com/GooseMod/extension) [GooseMod Extension](https://github.com/GooseMod/extension)
[electron-discord-webapp](https://github.com/SpacingBat3/electron-discord-webapp) [electron-discord-webapp](https://github.com/SpacingBat3/electron-discord-webapp)
[custom-electron-titlebar](https://github.com/AlexTorresSk/custom-electron-titlebar) [custom-electron-titlebar (css only)](https://github.com/AlexTorresSk/custom-electron-titlebar)
[electron-localshortcut](https://github.com/parro-it/electron-localshortcut)
[electron-builder](https://electron.build) [electron-builder](https://electron.build)

BIN
build/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

3929
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,14 @@
{ {
"name": "armcord", "name": "ArmCord",
"version": "3.0.0", "version": "2.9.9",
"description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.", "description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.",
"main": "dist/main.js", "main": "ts-out/main.js",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"watch": "tsc -w", "watch": "tsc -w",
"start": "npm run build && npm run copy-files && electron ./dist/main.js", "start": "npm run build && npm run copy-files && electron ./ts-out/main.js",
"copy-files": "copyfiles -u 1 src/**/*.html src/**/*.css dist/ && copyfiles package.json dist/ && copyfiles assets/** dist/" "package": "npm run build && npm run copy-files && electron-builder",
"copy-files": "copyfiles -u 1 src/**/*.html src/**/*.css ts-out/ && copyfiles package.json ts-out/ && copyfiles assets/** ts-out/"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -20,15 +21,32 @@
}, },
"homepage": "https://github.com/armcord/armcord#readme", "homepage": "https://github.com/armcord/armcord#readme",
"devDependencies": { "devDependencies": {
"electron": "^16.0.5" "electron": "^16.0.7",
},
"dependencies": {
"@types/electron-json-storage": "^4.5.0", "@types/electron-json-storage": "^4.5.0",
"@types/node": "^14.18.2", "@types/node": "^14.18.2",
"copyfiles": "^2.4.1",
"electron-json-storage": "^4.5.0",
"typescript": "^4.5.4", "typescript": "^4.5.4",
"v8-compile-cache": "^2.3.0", "copyfiles": "^2.4.1",
"ws": "^8.4.0" "electron-builder": "^22.14.5"
},
"dependencies": {
"electron-json-storage": "^4.5.0",
"v8-compile-cache": "^2.3.0"
},
"build": {
"appId": "com.smartfridge.armcord",
"productName": "ArmCord",
"mac": {
"category": "Network"
},
"linux": {
"category": "Network",
"maintainer": "smartfrigde@gmail.com",
"target": [
"deb",
"tar.gz",
"rpm",
"AppImage"
]
}
} }
} }

View file

@ -0,0 +1,12 @@
.info-1VyQPT:last-child:before {
content: "ArmCord Version: 3.0.0"!important;
height: auto;
line-height: 16px;
text-align: center;
color: var(--text-muted);
font-size: 12px;
text-transform: none;
}
.notice-2HEN-u {
display: none;
}

View file

@ -5,122 +5,104 @@
--armcord-color: #7289da; --armcord-color: #7289da;
--titlebar-color: var(--background-tertiary); --titlebar-color: var(--background-tertiary);
} }
.titleebar { .titlebar {
position: absolute; display: block;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
box-sizing: border-box; flex-shrink: 0;
width: 100%; overflow: hidden;
font-size: 13px; zoom: 1;
padding: 0 16px; box-sizing: border-box;
overflow: hidden; width: 100%;
flex-shrink: 0; clear: both;
align-items: center; height: 30px;
justify-content: center; line-height: 30px;
user-select: none; background-color: #202225;
zoom: 1; -webkit-app-region: drag;
line-height: 22px; width: 100%;
height: 22px; user-select: none;
display: flex; -webkit-user-select: none;
z-index: 99999; position: fixed;
} z-index: 99999;
.titlebar { }
display: block; .titlebar #window-title {
top: 0; width: 30%;
left: 0; height: 100%;
right: 0; line-height: 30px;
flex-shrink: 0; float: left;
overflow: hidden; padding: 0 0 0 1em;
zoom: 1; }
box-sizing: border-box;
width: 100%; .titlebar #window-controls-container {
clear:both; float: right;
height: 30px; width: 150px;
line-height: 30px; height: 100%;
background-color: #202225; line-height: 30px;
-webkit-app-region: drag; background-color: #202225;
width: 100%; -webkit-app-region: no-drag;
user-select: none; }
-webkit-user-select: none;
position: fixed; .titlebar #window-controls-container #minimize,
z-index: 99999; .titlebar #window-controls-container #maximize,
.titlebar #window-controls-container #quit {
} float: left;
.appMount-3lHmkl{ height: 100%;
width: 33%;
} text-align: center;
.titlebar #window-title { color: #f7f7f7;
width: 30%; cursor: default;
height: 100%; }
line-height: 30px;
float: left; .titlebar #window-controls-container #minimize:hover {
padding: 0 0 0 1em; background-color: #99aab5;
} }
.titlebar #window-controls-container #maximize:hover {
.titlebar #window-controls-container { background-color: #99aab5;
float: right; }
width: 150px; .titlebar #window-controls-container #quit:hover {
height: 100%; background-color: #f04747;
line-height: 30px; }
background-color: #202225; .titlebar #window-controls-container #quit {
-webkit-app-region: no-drag; background-color: #f7f7f7;
} -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23000'/%3E%3C/svg%3E")
no-repeat 50% 50%;
.titlebar #window-controls-container #minimize, mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23000'/%3E%3C/svg%3E")
.titlebar #window-controls-container #maximize, no-repeat 50% 50%;
.titlebar #window-controls-container #quit { }
float: left; .titlebar #window-controls-container #minimize {
height: 100%; background-color: #f7f7f7;
width: 33%; -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23000'/%3E%3C/svg%3E")
text-align: center; no-repeat 50% 50%;
color: #f7f7f7; mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23000'/%3E%3C/svg%3E")
cursor: default; no-repeat 50% 50%;
} }
.titlebar #window-controls-container #maximize {
.titlebar #window-controls-container #minimize:hover { background-color: #f7f7f7;
background-color: #99AAB5; -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23000'/%3E%3C/svg%3E")
} no-repeat 50% 50%;
.titlebar #window-controls-container #maximize:hover { mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23000'/%3E%3C/svg%3E")
background-color: #99AAB5; no-repeat 50% 50%;
} }
.titlebar #window-controls-container #quit:hover { .window-title:after {
background-color: #F04747; content: "Cord";
} color: var(--cord-color) !important;
.titlebar #window-controls-container #quit { font-weight: normal;
background-color: #f7f7f7; font-size: 14px;
-webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%; font-family: Discordinated;
mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%; }
} .window-title:before {
.titlebar #window-controls-container #minimize { content: "ARM";
background-color: #f7f7f7; color: var(--armcord-color);
-webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%; font-weight: normal;
mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%; font-size: 14px;
} font-family: Helvetica, sans-serif;
.titlebar #window-controls-container #maximize { }
background-color: #f7f7f7; .window-title {
-webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%; font-size: 0px !important;
mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%; margin-left: initial !important;
} transform: translate(10px, 0px);
.window-title:after { }
content: "Cord"; .withFrame-haYltI {
color: var(--cord-color) !important; height: 30px !important;
font-weight: normal; }
font-size: 14px;
font-family: Discordinated;
}
.window-title:before {
content: "ARM";
color: var(--armcord-color);
font-weight: normal;
font-size: 14px;
font-family: Helvetica, sans-serif;
}
.window-title {
font-size: 0px !important;
margin-left: initial !important;
transform: translate(10px, 0px);
}
.withFrame-haYltI {
height: 23px !important;
}

View file

@ -22,24 +22,7 @@
</div> </div>
</div> </div>
<script> <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) { function fade(element) {
var op = 1; // initial opacity var op = 1; // initial opacity
var timer = setInterval(function () { var timer = setInterval(function () {
@ -58,6 +41,13 @@
"You appear to be offline. Please connect to the internet and restart ArmCord Setup."; "You appear to be offline. Please connect to the internet and restart ArmCord Setup.";
} else { } else {
console.log("Starting ArmCord Setup..."); console.log("Starting ArmCord Setup...");
document.getElementById("express").addEventListener("click", function () {
window.armcord.saveSettings(true, "stable", true, "cumcord");
fade(document.getElementById("setup"));
setTimeout(function () {
window.armcord.restart()
}, 5000);
})
document.getElementById("full").addEventListener("click", function () { document.getElementById("full").addEventListener("click", function () {
document.getElementById("setup").innerHTML = ` document.getElementById("setup").innerHTML = `
<p class="text-center setup-ask">Choose your Discord channel/instance:</p> <p class="text-center setup-ask">Choose your Discord channel/instance:</p>
@ -90,7 +80,7 @@
<select name="mod" id="mod" class="dropdown-button"> <select name="mod" id="mod" class="dropdown-button">
<option value="cumcord">Cumcord</option> <option value="cumcord">Cumcord</option>
<option value="goosemod">GooseMod</option> <option value="goosemod">GooseMod</option>
<option value="flicker">Flicker (WIP)</option> <option value="flicker">Flicker (Heavily WIP)</option>
</select> </select>
</div> </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> <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>
@ -103,8 +93,7 @@
window.armcord.saveSettings(true, branch, true, mod); window.armcord.saveSettings(true, branch, true, mod);
fade(document.getElementById("setup")); fade(document.getElementById("setup"));
setTimeout(function () { setTimeout(function () {
window.armcord.splashEnd(); window.armcord.restart();
discord();
}, 5000); }, 5000);
}); });
} else { } else {
@ -112,8 +101,7 @@
window.armcord.saveSettings(true, branch, true, "none"); window.armcord.saveSettings(true, branch, true, "none");
fade(document.getElementById("setup")); fade(document.getElementById("setup"));
setTimeout(function () { setTimeout(function () {
window.armcord.splashEnd(); window.armcord.restart()
discord();
}, 5000); }, 5000);
} }
}); });

View file

@ -26,25 +26,43 @@
"You appear to be offline. Please connect to the internet and try again."; "You appear to be offline. Please connect to the internet and try again.";
} else { } else {
text.innerHTML = "Starting ArmCord..."; text.innerHTML = "Starting ArmCord...";
fetch("https://armcord.smartfridge.space/latest.json")
.then((response) => response.json())
.then((data) => {
if (data.version !== window.armcord.version) {
var elem = document.createElement("img");
elem.classList.add("logo");
elem.src = "https://armcord.smartfridge.space/update.webp";
document.body.prepend(elem);
document.getElementById("splashscreen-armcord").remove();
text.innerHTML =
"A new version of ArmCord is available. Please update to the latest version.";
} else {
console.log("ArmCord is up to date.")
}
});
setTimeout(() => { setTimeout(() => {
window.armcord.splashEnd(); window.armcord.splashEnd();
switch (window.armcord.channel) { switch (window.armcord.channel) {
case "stable": case "stable":
window.location.href = "https://discord.com/app"; window.location.replace("https://discord.com/app");
break; break;
case "canary": case "canary":
window.location.href = "https://canary.discord.com/app"; window.location.replace("https://canary.discord.com/app");
break; break;
case "ptb": case "ptb":
window.location.href = "https://ptb.discord.com/app"; window.location.replace("https://ptb.discord.com/app");
break; break;
case "foss": case "foss":
window.location.href = "https://dev.fosscord.com/app"; window.location.replace("https://dev.fosscord.com/app");
break;
case undefined:
window.location.replace("https://discord.com/app");
break; break;
default: default:
window.location.href = "https://discord.com/app"; window.location.replace("https://discord.com/app");
}}, 5000); }
}, 5000);
} }
</script> </script>
</html> </html>

View file

@ -1,49 +1,50 @@
// Modules to control application life and create native browser window // Modules to control application life and create native browser window
import { app, BrowserWindow, ipcMain, shell, desktopCapturer } from "electron"; import { app, BrowserWindow, ipcMain, shell, desktopCapturer, session } from "electron";
import * as path from "path"; import * as path from "path";
import "v8-compile-cache"; import "v8-compile-cache";
import * as storage from "electron-json-storage"; import * as storage from "electron-json-storage";
import { saveSettings } from "./utils"; import { saveSettings, getVersion, setup } from "./utils";
import "./extensions/mods"; import "./extensions/mods";
import "./extensions/plugin"; import "./extensions/plugin";
import "./tray"; import "./tray";
var isSetup = null; import "./shortcuts";
var contentPath: string = "null"; var contentPath: string = "null";
var frame: boolean; var frame: boolean;
var channel: string;
var titlebar: boolean;
export var mainWindow: BrowserWindow; export var mainWindow: BrowserWindow;
var settings: any;
storage.keys(function (error, keys) {
if (error) throw error;
for (var key of keys) {
console.log("There is a key called: " + key);
}
});
storage.has("settings", function (error, hasKey) { storage.has("settings", function (error, hasKey) {
if (error) throw error; if (error) throw error;
if (!hasKey) { if (!hasKey) {
console.log("First run of the ArmCord. Starting setup."); console.log("First run of the ArmCord. Starting setup.");
isSetup = true; setup();
// setup(); will be done at setup
contentPath = __dirname + "/content/setup.html"; contentPath = __dirname + "/content/setup.html";
} else { } else {
console.log("ArmCord has been run before. Skipping setup."); console.log("ArmCord has been run before. Skipping setup.");
isSetup = false;
contentPath = __dirname + "/content/splash.html"; contentPath = __dirname + "/content/splash.html";
} }
}); });
storage.get("settings", function (error, data: any) { storage.get("settings", function (error, data: any) {
if (error) throw error; if (error) throw error;
console.log(data); console.log(data);
frame = data.customTitlebar; titlebar = data.customTitlebar;
console.log(frame); channel = data.channel;
settings = data;
if ((titlebar = true)) {
frame = false;
} else {
frame = true;
}
}); });
function createWindow() { function createWindow() {
mainWindow = new BrowserWindow({ mainWindow = new BrowserWindow({
width: 300, width: 300,
height: 350, height: 350,
title: "ArmCord", title: "ArmCord",
icon: "./assets/ac_icon_transparent.png",
frame: frame, frame: frame,
webPreferences: { webPreferences: {
preload: path.join(__dirname, "preload/preload.js"), preload: path.join(__dirname, "preload/preload.js"),
@ -74,27 +75,28 @@ function createWindow() {
mainWindow.hide(); mainWindow.hide();
}); });
ipcMain.on("get-app-version", (event) => { ipcMain.on("get-app-version", (event) => {
event.returnValue = process.env.npm_package_version; event.returnValue = getVersion();
}); });
ipcMain.on("splashEnd", (event, arg) => { ipcMain.on("splashEnd", (event, arg) => {
mainWindow.setSize(800, 600); mainWindow.setSize(800, 600);
}); });
ipcMain.on("channel", (event) => { ipcMain.on("restart", (event, arg) => {
storage.get("settings", function (error, data: any) { app.relaunch();
if (error) throw error; app.exit();
event.returnValue = data.channel;
});
}); });
ipcMain.on("saveSettings", (event, ...args) => { ipcMain.on("saveSettings", (event, ...args) => {
//@ts-ignore //@ts-ignore
saveSettings(...args); saveSettings(...args);
}); });
ipcMain.on('clientmod' , (event, arg) => { ipcMain.on("channel", (event) => {
storage.get("settings", function (error, data: any) { event.returnValue = channel;
if (error) throw error; });
event.returnValue = data.mods; ipcMain.on("clientmod", (event, arg) => {
}); event.returnValue = settings.mods;
}) });
ipcMain.on("setting-armcordCSP", (event) => { ipcMain.on("setting-armcordCSP", (event) => {
storage.get("settings", function (error, data: any) { storage.get("settings", function (error, data: any) {
if (error) throw error; if (error) throw error;
@ -110,16 +112,42 @@ function createWindow() {
); );
mainWindow.webContents.userAgent = 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 "Mozilla/5.0 (X11; Linux x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"; //fake useragent
mainWindow.webContents.on("new-window", function (e, url) { mainWindow.webContents.setWindowOpenHandler(({ url }) => {
e.preventDefault();
shell.openExternal(url); shell.openExternal(url);
return { action: "deny" };
}); });
mainWindow.loadFile(contentPath); mainWindow.loadFile(contentPath);
} }
app.whenReady().then(() => { app.whenReady().then(() => {
createWindow(); createWindow();
session
.fromPartition("some-partition")
.setPermissionRequestHandler((webContents, permission, callback) => {
const url = webContents.getURL(); //unused?
if (permission === "notifications") {
// Approves the permissions request
callback(true);
}
if (permission === "media") {
// 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);
}
});
app.on("activate", function () { app.on("activate", function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow(); if (BrowserWindow.getAllWindows().length === 0) createWindow();
}); });

View file

@ -1,20 +1,31 @@
import { contextBridge, ipcRenderer } from 'electron'; import { contextBridge, ipcRenderer } from "electron";
import {getDisplayMediaSelector} from './capturer'; import { getDisplayMediaSelector } from "./capturer";
console.log(ipcRenderer.send('channel'))
contextBridge.exposeInMainWorld("armcord", { contextBridge.exposeInMainWorld("armcord", {
window: { window: {
show: () => ipcRenderer.send('win-show'), show: () => ipcRenderer.send("win-show"),
hide: () => ipcRenderer.send('win-hide'), hide: () => ipcRenderer.send("win-hide"),
minimize: () => ipcRenderer.send('win-minimize'), minimize: () => ipcRenderer.send("win-minimize"),
maximize: () => ipcRenderer.send('win-maximize'), maximize: () => ipcRenderer.send("win-maximize"),
}, },
electron: process.versions.electron, electron: process.versions.electron,
version: ipcRenderer.send('get-app-version', 'app-version'), channel: ipcRenderer.sendSync("channel"),
version: ipcRenderer.sendSync("get-app-version", "app-version"),
getDisplayMediaSelector: getDisplayMediaSelector, getDisplayMediaSelector: getDisplayMediaSelector,
saveSettings: (...args: any) => ipcRenderer.send('saveSettings', ...args), restart: () => ipcRenderer.send("restart"),
splashEnd: () => ipcRenderer.send('splashEnd'), saveSettings: (...args: any) => ipcRenderer.send("saveSettings", ...args),
channel: ipcRenderer.send('channel') splashEnd: () => ipcRenderer.send("splashEnd"),
}); });
contextBridge.exposeInMainWorld("electron", {}) //deprecated, used for legacy purposes, will be removed in future versions 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"),
});

View file

@ -1,12 +1,10 @@
import "./capturer";
import "./bridge"; import "./bridge";
import "./capturer";
import * as fs from "fs";
import * as path from "path";
import { injectTitlebar } from "./titlebar"; import { injectTitlebar } from "./titlebar";
import { sleep, addStyle } from "../utils";
import { ipcRenderer } from "electron"; import { ipcRenderer } from "electron";
declare global {
interface Window {
splash: any;
}
}
const clientMods = { const clientMods = {
goosemod: "https://api.goosemod.com/inject.js", goosemod: "https://api.goosemod.com/inject.js",
@ -29,18 +27,23 @@ if (window.location.href.indexOf("splash.html") > -1) {
console.log("Skipping titlebar injection and client mod injection."); console.log("Skipping titlebar injection and client mod injection.");
} else { } else {
injectTitlebar(); injectTitlebar();
switch (ipcRenderer.sendSync("clientmod")) { sleep(5000).then(() => {
case "goosemod": const cssPath = path.join(__dirname, "../", "/content/css/discord.css");
injectJS(clientMods.goosemod); addStyle(fs.readFileSync(cssPath, "utf8"));
console.log("Loading GooseMod...");
break; switch (ipcRenderer.sendSync("clientmod")) {
case "cumcord": case "goosemod":
injectJS(clientMods.cumcord); injectJS(clientMods.goosemod);
console.log("Loading Cumcord..."); console.log("Loading GooseMod...");
break; break;
case "flicker": case "cumcord":
injectJS(clientMods.flicker); injectJS(clientMods.cumcord);
console.log("Loading FlickerMod..."); console.log("Loading Cumcord...");
break; break;
} case "flicker":
injectJS(clientMods.flicker);
console.log("Loading FlickerMod...");
break;
}
});
} }

35
src/shortcuts.ts Normal file
View file

@ -0,0 +1,35 @@
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);

View file

@ -1,4 +1,4 @@
import { app, Menu, Tray, ipcRenderer } from 'electron'; import { app, Menu, Tray } from 'electron';
import {mainWindow} from './main'; import {mainWindow} from './main';
let tray = null let tray = null
app.whenReady().then(() => { app.whenReady().then(() => {
@ -24,6 +24,7 @@ app.whenReady().then(() => {
}, },
}, },
]); ]);
tray.setToolTip('ArmCord' + process.env.npm_package_version) tray.setToolTip('ArmCord' + process.env.npm_package_version)
tray.setContextMenu(contextMenu) tray.setContextMenu(contextMenu)
}) })

View file

@ -1,29 +1,58 @@
import * as fs from "fs";
import * as storage from 'electron-json-storage'; 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 //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) { export function addStyle(styleString: string) {
const style = document.createElement('style'); const style = document.createElement("style");
style.textContent = styleString; style.textContent = styleString;
document.head.append(style); document.head.append(style);
}; }
export function addScript(scriptString: string) { export function addScript(scriptString: string) {
var script = document.createElement("script"); var script = document.createElement("script");
script.textContent = scriptString; script.textContent = scriptString;
document.body.append(script); document.body.append(script);
};
export function setup(){
console.log("Setting up ArmCord settings.");
storage.set('settings', { customTitlebar: true, channel: 'stable', firstRun: 'done', armcordCSP: true }, function(error) {
if (error) throw error;
});
} }
export async function sleep(ms:number) { export function setup() {
return new Promise(resolve => setTimeout(resolve, ms));
}
export function saveSettings(customTitlebarSetting: boolean, channelSetting: string, armcordCSPSetting: boolean, modsSetting: string) {
console.log("Setting up ArmCord settings."); console.log("Setting up ArmCord settings.");
storage.set('settings', { customTitlebar: customTitlebarSetting, channel: channelSetting, firstRun: 'done', armcordCSP: armcordCSPSetting, mods: modsSetting }, function(error) { storage.set(
"settings",
{
customTitlebar: true,
channel: "stable",
firstRun: "done",
armcordCSP: true,
},
function (error) {
if (error) throw error; if (error) throw error;
}); }
} );
}
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;
}
);
}
export function getVersion() {
const pkgjson = fs.readFileSync("./package.json", "utf8");
return JSON.parse(pkgjson).version;
}

View file

@ -5,7 +5,7 @@
"compilerOptions": { "compilerOptions": {
// Project Structure // // Project Structure //
"rootDir": "src", // rootDir only affects the STRUCTURE of the folders, not what gets compiled. For extra measure, make sure the structure conforms to "src". "rootDir": "src", // rootDir only affects the STRUCTURE of the folders, not what gets compiled. For extra measure, make sure the structure conforms to "src".
"outDir": "dist", // Likewise, outDir only chooses which folder to compile to. Prevent the compiler from creating JS files right next to source files. "outDir": "ts-out", // Likewise, outDir only chooses which folder to compile to. Prevent the compiler from creating JS files right next to source files.
"moduleResolution": "node", // Specify how the compiler resolves modules, like going for node_modules first then searching elsewhere. The official docs just say to use this instead of classic. "moduleResolution": "node", // Specify how the compiler resolves modules, like going for node_modules first then searching elsewhere. The official docs just say to use this instead of classic.
// Type Settings // // Type Settings //