Compare commits

...

8 commits

Author SHA1 Message Date
dependabot[bot]
6a65b4397e
Update prettier requirement from ^2.5.1 to ^2.6.2
Updates the requirements on [prettier](https://github.com/prettier/prettier) to permit the latest version.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.5.1...2.6.2)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-10 18:48:42 +00:00
smartfrigde
98f88f4609 Fix icon loading 2022-06-10 20:46:30 +02:00
smartfrigde
81377d3657 Add performance mode 2022-06-10 20:27:37 +02:00
KayoticCarnige
40d743d0e2 Fixed "null" bug
Fixed "null" bug, where on Windows, Discord wouldn't recognize the OS (Only tested onw Windows 10)
2022-06-03 12:05:28 -04:00
smartfrigde
54b1481a4e Update WindowOpenHandler to be much more secure 2022-06-03 15:18:36 +02:00
smartfrigde
12352e3536 Fix icon generating on Debian 2022-06-02 14:28:42 +02:00
smartfrigde
13eb57d17d Add the stable release workflow onto dev 2022-06-02 14:27:29 +02:00
smartfrigde
af84a2a625 Add a license header for OpenAsar version settings/version info injection 2022-05-23 15:42:13 +02:00
10 changed files with 328 additions and 15 deletions

196
.github/workflows/stable.yml vendored Normal file
View file

@ -0,0 +1,196 @@
name: Release build
on:
push:
branches:
- stable
env:
FORCE_COLOR: true
jobs:
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Checkout code
uses: actions/checkout@v2
- name: Install Node dependencies
run: npm install
- name: Install Electron-Builder
run: npm install -g electron-builder
- name: Build
run: npm run build && electron-builder --linux && electron-builder --arm64 --linux && electron-builder --armv7l --linux
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: List all files in the dist directory
run: ls -l dist
- name: Delete unpacked builds
run: rm -rf dist/linux-unpacked && rm -rf dist/linux-arm64-unpacked && rm -rf dist/linux-armv7l-unpacked
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordLinux
path: dist/
build-mac:
runs-on: macos-latest
steps:
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Checkout code
uses: actions/checkout@v2
- name: Install Node dependencies
run: npm install
- name: Install Electron-Builder
run: npm install -g electron-builder
- name: Build
run: npm run build && electron-builder --macos
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: List all files in the dist directory
run: ls -l dist
- name: Delete unpacked builds
run: rm -rf dist/macos-unpacked
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordMac
path: dist/
build-windows:
runs-on: windows-latest
steps:
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Checkout code
uses: actions/checkout@v2
- name: Install Node dependencies
run: npm install
- name: Install Electron-Builder
run: npm install -g electron-builder
- name: Build
run: npm run build && electron-builder --windows
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Delete unpacked builds
run: Remove-Item -LiteralPath ".\dist\win-unpacked" -Force -Recurse
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordWindows
path: dist/
release:
runs-on: ubuntu-latest
needs: [build-linux, build-mac, build-windows]
steps:
- uses: actions/download-artifact@v2
with:
name: ArmCordMac
path: macos
- uses: actions/download-artifact@v2
with:
name: ArmCordWindows
path: windows
- uses: actions/download-artifact@v2
with:
name: ArmCordLinux
path: linux
- name: ls
run: ls
- name: Delete unwanted directories
run: rm -rf {linux,macos,windows}/*/
rm -rf {linux,macos,windows}/.icon*
rm -rf {linux,macos,windows}/builder-debug.yml
- name: ls dirs
run: ls linux && ls macos && ls windows
- name: Get some values needed for the release
id: vars
shell: bash
run: |
echo "::set-output name=releaseTag::$(git describe --tags --abbrev=0)"
- uses: dev-drprasad/delete-tag-and-release@v0.2.0
with:
delete_release: true
tag_name: v3.0.6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Release
uses: actions/github-script@v2
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
console.log('environment', process.versions);
const fs = require('fs').promises;
const { repo: { owner, repo }, sha } = context;
console.log({ owner, repo, sha });
const release = await github.repos.createRelease({
owner, repo,
tag_name: process.env.releaseTag,
draft: true,
target_commitish: sha
});
console.log('created release', { release });
for (let file of await fs.readdir('linux')) {
// do whatever filtering you want here, I'm just uploading all the files
console.log('uploading', file);
await github.repos.uploadReleaseAsset({
owner, repo,
release_id: release.data.id,
name: file,
data: await fs.readFile(`./linux/${file}`)
});
}
for (let file of await fs.readdir('windows')) {
// do whatever filtering you want here, I'm just uploading all the files
console.log('uploading', file);
await github.repos.uploadReleaseAsset({
owner, repo,
release_id: release.data.id,
name: file,
data: await fs.readFile(`./windows/${file}`)
});
}
for (let file of await fs.readdir('macos')) {
// do whatever filtering you want here, I'm just uploading all the files
console.log('uploading', file);
await github.repos.uploadReleaseAsset({
owner, repo,
release_id: release.data.id,
name: file,
data: await fs.readFile(`./macos/${file}`)
});
}
env:
releaseTag: ${{ steps.vars.outputs.releaseTag }}

View file

@ -73,7 +73,7 @@ ArmCord is also available on the Snap store [here](https://snapcraft.io/armcord)
[electron-discord-webapp](https://github.com/SpacingBat3/electron-discord-webapp)
[custom-electron-titlebar (css only)](https://github.com/AlexTorresSk/custom-electron-titlebar)
[electron-builder](https://electron.build)
[OpenAsar (~~stole~~ borrowed code for adding custom build info seemlessly)](https://github.com/GooseMod/OpenAsar)
[OpenAsar](https://github.com/GooseMod/OpenAsar)
# Sponsors
[![JetBrains supports ArmCord with free licenses to their software to core developers](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://jb.gg/OpenSourceSupport)

BIN
build/icon.icns Normal file

Binary file not shown.

View file

@ -26,10 +26,10 @@
"@types/node": "^17.0.33",
"@types/ws": "^8.5.3",
"copyfiles": "^2.4.1",
"electron": "^18.2.4",
"electron": "^19.0.4",
"electron-builder": "^23.0.3",
"husky": "^8.0.1",
"prettier": "^2.5.1",
"prettier": "^2.6.2",
"typescript": "^4.6.3"
},
"dependencies": {
@ -44,6 +44,7 @@
"category": "Network"
},
"linux": {
"icon": "build/icon.icns",
"category": "Network",
"maintainer": "smartfrigde@gmail.com",
"target": [

View file

@ -101,6 +101,7 @@
automaticPatches: false,
mods: "cumcord",
inviteWebsocket: true,
performanceMode: "none",
blurType: "acrylic"
});
setTimeout(() => window.armcordinternal.restart(), 5000);
@ -130,6 +131,7 @@
autoLaunch: true,
minimizeToTray: true,
automaticPatches: false,
performanceMode: "none",
mods: options.mod,
inviteWebsocket: true,
blurType: "acrylic"
@ -145,6 +147,7 @@
automaticPatches: false,
autoLaunch: true,
mods: "none",
performanceMode: "none",
inviteWebsocket: true,
blurType: "acrylic"
});

View file

@ -1,7 +1,7 @@
// Modules to control application life and create native browser window
import {app, BrowserWindow, session, dialog} from "electron";
import "v8-compile-cache";
import {getConfig, setup, checkIfConfigExists} from "./utils";
import {getConfig, setup, checkIfConfigExists, injectElectronFlags} from "./utils";
import "./extensions/mods";
import "./extensions/plugin";
import "./tray";
@ -12,6 +12,7 @@ export var settings: any;
export var customTitlebar: boolean;
export var tabs: boolean;
if (process.platform == "linux") {
if (process.env.$XDG_SESSION_TYPE == "wayland") {
console.log("Wayland specific patches applied.");
@ -24,7 +25,7 @@ if (process.platform == "linux") {
}
}
checkIfConfigExists();
injectElectronFlags();
app.whenReady().then(async () => {
switch (await getConfig("windowStyle")) {
case "default":

View file

@ -50,8 +50,30 @@ if (window.location.href.indexOf("splash.html") > -1) {
}
});
}
/*
MIT License
// Settings info version injection (Stolen and modified from OpenAsar, mwuh ha ha ha ha >:D)
Copyright (c) 2022 GooseNest
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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.
*/
// Settings info version injection
setInterval(() => {
const host = document.getElementsByClassName("info-3pQQBb")[0];
if (!host || document.querySelector("#ac-ver")) return;

View file

@ -58,7 +58,14 @@
</select>
<p class="header">Client mod:</p>
</div>
<div class="switch">
<select name="prfmMode" id="prfmMode" class="left">
<option value="performance">Performance</option>
<option value="battery">Battery</option>
<option value="none">None</option>
</select>
<p class="header">Performance mode:</p>
</div>
<button id="save" class="center">Save settings</button>
</body>
@ -71,6 +78,7 @@
document.getElementById("mod").value = await settings.get("mods");
document.getElementById("channel").value = await settings.get("channel");
document.getElementById("theme").value = await settings.get("windowStyle");
document.getElementById("performanceMode").value = await settings.get("performanceMode");
}
loadSettings();
document.getElementById("save").addEventListener("click", function () {
@ -84,6 +92,7 @@
mods: document.getElementById("mod").value,
blurType: "acrylic",
inviteWebsocket: document.getElementById("websocket").checked,
performanceMode: document.getElementById("prfmMode").value,
doneSetup: true
});
});

View file

@ -1,6 +1,7 @@
import * as fs from "fs";
import {app, dialog} from "electron";
import path from "path";
import { defaultMaxListeners } from "events";
export var firstRun: boolean;
export var isSetup: boolean;
export var contentPath: string;
@ -42,6 +43,7 @@ export function setup() {
automaticPatches: false,
mods: "cumcord",
blurType: "acrylic",
performanceMode: "none",
inviteWebsocket: true,
doneSetup: false
};
@ -63,7 +65,45 @@ export async function injectJS(inject: string) {
document.body.appendChild(el);
}
export async function injectElectronFlags() {
// MIT License
// Copyright (c) 2022 GooseNest
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// 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.
const presets = {
'performance': `--enable-gpu-rasterization --enable-zero-copy --ignore-gpu-blocklist --enable-hardware-overlays=single-fullscreen,single-on-top,underlay --enable-features=EnableDrDc,CanvasOopRasterization,BackForwardCache:TimeToLiveInBackForwardCacheInSeconds/300/should_ignore_blocklists/true/enable_same_site/true,ThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframes,UseSkiaRenderer,WebAssemblyLazyCompilation --disable-features=Vulkan --force_high_performance_gpu`, // Performance
'battery': '--enable-features=TurnOffStreamingMediaCachingOnBattery --force_low_power_gpu' // Known to have better battery life for Chromium?
};
switch (await getConfig("performanceMode")) {
case "performance":
console.log("Performance mode enabled");
app.commandLine.appendSwitch(presets.performance);
break;
case "battery":
console.log("Battery mode enabled");
app.commandLine.appendSwitch(presets.battery);
break;
default:
console.log("No performance modes set");
}
}
//ArmCord Settings/Storage manager
export interface Settings {
@ -73,6 +113,7 @@ export interface Settings {
minimizeToTray: boolean;
automaticPatches: boolean;
mods: string;
performanceMode: string,
blurType: string;
inviteWebsocket: boolean;
doneSetup: boolean;

View file

@ -4,7 +4,7 @@
// I'm sorry for this mess but I'm not sure how to fix it.
import {BrowserWindow, shell, app, ipcMain, dialog, clipboard} from "electron";
import path from "path";
import {checkIfConfigIsBroken, firstRun, getConfig, contentPath, isSetup} from "./utils";
import {checkIfConfigIsBroken, firstRun, getConfig, contentPath, isSetup, setConfig} from "./utils";
import {registerIpc} from "./ipc";
import startServer from "./socket";
import contextMenu from "electron-context-menu";
@ -13,6 +13,7 @@ export var icon: string;
export let mainWindow: BrowserWindow;
export let inviteWindow: BrowserWindow;
let guestWindows: BrowserWindow[] = [];
var osType = os.type()
contextMenu({
showSaveImageAs: true,
@ -21,11 +22,50 @@ contextMenu({
});
async function doAfterDefiningTheWindow() {
var ignoreProtocolWarning = await getConfig("ignoreProtocolWarning");
checkIfConfigIsBroken();
registerIpc();
mainWindow.webContents.userAgent = `Mozilla/5.0 (X11; ${os.type()} ${os.arch()}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36`; //fake useragent for screenshare to work
// A little sloppy but it works :p
if (osType == 'Windows_NT') {
osType = "Windows " + os.release().split('.')[0] + " (" + os.release() + ")";
}
mainWindow.webContents.userAgent = `Mozilla/5.0 (X11; ${osType} ${os.arch()}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36`; //fake useragent for screenshare to work
mainWindow.webContents.setWindowOpenHandler(({url}) => {
shell.openExternal(url);
if (url.startsWith("https:" || url.startsWith("http:") || url.startsWith("mailto:"))) {
shell.openExternal(url);
} else {
if (ignoreProtocolWarning) {
shell.openExternal(url);
} else {
const options = {
type: "question",
buttons: ["Yes, please", "No, I don't"],
defaultId: 1,
title: url,
message: `Do you want to open ${url}?`,
detail: "This url was detected to not use normal browser protocols. It could mean that this url leads to a local program on your computer. Please check if you recognise it, before proceeding!",
checkboxLabel: "Remember my answer and ignore this warning for future sessions",
checkboxChecked: false
};
dialog.showMessageBox(mainWindow, options).then(({response, checkboxChecked}) => {
console.log(response, checkboxChecked);
if (checkboxChecked) {
if (response == 0) {
setConfig("ignoreProtocolWarning", true);
} else {
setConfig("ignoreProtocolWarning", false);
}
}
if (response == 0) {
shell.openExternal(url);
} else {
return;
}
});
}
}
return {action: "deny"};
});
mainWindow.webContents.session.webRequest.onBeforeRequest((details, callback) => {
@ -79,7 +119,7 @@ export function createCustomWindow() {
height: 350,
title: "ArmCord",
darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"),
icon: path.join(__dirname, "../", "/assets/ac_icon_transparent.png"),
frame: false,
autoHideMenuBar: true,
webPreferences: {
@ -95,7 +135,7 @@ export function createNativeWindow() {
height: 350,
title: "ArmCord",
darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"),
icon: path.join(__dirname, "../", "/assets/ac_icon_transparent.png"),
frame: true,
autoHideMenuBar: true,
webPreferences: {
@ -117,7 +157,7 @@ export function createTabsHost() {
height: 350,
title: "ArmCord",
darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"),
icon: path.join(__dirname, "../", "/assets/ac_icon_transparent.png"),
frame: true,
autoHideMenuBar: true,
webPreferences: {
@ -146,7 +186,7 @@ export function createTabsGuest(number: number) {
height: 600,
title: "ArmCord Guest Window " + number,
darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"),
icon: path.join(__dirname, "../", "/assets/ac_icon_transparent.png"),
frame: true,
autoHideMenuBar: true,
webPreferences: {
@ -183,7 +223,7 @@ export function createInviteWindow() {
height: 600,
title: "ArmCord Invite Manager",
darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"),
icon: path.join(__dirname, "../", "/assets/ac_icon_transparent.png"),
frame: true,
autoHideMenuBar: true,
webPreferences: {