mirror of
https://github.com/smartfrigde/armcord.git
synced 2024-08-14 23:56:58 +00:00
Compare commits
18 commits
d40b76719a
...
e6df2b0ecf
Author | SHA1 | Date | |
---|---|---|---|
|
e6df2b0ecf | ||
|
d7a318d5c3 | ||
|
afa83c782d | ||
|
a4968e7529 | ||
|
ed775cbf31 | ||
|
c5ce910940 | ||
|
bea251634c | ||
|
fbeffdb166 | ||
|
17c05fedd3 | ||
|
ddac01ee8f | ||
|
beaa993e39 | ||
|
598ac2eb2f | ||
|
235015bd24 | ||
|
35b86b92e3 | ||
|
ac806fffb7 | ||
|
3b571f2322 | ||
|
a0e0f6a516 | ||
|
0bd294480d |
36 changed files with 1809 additions and 527 deletions
42
.github/workflows/dev.yml
vendored
42
.github/workflows/dev.yml
vendored
|
@ -113,11 +113,44 @@ jobs:
|
|||
with:
|
||||
name: ArmCordWindows.zip
|
||||
path: dist/ArmCord-3.1.0-win.zip
|
||||
|
||||
build-windowsOnARM:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set architecture
|
||||
run: set npm_config_arch=arm64
|
||||
|
||||
- uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json
|
||||
|
||||
- name: Install Node dependencies
|
||||
run: pnpm install -g cargo-cp-artifact && pnpm install
|
||||
|
||||
- name: Install Electron-Builder
|
||||
run: pnpm install -g electron-builder
|
||||
|
||||
- name: Replace the version number
|
||||
run: (Get-Content src/utils.ts) -replace "\d\.\d\.\d", "DEV" | Out-File src/utils.ts
|
||||
|
||||
- name: Build
|
||||
run: npm run build && electron-builder --windows zip --arm64
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ArmCordWindowsArm64.zip
|
||||
path: dist\ArmCord-3.1.0-arm64-win.zip
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-linux, build-mac, build-windows]
|
||||
needs: [build-linux, build-mac, build-windows, build-windowsOnARM]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
@ -142,6 +175,10 @@ jobs:
|
|||
with:
|
||||
name: ArmCordLinuxArm64.zip
|
||||
path: linux
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: ArmCordWindowsArm64.zip
|
||||
path: windows
|
||||
|
||||
- name: Get some values needed for the release
|
||||
id: vars
|
||||
|
@ -171,3 +208,4 @@ jobs:
|
|||
linux/ArmCord-3.1.0-arm64.zip
|
||||
macos/ArmCord-3.1.0-mac.zip
|
||||
windows/ArmCord-3.1.0-win.zip
|
||||
windows/ArmCord-3.1.0-arm64-win.zip
|
||||
|
|
38
.github/workflows/winArm.yml
vendored
38
.github/workflows/winArm.yml
vendored
|
@ -1,38 +0,0 @@
|
|||
name: Windows on ARM
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
jobs:
|
||||
build-windowsOnARM:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install pnpm
|
||||
run: npm i -g pnpm && pnpm setup
|
||||
- name: Set architecture
|
||||
run: set npm_config_arch=arm64
|
||||
- name: Install Node dependencies
|
||||
run: pnpm install -g cargo-cp-artifact && pnpm install
|
||||
|
||||
- name: Install Electron-Builder
|
||||
run: pnpm install -g electron-builder
|
||||
|
||||
- name: Build
|
||||
run: npm run build && electron-builder --windows --arm64
|
||||
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/
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname $0)/_/husky.sh"
|
||||
set -e
|
||||
|
||||
npm run format
|
||||
git add -A
|
1
.husky/.gitignore
vendored
1
.husky/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
_
|
|
@ -1,3 +1,3 @@
|
|||
node-linker=hoisted
|
||||
public-hoist-pattern=*
|
||||
shamefully-hoist=true
|
||||
shamefully-hoist=true
|
13
.vscode/launch.json
vendored
13
.vscode/launch.json
vendored
|
@ -9,14 +9,9 @@
|
|||
"request": "launch",
|
||||
"name": "Debug ArmCord via NPM",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"start",
|
||||
"debug",
|
||||
],
|
||||
"runtimeArgs": ["start", "debug"],
|
||||
"port": 9229,
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
]
|
||||
},
|
||||
"skipFiles": ["<node_internals>/**"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
- **Various mods built in**
|
||||
|
||||
Enjoy Cumcord, GooseMod, Flicker, and their many features, or have a more vanilla experience, it's your choice!
|
||||
Enjoy Vencord, Shelter and their many features, or have a more vanilla experience, it's your choice!
|
||||
|
||||
|
||||
- **Made for Privacy™**
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
"settings-channel-desc3": "this is alpha test release of Discord. By using it you gain access to the newest\n features and fixes.",
|
||||
"settings-channel-desc4": "public test build. Receives features earlier than stable but is a bit older than Canary.",
|
||||
"settings-channel-desc5": "unofficial instance of Discord that takes you back to 2016! Only client mod\n available to run alongside with it is Cordwood. It's run by community, so you take all the risk by\n using it.",
|
||||
"settings-invitewebsocket": "Invite Websocket",
|
||||
"settings-invitewebsocket-desc": "When enabled ArmCord will support Discord.gg links which means that if you open an invite link in your\n browser, ArmCord will automatically accept the invite. Can be unresponsive at times.",
|
||||
"settings-invitewebsocket": "Rich Presence (Experimental)",
|
||||
"settings-invitewebsocket-desc": "Uses <a target=\"_blank\" href=\"https://github.com/OpenAsar/arrpc\">arRPC</a> to support Discord RPC (Rich Presence) with local programs on your machine. Work in progress.",
|
||||
"settings-altPaste": "Alternative Paste",
|
||||
"settings-altPaste-desc": "If you're on Gnome on Linux or just simply can't paste images copied from other messages, then this is\n for you. This enables alternative module for pasting images. Only enable this when you're experiencing\n issues.",
|
||||
"settings-mod": "Client mod",
|
||||
|
|
572
log.txt
Normal file
572
log.txt
Normal file
|
@ -0,0 +1,572 @@
|
|||
|
||||
> ArmCord@3.1.0 start
|
||||
> npm run build && electron ./ts-out/main.js
|
||||
|
||||
|
||||
> ArmCord@3.1.0 build
|
||||
> tsc && copyfiles -u 1 src/**/*.html src/**/**/*.css src/**/**/*.js ts-out/ && copyfiles package.json ts-out/ && copyfiles assets/**/** ts-out/
|
||||
|
||||
[Config manager] doneSetup: undefined
|
||||
[Config manager] performanceMode: none
|
||||
ArmCord has been run before. Skipping setup.
|
||||
No performance modes set
|
||||
[Config manager] windowStyle: default
|
||||
[Config manager] armcordCSP: true
|
||||
[Config manager] doneSetup: undefined
|
||||
[Config manager] customIcon: undefined
|
||||
Setting up CSP unstricter...
|
||||
[Config manager] mods: vencord
|
||||
[Config manager] trayIcon: default
|
||||
[Config manager] windowStyle: default
|
||||
[Config manager] windowStyle: default
|
||||
[Config manager] ignoreProtocolWarning: undefined
|
||||
[Config manager] clientName: undefined
|
||||
[Config manager] 0: undefined
|
||||
[Config manager] mods: vencord
|
||||
[Config manager] noBundleUpdates: undefined
|
||||
[Config manager] mobileMode: false
|
||||
Downloading mod bundle
|
||||
[Config manager] mods: vencord
|
||||
[Config manager] trayIcon: default
|
||||
[Mod loader] Loaded ArmCord Mod Loader made by Vendicated
|
||||
[Config manager] alternativePaste: false
|
||||
undefined
|
||||
[Config manager] inviteWebsocket: true
|
||||
[Config manager] skipSplash: undefined
|
||||
[[38;2;88;101;242marRPC[0m] arRPC v1.1.0-beta ArmCord
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] checking /run/user/1000/discord-ipc-0
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;87;242;135mbridge[0m] listening on 1337
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] checked if socket is available: true
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] listening at /run/user/1000/discord-ipc-0
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;235;69;158mwebsocket[0m] trying port 6463
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;235;69;158mwebsocket[0m] listening on 6463
|
||||
[Config manager] channel: stable
|
||||
[Config manager] mods: vencord
|
||||
[Config manager] automaticPatches: false
|
||||
[Config manager] channel: stable
|
||||
[Window state manager] width: 1920
|
||||
[Window state manager] height: 1048
|
||||
[Window state manager] isMaximized: true
|
||||
[Config manager] channel: stable
|
||||
[Config manager] mods: vencord
|
||||
[Config manager] automaticPatches: false
|
||||
[Config manager] channel: stable
|
||||
[Config manager] mobileMode: false
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] new connection!
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] handshake: { v: 1, client_id: '383226320970055681' }
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] sending { cmd: 'DISPATCH', evt: 'READY', data: { v: 1 } }
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '4d2717f7-8fae-4339-222a-800a0e43f023'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'ed60da61-58bc-4e12-0fc3-c628a710cf7d'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;87;242;135mbridge[0m] fetched app info for 383226320970055681 {
|
||||
id: '383226320970055681',
|
||||
name: 'Visual Studio Code',
|
||||
icon: 'bc45e1c85351ce0bafcb9245b3762e75',
|
||||
description: '',
|
||||
summary: '',
|
||||
type: null,
|
||||
cover_image: 'f1794a9f863d86c4a80aa51c3738fe58',
|
||||
hook: true,
|
||||
verify_key: 'd9fda69a8c8a9168d7fc41738822738eb31a4975a261d3172835df3595203f99',
|
||||
flags: 0,
|
||||
assets: [
|
||||
{ id: '565944082250334228', type: 1, name: 'applescript' },
|
||||
{ id: '565944082258722817', type: 1, name: 'arduino' },
|
||||
{ id: '565944082266849297', type: 1, name: 'cshtml' },
|
||||
{ id: '565944082271305778', type: 1, name: 'ahk' },
|
||||
{ id: '565944082317312000', type: 1, name: 'assembly' },
|
||||
{ id: '565944082321637386', type: 1, name: 'android' },
|
||||
{ id: '565944082329763843', type: 1, name: 'csharp' },
|
||||
{ id: '565944082384551955', type: 1, name: 'cmake' },
|
||||
{ id: '565944082392940584', type: 1, name: 'autoit' },
|
||||
{ id: '565944082401198090', type: 1, name: 'c' },
|
||||
{ id: '565944082409455626', type: 1, name: 'angular' },
|
||||
{ id: '565944082417975296', type: 1, name: 'asp' },
|
||||
{ id: '565944082501861376', type: 1, name: 'appveyor' },
|
||||
{ id: '565944082506055681', type: 1, name: 'crystal' },
|
||||
{ id: '565944082510249984', type: 1, name: 'cpp' },
|
||||
{ id: '565944082522963968', type: 1, name: 'cargo' },
|
||||
{ id: '565944082573295616', type: 1, name: 'cssmap' },
|
||||
{ id: '565944082585878538', type: 1, name: 'css' },
|
||||
{ id: '565944082816565284', type: 1, name: 'bower' },
|
||||
{ id: '565944082833342465', type: 1, name: 'clojure' },
|
||||
{ id: '565944082858377220', type: 1, name: 'circleci' },
|
||||
{ id: '565944082992726027', type: 1, name: 'as' },
|
||||
{ id: '565944083021955093', type: 1, name: 'coffee' },
|
||||
{ id: '565944083088932884', type: 1, name: 'bat' },
|
||||
{ id: '565944083441516564', type: 1, name: 'brainfuck' },
|
||||
{ id: '565944476732882948', type: 1, name: 'dart' },
|
||||
{ id: '565944476829351967', type: 1, name: 'elixir' },
|
||||
{ id: '565944476879683585', type: 1, name: 'eslint' },
|
||||
{ id: '565944477068296243', type: 1, name: 'haskell' },
|
||||
{ id: '565944477076684801', type: 1, name: 'go' },
|
||||
{ id: '565944477085073418', type: 1, name: 'dm' },
|
||||
{ id: '565944477122822179', type: 1, name: 'flowconfig' },
|
||||
{ id: '565944477152444416', type: 1, name: 'fsharp' },
|
||||
{ id: '565944477202645033', type: 1, name: 'erlang' },
|
||||
{ id: '565944477215358986', type: 1, name: 'gemfile' },
|
||||
{ id: '565944477232136192', type: 1, name: 'd' },
|
||||
{ id: '565944477232136202', type: 1, name: 'git' },
|
||||
{ id: '565944477278142465', type: 1, name: 'haxe' },
|
||||
{ id: '565944477286531072', type: 1, name: 'graphql' },
|
||||
{ id: '565944477328343040', type: 1, name: 'docker' },
|
||||
{ id: '565944477336993822', type: 1, name: 'firebase' },
|
||||
{ id: '565944477340926001', type: 1, name: 'editorconfig' },
|
||||
{ id: '565944477647241228', type: 1, name: 'delphi' },
|
||||
{ id: '565944477684989977', type: 1, name: 'handlebars' },
|
||||
{ id: '565944477752098836', type: 1, name: 'gulp' },
|
||||
{ id: '565944477961814016', type: 1, name: 'cuda' },
|
||||
{ id: '565944478142169089', type: 1, name: 'gatsbyjs' },
|
||||
{ id: '565944478418993152', type: 1, name: 'gradle' },
|
||||
{ id: '565944478549016577', type: 1, name: 'env' },
|
||||
{ id: '565944478557274142', type: 1, name: 'ejs' },
|
||||
{ id: '565944478792155136', type: 1, name: 'elm' },
|
||||
{ id: '565944479194808320', type: 1, name: 'gruntfile' },
|
||||
{ id: '565944799245369386', type: 1, name: 'makefile' },
|
||||
{ id: '565944799312740364', type: 1, name: 'less' },
|
||||
{ id: '565944799446827009', type: 1, name: 'julia' },
|
||||
{ id: '565944799450890240', type: 1, name: 'jar' },
|
||||
{ id: '565944799455346703', type: 1, name: 'html' },
|
||||
{ id: '565944799459278879', type: 1, name: 'jsmap' },
|
||||
{ id: '565944799492964353', type: 1, name: 'kotlin' },
|
||||
{ id: '565944799538970634', type: 1, name: 'heroku' },
|
||||
{ id: '565944799576719366', type: 1, name: 'js' },
|
||||
{ id: '565944799618662400', type: 1, name: 'livescript' },
|
||||
{ id: '565944799707004929', type: 1, name: 'log' },
|
||||
{ id: '565944799761268737', type: 1, name: 'json' },
|
||||
{ id: '565944799761268766', type: 1, name: 'jest' },
|
||||
{ id: '565944799996411914', type: 1, name: 'http' },
|
||||
{ id: '565944800021446707', type: 1, name: 'java' },
|
||||
{ id: '565944800021577729', type: 1, name: 'lisp' },
|
||||
{ id: '565944800105332777', type: 1, name: 'lua' },
|
||||
{ id: '565944802462531603', type: 1, name: 'jsx' },
|
||||
{ id: '565945077252489228', type: 1, name: 'nim' },
|
||||
{ id: '565945077260746763', type: 1, name: 'pascal' },
|
||||
{ id: '565945077277655043', type: 1, name: 'perl' },
|
||||
{ id: '565945077323792386', type: 1, name: 'postcss' },
|
||||
{ id: '565945077348958236', type: 1, name: 'marko' },
|
||||
{ id: '565945077411741717', type: 1, name: 'prisma' },
|
||||
{ id: '565945077487108099', type: 1, name: 'nodemon' },
|
||||
{ id: '565945077491433494', type: 1, name: 'markdown' },
|
||||
{ id: '565945077524987927', type: 1, name: 'markdownx' },
|
||||
{ id: '565945077554479114', type: 1, name: 'manifest' },
|
||||
{ id: '565945077575319552', type: 1, name: 'pawn' },
|
||||
{ id: '565945077583839243', type: 1, name: 'npm' },
|
||||
{ id: '565945077625651200', type: 1, name: 'pug' },
|
||||
{ id: '565945077642559498', type: 1, name: 'ocaml' },
|
||||
{ id: '565945077709406209', type: 1, name: 'prettier' },
|
||||
{ id: '565945078166716458', type: 1, name: 'powershell' },
|
||||
{ id: '565945078359785494', type: 1, name: 'objc' },
|
||||
{ id: '565945078833741834', type: 1, name: 'php' },
|
||||
{ id: '565945350532104193', type: 1, name: 'tex' },
|
||||
{ id: '565945350641418270', type: 1, name: 'reasonml' },
|
||||
{ id: '565945350645481492', type: 1, name: 'python' },
|
||||
{ id: '565945350670647298', type: 1, name: 'swift' },
|
||||
{ id: '565945350695813133', type: 1, name: 'scala' },
|
||||
{ id: '565945350766985216', type: 1, name: 'svg' },
|
||||
{ id: '565945350771441676', type: 1, name: 'rust' },
|
||||
{ id: '565945350792151064', type: 1, name: 'toml' },
|
||||
{ id: '565945350838419490', type: 1, name: 'sql' },
|
||||
{ id: '565945350846939145', type: 1, name: 'text' },
|
||||
{ id: '565945350851002389', type: 1, name: 'shell' },
|
||||
{ id: '565945350897008640', type: 1, name: 'scss' },
|
||||
... 50 more items
|
||||
]
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;87;242;135mbridge[0m] fetched app info for 383226320970055681 {
|
||||
id: '383226320970055681',
|
||||
name: 'Visual Studio Code',
|
||||
icon: 'bc45e1c85351ce0bafcb9245b3762e75',
|
||||
description: '',
|
||||
summary: '',
|
||||
type: null,
|
||||
cover_image: 'f1794a9f863d86c4a80aa51c3738fe58',
|
||||
hook: true,
|
||||
verify_key: 'd9fda69a8c8a9168d7fc41738822738eb31a4975a261d3172835df3595203f99',
|
||||
flags: 0,
|
||||
assets: [
|
||||
{ id: '565944082250334228', type: 1, name: 'applescript' },
|
||||
{ id: '565944082258722817', type: 1, name: 'arduino' },
|
||||
{ id: '565944082266849297', type: 1, name: 'cshtml' },
|
||||
{ id: '565944082271305778', type: 1, name: 'ahk' },
|
||||
{ id: '565944082317312000', type: 1, name: 'assembly' },
|
||||
{ id: '565944082321637386', type: 1, name: 'android' },
|
||||
{ id: '565944082329763843', type: 1, name: 'csharp' },
|
||||
{ id: '565944082384551955', type: 1, name: 'cmake' },
|
||||
{ id: '565944082392940584', type: 1, name: 'autoit' },
|
||||
{ id: '565944082401198090', type: 1, name: 'c' },
|
||||
{ id: '565944082409455626', type: 1, name: 'angular' },
|
||||
{ id: '565944082417975296', type: 1, name: 'asp' },
|
||||
{ id: '565944082501861376', type: 1, name: 'appveyor' },
|
||||
{ id: '565944082506055681', type: 1, name: 'crystal' },
|
||||
{ id: '565944082510249984', type: 1, name: 'cpp' },
|
||||
{ id: '565944082522963968', type: 1, name: 'cargo' },
|
||||
{ id: '565944082573295616', type: 1, name: 'cssmap' },
|
||||
{ id: '565944082585878538', type: 1, name: 'css' },
|
||||
{ id: '565944082816565284', type: 1, name: 'bower' },
|
||||
{ id: '565944082833342465', type: 1, name: 'clojure' },
|
||||
{ id: '565944082858377220', type: 1, name: 'circleci' },
|
||||
{ id: '565944082992726027', type: 1, name: 'as' },
|
||||
{ id: '565944083021955093', type: 1, name: 'coffee' },
|
||||
{ id: '565944083088932884', type: 1, name: 'bat' },
|
||||
{ id: '565944083441516564', type: 1, name: 'brainfuck' },
|
||||
{ id: '565944476732882948', type: 1, name: 'dart' },
|
||||
{ id: '565944476829351967', type: 1, name: 'elixir' },
|
||||
{ id: '565944476879683585', type: 1, name: 'eslint' },
|
||||
{ id: '565944477068296243', type: 1, name: 'haskell' },
|
||||
{ id: '565944477076684801', type: 1, name: 'go' },
|
||||
{ id: '565944477085073418', type: 1, name: 'dm' },
|
||||
{ id: '565944477122822179', type: 1, name: 'flowconfig' },
|
||||
{ id: '565944477152444416', type: 1, name: 'fsharp' },
|
||||
{ id: '565944477202645033', type: 1, name: 'erlang' },
|
||||
{ id: '565944477215358986', type: 1, name: 'gemfile' },
|
||||
{ id: '565944477232136192', type: 1, name: 'd' },
|
||||
{ id: '565944477232136202', type: 1, name: 'git' },
|
||||
{ id: '565944477278142465', type: 1, name: 'haxe' },
|
||||
{ id: '565944477286531072', type: 1, name: 'graphql' },
|
||||
{ id: '565944477328343040', type: 1, name: 'docker' },
|
||||
{ id: '565944477336993822', type: 1, name: 'firebase' },
|
||||
{ id: '565944477340926001', type: 1, name: 'editorconfig' },
|
||||
{ id: '565944477647241228', type: 1, name: 'delphi' },
|
||||
{ id: '565944477684989977', type: 1, name: 'handlebars' },
|
||||
{ id: '565944477752098836', type: 1, name: 'gulp' },
|
||||
{ id: '565944477961814016', type: 1, name: 'cuda' },
|
||||
{ id: '565944478142169089', type: 1, name: 'gatsbyjs' },
|
||||
{ id: '565944478418993152', type: 1, name: 'gradle' },
|
||||
{ id: '565944478549016577', type: 1, name: 'env' },
|
||||
{ id: '565944478557274142', type: 1, name: 'ejs' },
|
||||
{ id: '565944478792155136', type: 1, name: 'elm' },
|
||||
{ id: '565944479194808320', type: 1, name: 'gruntfile' },
|
||||
{ id: '565944799245369386', type: 1, name: 'makefile' },
|
||||
{ id: '565944799312740364', type: 1, name: 'less' },
|
||||
{ id: '565944799446827009', type: 1, name: 'julia' },
|
||||
{ id: '565944799450890240', type: 1, name: 'jar' },
|
||||
{ id: '565944799455346703', type: 1, name: 'html' },
|
||||
{ id: '565944799459278879', type: 1, name: 'jsmap' },
|
||||
{ id: '565944799492964353', type: 1, name: 'kotlin' },
|
||||
{ id: '565944799538970634', type: 1, name: 'heroku' },
|
||||
{ id: '565944799576719366', type: 1, name: 'js' },
|
||||
{ id: '565944799618662400', type: 1, name: 'livescript' },
|
||||
{ id: '565944799707004929', type: 1, name: 'log' },
|
||||
{ id: '565944799761268737', type: 1, name: 'json' },
|
||||
{ id: '565944799761268766', type: 1, name: 'jest' },
|
||||
{ id: '565944799996411914', type: 1, name: 'http' },
|
||||
{ id: '565944800021446707', type: 1, name: 'java' },
|
||||
{ id: '565944800021577729', type: 1, name: 'lisp' },
|
||||
{ id: '565944800105332777', type: 1, name: 'lua' },
|
||||
{ id: '565944802462531603', type: 1, name: 'jsx' },
|
||||
{ id: '565945077252489228', type: 1, name: 'nim' },
|
||||
{ id: '565945077260746763', type: 1, name: 'pascal' },
|
||||
{ id: '565945077277655043', type: 1, name: 'perl' },
|
||||
{ id: '565945077323792386', type: 1, name: 'postcss' },
|
||||
{ id: '565945077348958236', type: 1, name: 'marko' },
|
||||
{ id: '565945077411741717', type: 1, name: 'prisma' },
|
||||
{ id: '565945077487108099', type: 1, name: 'nodemon' },
|
||||
{ id: '565945077491433494', type: 1, name: 'markdown' },
|
||||
{ id: '565945077524987927', type: 1, name: 'markdownx' },
|
||||
{ id: '565945077554479114', type: 1, name: 'manifest' },
|
||||
{ id: '565945077575319552', type: 1, name: 'pawn' },
|
||||
{ id: '565945077583839243', type: 1, name: 'npm' },
|
||||
{ id: '565945077625651200', type: 1, name: 'pug' },
|
||||
{ id: '565945077642559498', type: 1, name: 'ocaml' },
|
||||
{ id: '565945077709406209', type: 1, name: 'prettier' },
|
||||
{ id: '565945078166716458', type: 1, name: 'powershell' },
|
||||
{ id: '565945078359785494', type: 1, name: 'objc' },
|
||||
{ id: '565945078833741834', type: 1, name: 'php' },
|
||||
{ id: '565945350532104193', type: 1, name: 'tex' },
|
||||
{ id: '565945350641418270', type: 1, name: 'reasonml' },
|
||||
{ id: '565945350645481492', type: 1, name: 'python' },
|
||||
{ id: '565945350670647298', type: 1, name: 'swift' },
|
||||
{ id: '565945350695813133', type: 1, name: 'scala' },
|
||||
{ id: '565945350766985216', type: 1, name: 'svg' },
|
||||
{ id: '565945350771441676', type: 1, name: 'rust' },
|
||||
{ id: '565945350792151064', type: 1, name: 'toml' },
|
||||
{ id: '565945350838419490', type: 1, name: 'sql' },
|
||||
{ id: '565945350846939145', type: 1, name: 'text' },
|
||||
{ id: '565945350851002389', type: 1, name: 'shell' },
|
||||
{ id: '565945350897008640', type: 1, name: 'scss' },
|
||||
... 50 more items
|
||||
]
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'b3d5dd03-d425-40ae-132e-8acf53b18497'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'a81c11d1-60e8-4c23-2af3-6626c0791f1a'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '3230ba41-4874-460a-1689-9b9ff1663a7f'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'f6d973b1-1e75-4dd6-2e93-b65a9ef3be0b'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'b8843cb1-aa6e-437d-3da0-1e08cd44cfb5'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'd6a257e0-fa89-449f-38b1-44fa71811fb7'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'ac9e04a8-52c3-4614-04b2-1779e10e263f'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
details: 'Idling',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'f0e4d6e4-7aa8-4f5b-1264-ac76680cfd24'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing server.js',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '3cc9be1b-338f-4867-1cf0-cba574084c45'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing server.js',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'd4965762-a25b-4b8b-2891-11a1ed78289d'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '92243961-65fb-48a2-26d1-1d8980a376f3'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '4d1001fa-6d04-4b0a-0d0d-4ceefd1c79f0'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '1cb43f39-5cd6-40aa-385b-16fd9fe70d4f'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '1b139214-f410-48bc-24d4-2835d2d49f02'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '442a6b6a-126d-435d-2a85-296ec86c36a8'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: 'a0517d56-4927-4761-2642-699fd091dc0c'
|
||||
}
|
||||
[[38;2;88;101;242marRPC[0m > [38;2;254;231;92mipc[0m] message {
|
||||
cmd: 'SET_ACTIVITY',
|
||||
args: {
|
||||
pid: 5707,
|
||||
activity: {
|
||||
state: 'Workspace: ArmCord',
|
||||
details: 'Editing log.txt',
|
||||
timestamps: [Object],
|
||||
assets: [Object],
|
||||
buttons: [Array],
|
||||
instance: false
|
||||
}
|
||||
},
|
||||
nonce: '8c63a412-f861-49e9-288e-e31765f7c36b'
|
||||
}
|
||||
[Config manager] minimizeToTray: true
|
148
package.json
148
package.json
|
@ -1,80 +1,76 @@
|
|||
{
|
||||
"name": "ArmCord",
|
||||
"version": "3.1.0",
|
||||
"description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.",
|
||||
"main": "ts-out/main.js",
|
||||
"scripts": {
|
||||
"build": "tsc && copyfiles -u 1 src/**/*.html src/**/**/*.css ts-out/ && copyfiles package.json ts-out/ && copyfiles assets/**/** ts-out/",
|
||||
"watch": "tsc -w",
|
||||
"start": "npm run build && electron ./ts-out/main.js",
|
||||
"startNoSandbox": "npm run build && electron ./ts-out/main.js --no-sandbox",
|
||||
"package": "npm run build && electron-builder",
|
||||
"packageQuick": "npm run build && electron-builder --dir",
|
||||
"format": "prettier --write src/**/*",
|
||||
"CIbuild": "npm run build && electron-builder --linux zip && electron-builder --windows zip && electron-builder --macos zip",
|
||||
"postinstall": "husky install",
|
||||
"precommit-fix": "husky uninstall && echo - && echo !Make sure to run 'npm run format' before commiting! | chalk --stdin yellow inverse && echo -",
|
||||
"precommit-fix:format": "husky uninstall && npm run format"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/armcord/armcord.git"
|
||||
},
|
||||
"author": "smartfrigde",
|
||||
"license": "OSL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/armcord/armcord/issues"
|
||||
},
|
||||
"homepage": "https://github.com/armcord/armcord#readme",
|
||||
"devDependencies": {
|
||||
"@types/node": "^17.0.42",
|
||||
"@types/node-fetch": "^2.6.2",
|
||||
"@types/ws": "^8.5.3",
|
||||
"chalk-cli": "^5.0.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"electron": "^20.1.0",
|
||||
"electron-builder": "^23.6.0",
|
||||
"husky": "^8.0.1",
|
||||
"prettier": "^2.7.0",
|
||||
"typescript": "^4.7.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pyke/vibe": "github:pykeio/vibe#11984868ce9e007859ed91ff159c7f7f0a34e7ae",
|
||||
"electron-context-menu": "github:ArmCord/electron-context-menu",
|
||||
"extract-zip": "^2.0.1",
|
||||
"node-fetch": "v2",
|
||||
"os-locale": "^6.0.2",
|
||||
"v8-compile-cache": "^2.3.0",
|
||||
"ws": "^8.8.0"
|
||||
},
|
||||
"build": {
|
||||
"nsis": {
|
||||
"include": "build/installer.nsh"
|
||||
"name": "ArmCord",
|
||||
"version": "3.1.0",
|
||||
"description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.",
|
||||
"main": "ts-out/main.js",
|
||||
"scripts": {
|
||||
"build": "tsc && copyfiles -u 1 src/**/*.html src/**/**/*.css src/**/**/*.js ts-out/ && copyfiles package.json ts-out/ && copyfiles assets/**/** ts-out/",
|
||||
"watch": "tsc -w",
|
||||
"start": "npm run build && electron ./ts-out/main.js",
|
||||
"startNoSandbox": "npm run build && electron ./ts-out/main.js --no-sandbox",
|
||||
"package": "npm run build && electron-builder",
|
||||
"packageQuick": "npm run build && electron-builder --dir",
|
||||
"format": "prettier --write src *.json",
|
||||
"CIbuild": "npm run build && electron-builder --linux zip && electron-builder --windows zip && electron-builder --macos zip",
|
||||
"prepare": "git config --local core.hooksPath .hooks/"
|
||||
},
|
||||
"files": [
|
||||
"!*",
|
||||
"assets",
|
||||
"node_modules",
|
||||
"ts-out",
|
||||
"package.json",
|
||||
"LICENSE"
|
||||
],
|
||||
"appId": "com.smartfridge.armcord",
|
||||
"productName": "ArmCord",
|
||||
"mac": {
|
||||
"category": "Network"
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/armcord/armcord.git"
|
||||
},
|
||||
"linux": {
|
||||
"icon": "build/icon.icns",
|
||||
"category": "Network",
|
||||
"maintainer": "smartfridge@vivaldi.net",
|
||||
"target": [
|
||||
"deb",
|
||||
"tar.gz",
|
||||
"rpm",
|
||||
"AppImage"
|
||||
]
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@7.13.4"
|
||||
"author": "smartfrigde",
|
||||
"license": "OSL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/armcord/armcord/issues"
|
||||
},
|
||||
"homepage": "https://github.com/armcord/armcord#readme",
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/ws": "^8.5.3",
|
||||
"chalk-cli": "^5.0.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"electron": "^21.3.0",
|
||||
"electron-builder": "^23.6.0",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pyke/vibe": "github:pykeio/vibe#11984868ce9e007859ed91ff159c7f7f0a34e7ae",
|
||||
"arrpc": "file:src/arrpc",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"electron-context-menu": "github:ArmCord/electron-context-menu",
|
||||
"extract-zip": "^2.0.1",
|
||||
"v8-compile-cache": "^2.3.0",
|
||||
"ws": "^8.11.0"
|
||||
},
|
||||
"build": {
|
||||
"nsis": {
|
||||
"include": "build/installer.nsh"
|
||||
},
|
||||
"files": [
|
||||
"!*",
|
||||
"assets",
|
||||
"node_modules",
|
||||
"ts-out",
|
||||
"package.json",
|
||||
"LICENSE"
|
||||
],
|
||||
"appId": "com.smartfridge.armcord",
|
||||
"productName": "ArmCord",
|
||||
"mac": {
|
||||
"category": "Network"
|
||||
},
|
||||
"linux": {
|
||||
"icon": "build/icon.icns",
|
||||
"category": "Network",
|
||||
"maintainer": "smartfridge@vivaldi.net",
|
||||
"target": [
|
||||
"deb",
|
||||
"tar.gz",
|
||||
"rpm",
|
||||
"AppImage"
|
||||
]
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@7.13.4"
|
||||
}
|
||||
|
|
193
pnpm-lock.yaml
193
pnpm-lock.yaml
|
@ -2,43 +2,39 @@ lockfileVersion: 5.4
|
|||
|
||||
specifiers:
|
||||
'@pyke/vibe': github:pykeio/vibe#11984868ce9e007859ed91ff159c7f7f0a34e7ae
|
||||
'@types/node': ^17.0.42
|
||||
'@types/node-fetch': ^2.6.2
|
||||
'@types/node': ^18.11.9
|
||||
'@types/ws': ^8.5.3
|
||||
arrpc: file:src/arrpc
|
||||
chalk-cli: ^5.0.0
|
||||
copyfiles: ^2.4.1
|
||||
electron: ^20.1.0
|
||||
cross-fetch: ^3.1.5
|
||||
electron: ^21.3.0
|
||||
electron-builder: ^23.6.0
|
||||
electron-context-menu: github:ArmCord/electron-context-menu
|
||||
extract-zip: ^2.0.1
|
||||
husky: ^8.0.1
|
||||
node-fetch: v2
|
||||
os-locale: ^6.0.2
|
||||
prettier: ^2.7.0
|
||||
typescript: ^4.7.3
|
||||
prettier: ^2.7.1
|
||||
typescript: ^4.9.3
|
||||
v8-compile-cache: ^2.3.0
|
||||
ws: ^8.8.0
|
||||
ws: ^8.11.0
|
||||
|
||||
dependencies:
|
||||
'@pyke/vibe': github.com/pykeio/vibe/11984868ce9e007859ed91ff159c7f7f0a34e7ae_electron@20.3.1
|
||||
'@pyke/vibe': github.com/pykeio/vibe/11984868ce9e007859ed91ff159c7f7f0a34e7ae_electron@21.3.0
|
||||
arrpc: file:src/arrpc
|
||||
cross-fetch: 3.1.5
|
||||
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
|
||||
v8-compile-cache: 2.3.0
|
||||
ws: 8.9.0
|
||||
ws: 8.11.0
|
||||
|
||||
devDependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node-fetch': 2.6.2
|
||||
'@types/node': 18.11.9
|
||||
'@types/ws': 8.5.3
|
||||
chalk-cli: 5.0.0
|
||||
copyfiles: 2.4.1
|
||||
electron: 20.3.1
|
||||
electron: 21.3.0
|
||||
electron-builder: 23.6.0
|
||||
husky: 8.0.1
|
||||
prettier: 2.7.1
|
||||
typescript: 4.8.4
|
||||
typescript: 4.9.3
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -150,7 +146,7 @@ packages:
|
|||
/@types/fs-extra/9.0.13:
|
||||
resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 18.11.9
|
||||
dev: true
|
||||
|
||||
/@types/glob/7.2.0:
|
||||
|
@ -158,14 +154,14 @@ packages:
|
|||
requiresBuild: true
|
||||
dependencies:
|
||||
'@types/minimatch': 5.1.2
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 18.11.9
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@types/keyv/3.1.4:
|
||||
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 18.11.9
|
||||
|
||||
/@types/minimatch/5.1.2:
|
||||
resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==}
|
||||
|
@ -180,18 +176,11 @@ packages:
|
|||
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
|
||||
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.18.3:
|
||||
resolution: {integrity: sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg==}
|
||||
|
||||
/@types/node/16.11.64:
|
||||
resolution: {integrity: sha512-z5hPTlVFzNwtJ2LNozTpJcD1Cu44c4LNuzaq1mwxmiHWQh2ULdR6Vjwo1UGldzRpzL0yUEdZddnfqGW2G70z6Q==}
|
||||
|
||||
/@types/node/17.0.45:
|
||||
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
|
||||
/@types/node/18.11.9:
|
||||
resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==}
|
||||
|
||||
/@types/normalize-package-data/2.4.1:
|
||||
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
|
||||
|
@ -201,7 +190,7 @@ packages:
|
|||
resolution: {integrity: sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 18.11.9
|
||||
xmlbuilder: 15.1.1
|
||||
dev: true
|
||||
optional: true
|
||||
|
@ -209,7 +198,7 @@ packages:
|
|||
/@types/responselike/1.0.0:
|
||||
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 18.11.9
|
||||
|
||||
/@types/verror/1.10.6:
|
||||
resolution: {integrity: sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==}
|
||||
|
@ -220,7 +209,7 @@ packages:
|
|||
/@types/ws/8.5.3:
|
||||
resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 18.11.9
|
||||
dev: true
|
||||
|
||||
/@types/yargs-parser/21.0.0:
|
||||
|
@ -237,7 +226,7 @@ packages:
|
|||
resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 18.11.9
|
||||
optional: true
|
||||
|
||||
/agent-base/6.0.2:
|
||||
|
@ -283,8 +272,8 @@ packages:
|
|||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
/ansi-styles/6.1.1:
|
||||
resolution: {integrity: sha512-qDOv24WjnYuL+wbwHdlsYZFy+cgPtrYw0Tn7GLORicQp9BkQLzrgI3Pm4VyR9ERZ41YTn7KlMPuL1n05WdZvmg==}
|
||||
/ansi-styles/6.2.1:
|
||||
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
|
@ -320,7 +309,7 @@ packages:
|
|||
read-config-file: 6.2.0
|
||||
sanitize-filename: 1.6.3
|
||||
semver: 7.3.8
|
||||
tar: 6.1.11
|
||||
tar: 6.1.12
|
||||
temp-file: 3.4.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -511,8 +500,8 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/cargo-cp-artifact/0.1.6:
|
||||
resolution: {integrity: sha512-CQw0doK/aaF7j041666XzuilHxqMxaKkn+I5vmBsd8SAwS0cO5CqVEVp0xJwOKstyqWZ6WK4Ww3O6p26x/Goyg==}
|
||||
/cargo-cp-artifact/0.1.7:
|
||||
resolution: {integrity: sha512-pxEV9p1on8vu3BOKstVisF9TwMyGKCBRvzaVpQHuU2sLULCKrn3MJWx/4XlNzmG6xNCTPf78DJ7WCGgr2mOzjg==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
|
@ -521,7 +510,7 @@ packages:
|
|||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
ansi-styles: 6.1.1
|
||||
ansi-styles: 6.2.1
|
||||
chalk: 4.1.2
|
||||
dot-prop: 6.0.1
|
||||
get-stdin: 9.0.0
|
||||
|
@ -554,8 +543,9 @@ packages:
|
|||
resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==}
|
||||
dev: true
|
||||
|
||||
/ci-info/3.4.0:
|
||||
resolution: {integrity: sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==}
|
||||
/ci-info/3.6.1:
|
||||
resolution: {integrity: sha512-up5ggbaDqOqJ4UqLKZ2naVkyqSJQgJi5lwD6b6mM748ysrghDBX0bx/qJTUHzw7zu6Mq4gycviSF5hJnwceD8w==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/cli-truncate/2.1.0:
|
||||
|
@ -607,7 +597,7 @@ packages:
|
|||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
/colors/1.0.3:
|
||||
resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==}
|
||||
resolution: {integrity: sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=}
|
||||
engines: {node: '>=0.1.90'}
|
||||
dev: true
|
||||
|
||||
|
@ -636,7 +626,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/concat-map/0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
dev: true
|
||||
|
||||
/config-chain/1.1.13:
|
||||
|
@ -677,6 +667,14 @@ packages:
|
|||
dev: true
|
||||
optional: true
|
||||
|
||||
/cross-fetch/3.1.5:
|
||||
resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
|
||||
dependencies:
|
||||
node-fetch: 2.6.7
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/cross-spawn/7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
engines: {node: '>= 8'}
|
||||
|
@ -708,8 +706,8 @@ packages:
|
|||
dependencies:
|
||||
ms: 2.1.2
|
||||
|
||||
/decamelize-keys/1.1.0:
|
||||
resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==}
|
||||
/decamelize-keys/1.1.1:
|
||||
resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
decamelize: 1.2.0
|
||||
|
@ -838,13 +836,13 @@ packages:
|
|||
lazy-val: 1.0.5
|
||||
read-config-file: 6.2.0
|
||||
simple-update-notifier: 1.0.7
|
||||
yargs: 17.6.0
|
||||
yargs: 17.6.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/electron-dl/3.3.1:
|
||||
resolution: {integrity: sha512-kmcSYZyHVEHHHFKlZWW58GiCmu2NSu3Rdwnl3+/fr/ftQYHJULVf1QkrCBPFE2bp/Ly113Za7c8wJZs1nBy04A==}
|
||||
/electron-dl/3.5.0:
|
||||
resolution: {integrity: sha512-Oj+VSuScVx8hEKM2HEvTQswTX6G3MLh7UoAz/oZuvKyNDfudNi1zY6PK/UnFoK1nCl9DF6k+3PFwElKbtZlDig==}
|
||||
dependencies:
|
||||
ext-name: 5.0.0
|
||||
pupa: 2.1.1
|
||||
|
@ -865,7 +863,7 @@ packages:
|
|||
compare-version: 0.1.2
|
||||
debug: 2.6.9
|
||||
isbinaryfile: 3.0.3
|
||||
minimist: 1.2.6
|
||||
minimist: 1.2.7
|
||||
plist: 3.0.6
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -885,14 +883,14 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/electron/20.3.1:
|
||||
resolution: {integrity: sha512-mgFAa79Zj8oCegsluPAo6O1yXd7mVMZ0JZC2Rak9HQUAQ7x9xuQY7yop/+nMbi+bOMWwe5JrtOcvjotBArxioA==}
|
||||
/electron/21.3.0:
|
||||
resolution: {integrity: sha512-MGRpshN8fBcx4IRuBABIsGDv0tB/MclIFsyFHFFXsBCUc+vIXaE/E6vuWaniGIFSz5WyeuapfTH5IeRb+7yIfw==}
|
||||
engines: {node: '>= 10.17.0'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@electron/get': 1.14.1
|
||||
'@types/node': 16.11.64
|
||||
'@types/node': 16.18.3
|
||||
extract-zip: 2.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -1008,15 +1006,6 @@ packages:
|
|||
path-exists: 4.0.0
|
||||
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:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
engines: {node: '>= 6'}
|
||||
|
@ -1227,12 +1216,6 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/husky/8.0.1:
|
||||
resolution: {integrity: sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/iconv-corefoundation/1.1.7:
|
||||
resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==}
|
||||
engines: {node: ^8.11.2 || >=10}
|
||||
|
@ -1277,11 +1260,6 @@ packages:
|
|||
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
||||
optional: true
|
||||
|
||||
/invert-kv/3.0.1:
|
||||
resolution: {integrity: sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/is-arrayish/0.2.1:
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
dev: true
|
||||
|
@ -1290,11 +1268,11 @@ packages:
|
|||
resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
ci-info: 3.4.0
|
||||
ci-info: 3.6.1
|
||||
dev: true
|
||||
|
||||
/is-core-module/2.10.0:
|
||||
resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
|
||||
/is-core-module/2.11.0:
|
||||
resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==}
|
||||
dependencies:
|
||||
has: 1.0.3
|
||||
dev: true
|
||||
|
@ -1407,13 +1385,6 @@ packages:
|
|||
resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==}
|
||||
dev: true
|
||||
|
||||
/lcid/3.1.1:
|
||||
resolution: {integrity: sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
invert-kv: 3.0.1
|
||||
dev: false
|
||||
|
||||
/lines-and-columns/1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
dev: true
|
||||
|
@ -1466,7 +1437,7 @@ packages:
|
|||
'@types/minimist': 1.2.2
|
||||
camelcase-keys: 7.0.2
|
||||
decamelize: 5.0.1
|
||||
decamelize-keys: 1.1.0
|
||||
decamelize-keys: 1.1.1
|
||||
hard-rejection: 2.1.0
|
||||
minimist-options: 4.1.0
|
||||
normalize-package-data: 3.0.3
|
||||
|
@ -1531,8 +1502,8 @@ packages:
|
|||
kind-of: 6.0.3
|
||||
dev: true
|
||||
|
||||
/minimist/1.2.6:
|
||||
resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==}
|
||||
/minimist/1.2.7:
|
||||
resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==}
|
||||
dev: true
|
||||
|
||||
/minipass/3.3.4:
|
||||
|
@ -1598,7 +1569,7 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
hosted-git-info: 4.1.0
|
||||
is-core-module: 2.10.0
|
||||
is-core-module: 2.11.0
|
||||
semver: 7.3.8
|
||||
validate-npm-package-license: 3.0.4
|
||||
dev: true
|
||||
|
@ -1625,13 +1596,6 @@ packages:
|
|||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
|
||||
/os-locale/6.0.2:
|
||||
resolution: {integrity: sha512-qIb8bzRqaN/vVqEYZ7lTAg6PonskO7xOmM7OClD28F6eFa4s5XGe4bGpHUHMoCHbNNuR0pDYFeSLiW5bnjWXIA==}
|
||||
engines: {node: '>=12.20'}
|
||||
dependencies:
|
||||
lcid: 3.1.1
|
||||
dev: false
|
||||
|
||||
/p-cancelable/1.1.0:
|
||||
resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -2013,9 +1977,9 @@ packages:
|
|||
has-flag: 4.0.0
|
||||
dev: true
|
||||
|
||||
/tar/6.1.11:
|
||||
resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==}
|
||||
engines: {node: '>= 10'}
|
||||
/tar/6.1.12:
|
||||
resolution: {integrity: sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
chownr: 2.0.0
|
||||
fs-minipass: 2.1.0
|
||||
|
@ -2086,8 +2050,8 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/typescript/4.8.4:
|
||||
resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==}
|
||||
/typescript/4.9.3:
|
||||
resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
@ -2188,8 +2152,8 @@ packages:
|
|||
/wrappy/1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
/ws/8.9.0:
|
||||
resolution: {integrity: sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==}
|
||||
/ws/8.11.0:
|
||||
resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
|
@ -2243,8 +2207,8 @@ packages:
|
|||
yargs-parser: 20.2.9
|
||||
dev: true
|
||||
|
||||
/yargs/17.6.0:
|
||||
resolution: {integrity: sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==}
|
||||
/yargs/17.6.2:
|
||||
resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
|
@ -2267,17 +2231,28 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
file:src/arrpc:
|
||||
resolution: {directory: src/arrpc, type: directory}
|
||||
name: arrpc
|
||||
version: 1.1.0
|
||||
dependencies:
|
||||
ws: 8.11.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
github.com/ArmCord/electron-context-menu/280c81398c02a063f46e3285a9708d8db1a7ce32:
|
||||
resolution: {tarball: https://codeload.github.com/ArmCord/electron-context-menu/tar.gz/280c81398c02a063f46e3285a9708d8db1a7ce32}
|
||||
name: electron-context-menu
|
||||
version: 3.5.0
|
||||
dependencies:
|
||||
cli-truncate: 2.1.0
|
||||
electron-dl: 3.3.1
|
||||
electron-dl: 3.5.0
|
||||
electron-is-dev: 2.0.0
|
||||
dev: false
|
||||
|
||||
github.com/pykeio/vibe/11984868ce9e007859ed91ff159c7f7f0a34e7ae_electron@20.3.1:
|
||||
github.com/pykeio/vibe/11984868ce9e007859ed91ff159c7f7f0a34e7ae_electron@21.3.0:
|
||||
resolution: {tarball: https://codeload.github.com/pykeio/vibe/tar.gz/11984868ce9e007859ed91ff159c7f7f0a34e7ae}
|
||||
id: github.com/pykeio/vibe/11984868ce9e007859ed91ff159c7f7f0a34e7ae
|
||||
name: '@pyke/vibe'
|
||||
|
@ -2286,6 +2261,6 @@ packages:
|
|||
peerDependencies:
|
||||
electron: '>=11.0'
|
||||
dependencies:
|
||||
cargo-cp-artifact: 0.1.6
|
||||
electron: 20.3.1
|
||||
cargo-cp-artifact: 0.1.7
|
||||
electron: 21.3.0
|
||||
dev: false
|
||||
|
|
21
src/arrpc/LICENSE
Normal file
21
src/arrpc/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 OpenAsar
|
||||
|
||||
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.
|
81
src/arrpc/README.md
Normal file
81
src/arrpc/README.md
Normal file
|
@ -0,0 +1,81 @@
|
|||
<div align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/19228318/202900211-95e8474b-edbb-4048-ba0b-a581a6d57fc4.png" width=300>
|
||||
<img alt="arRPC" src="https://user-images.githubusercontent.com/19228318/203024061-064fc015-9096-40c3-9786-ad23d90414a6.png" width=300>
|
||||
</picture> <br>
|
||||
<a href="https://choosealicense.com/licenses/mit/l"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg"></a>
|
||||
<a href="https://github.com/sponsors/CanadaHonk"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/CanadaHonk?label=Sponsors&logo=github"></a>
|
||||
<h3>An open implementation of Discord's local RPC servers</h3>
|
||||
<h4>Allowing RPC where it was otherwise impossible, like Discord Web and custom clients</h4>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
arRPC is an open source implementation of Discord's half-documented local RPC servers for their desktop client. This open source implementation purely in NodeJS allows it to be used in many places where it is otherwise impossible to do: Discord web and alternative clients like ArmCord/etc. It opens a simple bridge WebSocket server which messages the JSON of exactly what to dispatch with in the client with no extra processing needed, allowing small and simple mods or plugins. **arRPC is experimental and a work in progress, so expect bugs, etc.**
|
||||
|
||||
<br>
|
||||
|
||||
Rich Presence (RPC) is the name for how some apps can talk to Discord desktop on your PC via localhost servers to display detailed info about the app's state. This usually works via parts of Discord desktop natively doing things + parts of Discord web interpreting that and setting it as your status. arRPC is an open source implementation of the local RPC servers on your PC, allowing apps to talk to it thinking it was just normal Discord. It can then send that info to apps which usually don't get RPC, like Discord Web, ArmCord, etc. which can then set that as your status. This would otherwise not be possible, as web apps/browsers/etc can't just use Discord's already existing code and version.
|
||||
|
||||
- App with Discord RPC
|
||||
- ~~Discord Desktop's native server~~ arRPC
|
||||
- ~~Discord Web's setting~~ mod/plugin
|
||||
|
||||
<br>
|
||||
|
||||
## Usage
|
||||
|
||||
### Server (**REQUIRED**)
|
||||
|
||||
1. Have latest (>=18) Node installed
|
||||
2. Clone GitHub repo
|
||||
3. `npm install`
|
||||
4. Run server with `node src`
|
||||
|
||||
### Web
|
||||
|
||||
#### No Mods
|
||||
|
||||
1. Get [the arRPC server running](#server-required)
|
||||
2. With Discord open, run the content of [`examples/bridge_mod.js`](examples/bridge_mod.js) in Console (Ctrl+Shift+I).
|
||||
|
||||
#### Vencord
|
||||
|
||||
1. Get [the arRPC server running](#server-required)
|
||||
2. Just enable the `WebRichPresence (arRPC)` Vencord plugin!
|
||||
|
||||
### Custom Clients
|
||||
|
||||
#### ArmCord
|
||||
|
||||
ArmCord has arRPC specially integrated, just enable the option in it's settings (server not required)!
|
||||
|
||||
#### Webcord
|
||||
|
||||
1. Get [the arRPC server running](#server-required)
|
||||
2. Disable the `Use built-in Content Security Policy` option in Advanced settings: ![image](https://user-images.githubusercontent.com/19228318/202926723-93b772fc-f37d-47d4-81fd-b11c5d4051e8.png)
|
||||
3. With Webcord open, run the content of [`examples/bridge_mod.js`](examples/bridge_mod.js) in the DevTools Console (Ctrl+Shift+I).
|
||||
|
||||
---
|
||||
|
||||
Then just use apps with Discord RPC like normal and they _should_ work!
|
||||
|
||||
<br>
|
||||
|
||||
## Supported
|
||||
|
||||
### Transports
|
||||
|
||||
- [x] WebSocket Server
|
||||
- [x] JSON
|
||||
- [ ] Erlpack
|
||||
- [ ] HTTP Server
|
||||
- [x] IPC
|
||||
|
||||
### Commands
|
||||
|
||||
- [x] DISPATCH
|
||||
- [x] SET_ACTIVITY
|
||||
- [x] INVITE_BROWSER
|
||||
- [x] GUILD_TEMPLATE_BROWSER
|
||||
- [x] DEEP_LINK
|
20
src/arrpc/changelog.md
Normal file
20
src/arrpc/changelog.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# arRPC Changelog
|
||||
|
||||
## v2.2.0 [20-11-2022]
|
||||
|
||||
- Server: Move all looking up/fetching to client
|
||||
|
||||
## v2.1.0 [20-11-2022]
|
||||
|
||||
- Server: Stop activites when app disconnects
|
||||
- Server: Added support for several apps shown at once (added `socketId`)
|
||||
- Bridge: Catchup newly connected clients with last message by socket id
|
||||
- Transports: Rewrote internal API to use handlers object
|
||||
- API: Added parsing for GUILD_TEMPLATE_BROWSER
|
||||
- API: Added parsing for DEEP_LINK
|
||||
|
||||
## v2.0.0 [20-11-2022]
|
||||
|
||||
- feat (breaking): moved asset lookup to client
|
||||
- feat: add examples
|
||||
- feat: add changelog
|
9
src/arrpc/examples/README.md
Normal file
9
src/arrpc/examples/README.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
# arRPC Examples
|
||||
|
||||
## [Bridge Mod](bridge_mod.js)
|
||||
|
||||
Simple mod for using the arRPC Bridge WebSocket server for setting RPC status (to be used with just Web).
|
||||
|
||||
## [Electron](electron)
|
||||
|
||||
Example usage for within an Electron client.
|
78
src/arrpc/examples/bridge_mod.js
Normal file
78
src/arrpc/examples/bridge_mod.js
Normal file
|
@ -0,0 +1,78 @@
|
|||
(() => {
|
||||
let Dispatcher,
|
||||
lookupAsset,
|
||||
lookupApp,
|
||||
apps = {};
|
||||
|
||||
const ws = new WebSocket("ws://127.0.0.1:1337"); // connect to arRPC bridge websocket
|
||||
ws.onmessage = async (x) => {
|
||||
msg = JSON.parse(x.data);
|
||||
console.log(msg);
|
||||
|
||||
if (!Dispatcher) {
|
||||
const wpRequire = window.webpackChunkdiscord_app.push([[Symbol()], {}, (x) => x]);
|
||||
const cache = wpRequire.c;
|
||||
window.webpackChunkdiscord_app.pop();
|
||||
|
||||
for (const id in cache) {
|
||||
let mod = cache[id].exports;
|
||||
mod = mod && (mod.Z ?? mod.ZP);
|
||||
|
||||
if (mod && mod.register && mod.wait) {
|
||||
Dispatcher = mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const factories = wpRequire.m;
|
||||
for (const id in factories) {
|
||||
if (factories[id].toString().includes("getAssetImage: size must === [number, number] for Twitch")) {
|
||||
const mod = wpRequire(id);
|
||||
|
||||
const _lookupAsset = Object.values(mod).find(
|
||||
(e) => typeof e === "function" && e.toString().includes("apply(")
|
||||
);
|
||||
lookupAsset = async (appId, name) => (await _lookupAsset(appId, [name, undefined]))[0];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const id in factories) {
|
||||
if (factories[id].toString().includes(`e.application={`)) {
|
||||
const mod = wpRequire(id);
|
||||
|
||||
const _lookupApp = Object.values(mod).find(
|
||||
(e) => typeof e === "function" && e.toString().includes(`e.application={`)
|
||||
);
|
||||
lookupApp = async (appId) => {
|
||||
let socket = {};
|
||||
await _lookupApp(socket, appId);
|
||||
return socket.application;
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.activity?.assets?.large_image)
|
||||
msg.activity.assets.large_image = await lookupAsset(
|
||||
msg.activity.application_id,
|
||||
msg.activity.assets.large_image
|
||||
);
|
||||
if (msg.activity?.assets?.small_image)
|
||||
msg.activity.assets.small_image = await lookupAsset(
|
||||
msg.activity.application_id,
|
||||
msg.activity.assets.small_image
|
||||
);
|
||||
|
||||
const appId = msg.activity.application_id;
|
||||
if (!apps[appId]) apps[appId] = await lookupApp(appId);
|
||||
|
||||
const app = apps[appId];
|
||||
if (!msg.activity.name) msg.activity.name = app.name;
|
||||
|
||||
Dispatcher.dispatch({type: "LOCAL_ACTIVITY_UPDATE", ...msg}); // set RPC status
|
||||
};
|
||||
})();
|
9
src/arrpc/examples/electron/main.js
Normal file
9
src/arrpc/examples/electron/main.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
// myWindow = your discord.com BrowserWindow
|
||||
|
||||
import Server from "./path/to/arrpc/server.js";
|
||||
|
||||
const arrpc = await new Server();
|
||||
arrpc.on("activity", (data) => myWindow.webContents.send("rpc", data));
|
||||
arrpc.on("invite", (code) => {
|
||||
// your invite code handling here
|
||||
});
|
73
src/arrpc/examples/electron/preload.js
Normal file
73
src/arrpc/examples/electron/preload.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
import {ipcRenderer} from "electron";
|
||||
|
||||
let Dispatcher,
|
||||
lookupAsset,
|
||||
lookupApp,
|
||||
apps = {};
|
||||
ipcRenderer.on("rpc", async (event, data) => {
|
||||
if (!Dispatcher) {
|
||||
const wpRequire = window.webpackChunkdiscord_app.push([[Symbol()], {}, (x) => x]);
|
||||
const cache = wpRequire.c;
|
||||
window.webpackChunkdiscord_app.pop();
|
||||
|
||||
for (const id in cache) {
|
||||
let mod = cache[id].exports;
|
||||
mod = mod && (mod.Z ?? mod.ZP);
|
||||
|
||||
if (mod && mod.register && mod.wait) {
|
||||
Dispatcher = mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const factories = wpRequire.m;
|
||||
for (const id in factories) {
|
||||
if (factories[id].toString().includes("getAssetImage: size must === [number, number] for Twitch")) {
|
||||
const mod = wpRequire(id);
|
||||
|
||||
const _lookupAsset = Object.values(mod).find(
|
||||
(e) => typeof e === "function" && e.toString().includes("apply(")
|
||||
);
|
||||
lookupAsset = async (appId, name) => (await _lookupAsset(appId, [name, undefined]))[0];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const id in factories) {
|
||||
if (factories[id].toString().includes(`e.application={`)) {
|
||||
const mod = wpRequire(id);
|
||||
|
||||
const _lookupApp = Object.values(mod).find(
|
||||
(e) => typeof e === "function" && e.toString().includes(`e.application={`)
|
||||
);
|
||||
lookupApp = async (appId) => {
|
||||
let socket = {};
|
||||
await _lookupApp(socket, appId);
|
||||
return socket.application;
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.activity?.assets?.large_image)
|
||||
data.activity.assets.large_image = await lookupAsset(
|
||||
data.activity.application_id,
|
||||
data.activity.assets.large_image
|
||||
);
|
||||
if (data.activity?.assets?.small_image)
|
||||
data.activity.assets.small_image = await lookupAsset(
|
||||
data.activity.application_id,
|
||||
data.activity.assets.small_image
|
||||
);
|
||||
|
||||
const appId = data.activity.application_id;
|
||||
if (!apps[appId]) apps[appId] = await lookupApp(appId);
|
||||
|
||||
const app = apps[appId];
|
||||
if (!data.activity.name) data.activity.name = app.name;
|
||||
|
||||
Dispatcher.dispatch({type: "LOCAL_ACTIVITY_UPDATE", ...data}); // set RPC status
|
||||
});
|
22
src/arrpc/package.json
Normal file
22
src/arrpc/package.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "arrpc",
|
||||
"version": "2.2.0",
|
||||
"description": "Open Discord RPC server for atypical setups",
|
||||
"main": "src/index.cjs",
|
||||
"scripts": {
|
||||
"start": "node src"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/OpenAsar/arrpc.git"
|
||||
},
|
||||
"author": "OpenAsar",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/OpenAsar/arrpc/issues"
|
||||
},
|
||||
"homepage": "https://github.com/OpenAsar/arrpc#readme",
|
||||
"dependencies": {
|
||||
"ws": "^8.11.0"
|
||||
}
|
||||
}
|
18
src/arrpc/src/index.cjs
Normal file
18
src/arrpc/src/index.cjs
Normal file
|
@ -0,0 +1,18 @@
|
|||
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
||||
const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")}]`, ...args);
|
||||
|
||||
log("arRPC v2.2.0 [ArmCord]");
|
||||
|
||||
const {RPCServer} = require("./server.js");
|
||||
const {mainWindow} = require("../../../ts-out/window.js");
|
||||
|
||||
async function run() {
|
||||
const server = await new RPCServer();
|
||||
server.on("activity", (data) => mainWindow.webContents.send("rpc", data));
|
||||
server.on("invite", (code) => {
|
||||
console.log(code);
|
||||
const {createInviteWindow} = require("../../../ts-out/window.js");
|
||||
createInviteWindow(code);
|
||||
});
|
||||
}
|
||||
run();
|
116
src/arrpc/src/server.js
Normal file
116
src/arrpc/src/server.js
Normal file
|
@ -0,0 +1,116 @@
|
|||
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
||||
const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")} > ${rgb(87, 242, 135, "bridge")}]`, ...args);
|
||||
|
||||
const {EventEmitter} = require("events");
|
||||
|
||||
const {IPCServer} = require("./transports/ipc.js");
|
||||
const {WSServer} = require("./transports/websocket.js");
|
||||
|
||||
let socketId = 0;
|
||||
class RPCServer extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
return (async () => {
|
||||
this.onConnection = this.onConnection.bind(this);
|
||||
this.onMessage = this.onMessage.bind(this);
|
||||
this.onClose = this.onClose.bind(this);
|
||||
|
||||
const handlers = {
|
||||
connection: this.onConnection,
|
||||
message: this.onMessage,
|
||||
close: this.onClose
|
||||
};
|
||||
|
||||
this.ipc = await new IPCServer(handlers);
|
||||
this.ws = await new WSServer(handlers);
|
||||
|
||||
return this;
|
||||
})();
|
||||
}
|
||||
|
||||
onConnection(socket) {
|
||||
socket.send({
|
||||
cmd: "DISPATCH",
|
||||
evt: "READY",
|
||||
|
||||
data: {
|
||||
v: 1
|
||||
}
|
||||
});
|
||||
|
||||
socket.socketId = socketId++;
|
||||
|
||||
this.emit("connection", socket);
|
||||
}
|
||||
|
||||
onClose(socket) {
|
||||
this.emit("activity", {
|
||||
activity: null,
|
||||
pid: socket.lastPid,
|
||||
socketId: socket.socketId.toString()
|
||||
});
|
||||
|
||||
this.emit("close", socket);
|
||||
}
|
||||
|
||||
async onMessage(socket, {cmd, args, nonce}) {
|
||||
this.emit("message", {socket, cmd, args, nonce});
|
||||
|
||||
switch (cmd) {
|
||||
case "SET_ACTIVITY":
|
||||
const {activity, pid} = args; // translate given parameters into what discord dispatch expects
|
||||
const {buttons, timestamps, instance} = activity;
|
||||
|
||||
socket.lastPid = pid ?? socket.lastPid;
|
||||
|
||||
const metadata = {};
|
||||
const extra = {};
|
||||
if (buttons) {
|
||||
// map buttons into expected metadata
|
||||
metadata.button_urls = buttons.map((x) => x.url);
|
||||
extra.buttons = buttons.map((x) => x.label);
|
||||
}
|
||||
|
||||
if (timestamps)
|
||||
for (const x in timestamps) {
|
||||
// translate s -> ms timestamps
|
||||
if (Date.now().toString().length - timestamps[x].toString().length > 2)
|
||||
timestamps[x] = Math.floor(1000 * timestamps[x]);
|
||||
}
|
||||
|
||||
this.emit("activity", {
|
||||
activity: {
|
||||
application_id: socket.clientId,
|
||||
type: 0,
|
||||
metadata,
|
||||
flags: instance ? 1 << 0 : 0,
|
||||
...activity,
|
||||
...extra
|
||||
},
|
||||
pid,
|
||||
socketId: socket.socketId.toString()
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case "GUILD_TEMPLATE_BROWSER":
|
||||
case "INVITE_BROWSER":
|
||||
const {code} = args;
|
||||
socket.send({
|
||||
cmd,
|
||||
data: {
|
||||
code
|
||||
},
|
||||
nonce
|
||||
});
|
||||
|
||||
this.emit(cmd === "INVITE_BROWSER" ? "invite" : "guild_template", code);
|
||||
break;
|
||||
|
||||
case "DEEP_LINK":
|
||||
this.emit("link", args.params);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = {RPCServer};
|
259
src/arrpc/src/transports/ipc.js
Normal file
259
src/arrpc/src/transports/ipc.js
Normal file
|
@ -0,0 +1,259 @@
|
|||
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
||||
const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")} > ${rgb(254, 231, 92, "ipc")}]`, ...args);
|
||||
|
||||
const {join} = require("path");
|
||||
const {platform, env} = require("process");
|
||||
const {unlinkSync} = require("fs");
|
||||
const {createServer, createConnection} = require("net");
|
||||
const SOCKET_PATH =
|
||||
platform === "win32"
|
||||
? "\\\\?\\pipe\\discord-ipc"
|
||||
: join(env.XDG_RUNTIME_DIR || env.TMPDIR || env.TMP || env.TEMP || "/tmp", "discord-ipc");
|
||||
|
||||
// enums for various constants
|
||||
const Types = {
|
||||
// types of packets
|
||||
HANDSHAKE: 0,
|
||||
FRAME: 1,
|
||||
CLOSE: 2,
|
||||
PING: 3,
|
||||
PONG: 4
|
||||
};
|
||||
|
||||
const CloseCodes = {
|
||||
// codes for closures
|
||||
CLOSE_NORMAL: 1000,
|
||||
CLOSE_UNSUPPORTED: 1003,
|
||||
CLOSE_ABNORMAL: 1006
|
||||
};
|
||||
|
||||
const ErrorCodes = {
|
||||
// codes for errors
|
||||
INVALID_CLIENTID: 4000,
|
||||
INVALID_ORIGIN: 4001,
|
||||
RATELIMITED: 4002,
|
||||
TOKEN_REVOKED: 4003,
|
||||
INVALID_VERSION: 4004,
|
||||
INVALID_ENCODING: 4005
|
||||
};
|
||||
|
||||
let uniqueId = 0;
|
||||
|
||||
const encode = (type, data) => {
|
||||
data = JSON.stringify(data);
|
||||
const dataSize = Buffer.byteLength(data);
|
||||
|
||||
const buf = Buffer.alloc(dataSize + 8);
|
||||
buf.writeInt32LE(type, 0); // type
|
||||
buf.writeInt32LE(dataSize, 4); // data size
|
||||
buf.write(data, 8, dataSize); // data
|
||||
|
||||
return buf;
|
||||
};
|
||||
|
||||
const read = (socket) => {
|
||||
let resp = socket.read(8);
|
||||
if (!resp) return;
|
||||
|
||||
resp = Buffer.from(resp);
|
||||
const type = resp.readInt32LE(0);
|
||||
const dataSize = resp.readInt32LE(4);
|
||||
|
||||
if (type < 0 || type >= Object.keys(Types).length) throw new Error("invalid type");
|
||||
|
||||
let data = socket.read(dataSize);
|
||||
if (!data) throw new Error("failed reading data");
|
||||
|
||||
data = JSON.parse(Buffer.from(data).toString());
|
||||
|
||||
switch (type) {
|
||||
case Types.PING:
|
||||
socket.emit("ping", data);
|
||||
socket.write(encode(Types.PONG, data));
|
||||
break;
|
||||
|
||||
case Types.PONG:
|
||||
socket.emit("pong", data);
|
||||
break;
|
||||
|
||||
case Types.HANDSHAKE:
|
||||
if (socket._handshook) throw new Error("already handshook");
|
||||
|
||||
socket._handshook = true;
|
||||
socket.emit("handshake", data);
|
||||
break;
|
||||
|
||||
case Types.FRAME:
|
||||
if (!socket._handshook) throw new Error("need to handshake first");
|
||||
|
||||
socket.emit("request", data);
|
||||
break;
|
||||
|
||||
case Types.CLOSE:
|
||||
socket.end();
|
||||
socket.destroy();
|
||||
break;
|
||||
}
|
||||
|
||||
read(socket);
|
||||
};
|
||||
|
||||
const socketIsAvailable = async (socket) => {
|
||||
socket.pause();
|
||||
socket.on("readable", () => {
|
||||
try {
|
||||
read(socket);
|
||||
} catch (e) {
|
||||
log("error whilst reading", e);
|
||||
|
||||
socket.end(
|
||||
encode(Types.CLOSE, {
|
||||
code: CloseCodes.CLOSE_UNSUPPORTED,
|
||||
message: e.message
|
||||
})
|
||||
);
|
||||
socket.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
const stop = () => {
|
||||
try {
|
||||
socket.end();
|
||||
socket.destroy();
|
||||
} catch {}
|
||||
};
|
||||
|
||||
const possibleOutcomes = Promise.race([
|
||||
new Promise((res) => socket.on("error", res)), // errored
|
||||
new Promise((res, rej) => socket.on("pong", () => rej("socket ponged"))), // ponged
|
||||
new Promise((res, rej) => setTimeout(() => rej("timed out"), 1000)) // timed out
|
||||
]).then(
|
||||
() => true,
|
||||
(e) => e
|
||||
);
|
||||
|
||||
socket.write(encode(Types.PING, ++uniqueId));
|
||||
|
||||
const outcome = await possibleOutcomes;
|
||||
stop();
|
||||
log("checked if socket is available:", outcome === true, outcome === true ? "" : `- reason: ${outcome}`);
|
||||
|
||||
return outcome === true;
|
||||
};
|
||||
|
||||
const getAvailableSocket = async (tries = 0) => {
|
||||
if (tries > 9) {
|
||||
throw new Error("ran out of tries to find socket", tries);
|
||||
}
|
||||
|
||||
const path = SOCKET_PATH + "-" + tries;
|
||||
const socket = createConnection(path);
|
||||
|
||||
log("checking", path);
|
||||
|
||||
if (await socketIsAvailable(socket)) {
|
||||
if (platform !== "win32")
|
||||
try {
|
||||
unlinkSync(path);
|
||||
} catch {}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
log(`not available, trying again (attempt ${tries + 1})`);
|
||||
return getAvailableSocket(tries + 1);
|
||||
};
|
||||
|
||||
class IPCServer {
|
||||
constructor(handers) {
|
||||
return new Promise(async (res) => {
|
||||
this.handlers = handers;
|
||||
|
||||
this.onConnection = this.onConnection.bind(this);
|
||||
this.onMessage = this.onMessage.bind(this);
|
||||
|
||||
const server = createServer(this.onConnection);
|
||||
server.on("error", (e) => {
|
||||
log("server error", e);
|
||||
});
|
||||
|
||||
const socketPath = await getAvailableSocket();
|
||||
server.listen(socketPath, () => {
|
||||
log("listening at", socketPath);
|
||||
this.server = server;
|
||||
|
||||
res(this);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onConnection(socket) {
|
||||
log("new connection!");
|
||||
|
||||
socket.pause();
|
||||
socket.on("readable", () => {
|
||||
try {
|
||||
read(socket);
|
||||
} catch (e) {
|
||||
log("error whilst reading", e);
|
||||
|
||||
socket.end(
|
||||
encode(Types.CLOSE, {
|
||||
code: CloseCodes.CLOSE_UNSUPPORTED,
|
||||
message: e.message
|
||||
})
|
||||
);
|
||||
socket.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
socket.once("handshake", (params) => {
|
||||
log("handshake:", params);
|
||||
|
||||
const ver = params.v ?? 1;
|
||||
const clientId = params.client_id ?? "";
|
||||
// encoding is always json for ipc
|
||||
|
||||
if (ver !== 1) {
|
||||
log("unsupported version requested", ver);
|
||||
|
||||
socket.close(ErrorCodes.INVALID_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (clientId === "") {
|
||||
log("client id required");
|
||||
|
||||
socket.close(ErrorCodes.INVALID_CLIENTID);
|
||||
return;
|
||||
}
|
||||
|
||||
socket.on("error", (e) => {
|
||||
log("socket error", e);
|
||||
});
|
||||
|
||||
socket.on("close", (e) => {
|
||||
log("socket closed", e);
|
||||
this.handlers.close(socket);
|
||||
});
|
||||
|
||||
socket.on("request", this.onMessage.bind(this, socket));
|
||||
|
||||
socket._send = socket.send;
|
||||
socket.send = (msg) => {
|
||||
log("sending", msg);
|
||||
socket.write(encode(Types.FRAME, msg));
|
||||
};
|
||||
|
||||
socket.clientId = clientId;
|
||||
|
||||
this.handlers.connection(socket);
|
||||
});
|
||||
}
|
||||
|
||||
onMessage(socket, msg) {
|
||||
log("message", msg);
|
||||
this.handlers.message(socket, msg);
|
||||
}
|
||||
}
|
||||
module.exports = {IPCServer};
|
130
src/arrpc/src/transports/websocket.js
Normal file
130
src/arrpc/src/transports/websocket.js
Normal file
|
@ -0,0 +1,130 @@
|
|||
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
||||
const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")} > ${rgb(235, 69, 158, "websocket")}]`, ...args);
|
||||
|
||||
const {WebSocketServer} = require("ws");
|
||||
const {createServer} = require("http");
|
||||
const {parse} = require("querystring");
|
||||
|
||||
const portRange = [6463, 6472]; // ports available/possible: 6463-6472
|
||||
|
||||
class WSServer {
|
||||
constructor(handlers) {
|
||||
return (async () => {
|
||||
this.handlers = handlers;
|
||||
|
||||
this.onConnection = this.onConnection.bind(this);
|
||||
this.onMessage = this.onMessage.bind(this);
|
||||
|
||||
let port = portRange[0];
|
||||
|
||||
let http, wss;
|
||||
while (port <= portRange[1]) {
|
||||
log("trying port", port);
|
||||
|
||||
if (
|
||||
await new Promise((res) => {
|
||||
http = createServer();
|
||||
http.on("error", (e) => {
|
||||
// log('http error', e);
|
||||
|
||||
if (e.code === "EADDRINUSE") {
|
||||
log(port, "in use!");
|
||||
res(false);
|
||||
}
|
||||
});
|
||||
|
||||
wss = new WebSocketServer({server: http});
|
||||
wss.on("error", (e) => {
|
||||
// log('wss error', e);
|
||||
});
|
||||
|
||||
wss.on("connection", this.onConnection);
|
||||
|
||||
http.listen(port, "127.0.0.1", () => {
|
||||
log("listening on", port);
|
||||
|
||||
this.http = http;
|
||||
this.wss = wss;
|
||||
|
||||
res(true);
|
||||
});
|
||||
})
|
||||
)
|
||||
break;
|
||||
port++;
|
||||
}
|
||||
|
||||
return this;
|
||||
})();
|
||||
}
|
||||
|
||||
onConnection(socket, req) {
|
||||
const params = parse(req.url.split("?")[1]);
|
||||
const ver = parseInt(params.v ?? 1);
|
||||
const encoding = params.encoding ?? "json"; // json | etf (erlpack)
|
||||
const clientId = params.client_id ?? "";
|
||||
|
||||
const origin = req.headers.origin ?? "";
|
||||
|
||||
log(`new connection! origin:`, origin, JSON.parse(JSON.stringify(params)));
|
||||
|
||||
if (
|
||||
origin !== "" &&
|
||||
!["https://discord.com", "https://ptb.discord.com", "https://canary.discord.com/"].includes(origin)
|
||||
) {
|
||||
log("disallowed origin", origin);
|
||||
|
||||
socket.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (encoding !== "json") {
|
||||
log("unsupported encoding requested", encoding);
|
||||
|
||||
socket.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ver !== 1) {
|
||||
log("unsupported version requested", ver);
|
||||
|
||||
socket.close();
|
||||
return;
|
||||
}
|
||||
|
||||
/* if (clientId === '') {
|
||||
log('client id required');
|
||||
|
||||
socket.close();
|
||||
return;
|
||||
} */
|
||||
|
||||
socket.clientId = clientId;
|
||||
socket.encoding = encoding;
|
||||
|
||||
socket.on("error", (e) => {
|
||||
log("socket error", e);
|
||||
});
|
||||
|
||||
socket.on("close", (e, r) => {
|
||||
log("socket closed", e, r);
|
||||
this.handlers.close(socket);
|
||||
});
|
||||
|
||||
socket.on("message", this.onMessage.bind(this, socket));
|
||||
|
||||
socket._send = socket.send;
|
||||
socket.send = (msg) => {
|
||||
log("sending", msg);
|
||||
socket._send(JSON.stringify(msg));
|
||||
};
|
||||
|
||||
this.handlers.connection(socket);
|
||||
}
|
||||
|
||||
onMessage(socket, msg) {
|
||||
log("message", JSON.parse(msg));
|
||||
this.handlers.message(socket, JSON.parse(msg));
|
||||
}
|
||||
}
|
||||
module.exports = {WSServer};
|
79
src/content/js/rpc.js
Normal file
79
src/content/js/rpc.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
(() => {
|
||||
let Dispatcher,
|
||||
lookupAsset,
|
||||
lookupApp,
|
||||
apps = {};
|
||||
|
||||
ArmCordRPC.listen(async (data) => {
|
||||
msg = data; //already parsed
|
||||
console.log(msg);
|
||||
|
||||
if (!Dispatcher) {
|
||||
const wpRequire = window.webpackChunkdiscord_app.push([[Symbol()], {}, (x) => x]);
|
||||
const cache = wpRequire.c;
|
||||
window.webpackChunkdiscord_app.pop();
|
||||
|
||||
for (const id in cache) {
|
||||
let mod = cache[id].exports;
|
||||
mod = mod && (mod.Z ?? mod.ZP);
|
||||
|
||||
if (mod && mod.register && mod.wait) {
|
||||
Dispatcher = mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const factories = wpRequire.m;
|
||||
for (const id in factories) {
|
||||
if (factories[id].toString().includes("getAssetImage: size must === [number, number] for Twitch")) {
|
||||
const mod = wpRequire(id);
|
||||
|
||||
const _lookupAsset = Object.values(mod).find(
|
||||
(e) => typeof e === "function" && e.toString().includes("apply(")
|
||||
);
|
||||
lookupAsset = async (appId, name) => (await _lookupAsset(appId, [name, undefined]))[0];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const id in factories) {
|
||||
if (factories[id].toString().includes(`e.application={`)) {
|
||||
const mod = wpRequire(id);
|
||||
|
||||
const _lookupApp = Object.values(mod).find(
|
||||
(e) => typeof e === "function" && e.toString().includes(`e.application={`)
|
||||
);
|
||||
lookupApp = async (appId) => {
|
||||
let socket = {};
|
||||
await _lookupApp(socket, appId);
|
||||
return socket.application;
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.activity?.assets?.large_image)
|
||||
msg.activity.assets.large_image = await lookupAsset(
|
||||
msg.activity.application_id,
|
||||
msg.activity.assets.large_image
|
||||
);
|
||||
if (msg.activity?.assets?.small_image)
|
||||
msg.activity.assets.small_image = await lookupAsset(
|
||||
msg.activity.application_id,
|
||||
msg.activity.assets.small_image
|
||||
);
|
||||
|
||||
if (msg.activity) {
|
||||
const appId = msg.activity.application_id;
|
||||
if (!apps[appId]) apps[appId] = await lookupApp(appId);
|
||||
|
||||
const app = apps[appId];
|
||||
if (!msg.activity.name) msg.activity.name = app.name;
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({type: "LOCAL_ACTIVITY_UPDATE", ...msg}); // set RPC status
|
||||
});
|
||||
})();
|
|
@ -1,52 +1,29 @@
|
|||
//https://github.com/GooseMod/GooseMod/wiki/Stuck-Updater-or-Blank-Window-Fix
|
||||
/*
|
||||
Copyright 2022 GooseMod
|
||||
|
||||
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.
|
||||
*/
|
||||
import electron from "electron";
|
||||
import {getConfig} from "../utils";
|
||||
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 = () => {
|
||||
const unstrictCSP = async () => {
|
||||
console.log("Setting up CSP unstricter...");
|
||||
|
||||
const cspAllowAll = ["connect-src", "style-src", "img-src", "font-src"];
|
||||
const cspAllowAll = ["style-src", "connect-src", "img-src", "font-src", "media-src"];
|
||||
|
||||
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) => {
|
||||
const isVencord = await getConfig("mods").then((s) => s.includes("vencord"));
|
||||
electron.session.defaultSession.webRequest.onHeadersReceived(({responseHeaders}, 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"];
|
||||
csp = [];
|
||||
}
|
||||
|
||||
if (csp) {
|
||||
for (let p of cspAllowAll) {
|
||||
csp[0] = csp[0].replace(`${p}`, `${p} * blob: data:`); // * does not include data: URIs
|
||||
for (const directive of cspAllowAll) {
|
||||
csp[0] = csp[0].replace(new RegExp(`${directive}.+?;`), `${directive} * blob: data: 'unsafe-inline';`);
|
||||
}
|
||||
|
||||
if (isVencord) {
|
||||
// unpkg and cdnjs are used for QuickCss and some plugins' dependencies (e.g. GifEncoder & APNG for FakeNitro)
|
||||
csp[0] = csp[0].replace(
|
||||
/script-src.+?(?=;)/,
|
||||
"$& 'unsafe-eval' https://unpkg.com https://cdnjs.cloudflare.com"
|
||||
);
|
||||
}
|
||||
// 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-.*?' /, "");
|
||||
}
|
||||
|
||||
if (corsAllowUrls.some((x) => url.startsWith(x))) {
|
||||
responseHeaders!["access-control-allow-origin"] = ["*"];
|
||||
csp[0] = csp[0].replace(/'nonce-.+?' /, "");
|
||||
}
|
||||
|
||||
done({responseHeaders});
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
import {customTitlebar} from "./main";
|
||||
import {createSettingsWindow} from "./settings/main";
|
||||
import os from "os";
|
||||
import fs from "fs"
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
export function registerIpc() {
|
||||
ipcMain.on("get-app-path", (event, arg) => {
|
||||
|
|
|
@ -52,7 +52,7 @@ app.whenReady().then(async () => {
|
|||
}
|
||||
}
|
||||
await init();
|
||||
await installModLoader()
|
||||
await installModLoader();
|
||||
session.fromPartition("some-partition").setPermissionRequestHandler((webContents, permission, callback) => {
|
||||
if (permission === "notifications") {
|
||||
// Approves the permissions request
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Menu, app, clipboard, globalShortcut} from "electron";
|
||||
import {BrowserWindow, Menu, app, clipboard, globalShortcut} from "electron";
|
||||
import {mainWindow} from "./window";
|
||||
import {getConfig} from "./utils";
|
||||
import {createSettingsWindow} from "./settings/main";
|
||||
|
@ -49,7 +49,7 @@ export async function setMenu() {
|
|||
label: "Developer tools",
|
||||
accelerator: "CmdOrCtrl+Shift+I",
|
||||
click: function () {
|
||||
mainWindow.webContents.toggleDevTools();
|
||||
BrowserWindow.getFocusedWindow()!.webContents.toggleDevTools();
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -28,6 +28,13 @@ contextBridge.exposeInMainWorld("armcord", {
|
|||
splashEnd: () => ipcRenderer.send("splashEnd"),
|
||||
openSettingsWindow: () => ipcRenderer.send("openSettingsWindow")
|
||||
});
|
||||
let windowCallback: (arg0: object) => void;
|
||||
contextBridge.exposeInMainWorld("ArmCordRPC", {
|
||||
listen: (callback: any) => (windowCallback = callback)
|
||||
});
|
||||
ipcRenderer.on("rpc", (event, data: object) => {
|
||||
windowCallback(data);
|
||||
});
|
||||
//to be only used inside armcord internal setup/splash etc
|
||||
if (window.location.href.indexOf("splash.html") > -1 || window.location.href.indexOf("setup.html") > -1) {
|
||||
contextBridge.exposeInMainWorld("armcordinternal", {
|
||||
|
|
|
@ -5,7 +5,7 @@ import "./patch";
|
|||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import {injectHummusTitlebar, injectTitlebar} from "./titlebar";
|
||||
import {sleep, addStyle} from "../utils";
|
||||
import {sleep, addStyle, addScript} from "../utils";
|
||||
import {injectMobileStuff} from "./mobile";
|
||||
var version = ipcRenderer.sendSync("displayVersion");
|
||||
var channel = ipcRenderer.sendSync("channel");
|
||||
|
@ -42,6 +42,23 @@ if (window.location.href.indexOf("splash.html") > -1) {
|
|||
injectMobileStuff();
|
||||
}
|
||||
sleep(5000).then(async () => {
|
||||
// dirty hack to make clicking notifications focus ArmCord
|
||||
addScript(`
|
||||
(() => {
|
||||
const originalSetter = Object.getOwnPropertyDescriptor(Notification.prototype, "onclick").set;
|
||||
Object.defineProperty(Notification.prototype, "onclick", {
|
||||
set(onClick) {
|
||||
originalSetter.call(this, function() {
|
||||
onClick.apply(this, arguments);
|
||||
armcord.window.show();
|
||||
})
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
})();
|
||||
`);
|
||||
|
||||
addScript(fs.readFileSync(path.join(__dirname, "../", "/content/js/rpc.js"), "utf8"));
|
||||
const cssPath = path.join(__dirname, "../", "/content/css/discord.css");
|
||||
addStyle(fs.readFileSync(cssPath, "utf8"));
|
||||
await updateLang();
|
||||
|
|
|
@ -62,12 +62,12 @@
|
|||
</div>
|
||||
<br />
|
||||
<div class="switch acWebsocket">
|
||||
<label class="header" id="settings-invitewebsocket">Invite Websocket</label>
|
||||
<label class="header" id="settings-invitewebsocket">Rich Presence (Experimental)</label>
|
||||
<input class="tgl tgl-light left" id="websocket" type="checkbox" />
|
||||
<label class="tgl-btn left" for="websocket"></label>
|
||||
<p class="description">
|
||||
When enabled ArmCord will support Discord.gg links which means that if you open an invite link in your
|
||||
browser, ArmCord will automatically accept the invite. Can be unresponsive at times.
|
||||
Uses <a target="_blank" href="https://github.com/OpenAsar/arrpc">arRPC</a> to support Discord RPC (Rich
|
||||
Presence) with local programs on your machine. Work in progress.
|
||||
</p>
|
||||
</div>
|
||||
<br />
|
||||
|
|
186
src/socket.ts
186
src/socket.ts
|
@ -1,186 +0,0 @@
|
|||
import type {Server, WebSocket} from "ws";
|
||||
import {inviteWindow, createInviteWindow} from "./window";
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2022 Dawid Papiewski "SpacingBat3"
|
||||
|
||||
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.
|
||||
*/
|
||||
async function wsLog(message: string, ...args: unknown[]) {
|
||||
console.log("[WebSocket] " + message, ...args);
|
||||
}
|
||||
|
||||
/** Generates an inclusive range (as `Array`) from `start` to `end`. */
|
||||
function range(start: number, end: number) {
|
||||
return Array.from({length: end - start + 1}, (_v, k) => start + k);
|
||||
}
|
||||
|
||||
interface InviteResponse {
|
||||
/** Response type/command. */
|
||||
cmd: "INVITE_BROWSER";
|
||||
/** Response arguments. */
|
||||
args: {
|
||||
/** An invitation code. */
|
||||
code: string;
|
||||
};
|
||||
/** Nonce indentifying the communication. */
|
||||
nonce: string;
|
||||
}
|
||||
|
||||
function isInviteResponse(data: unknown): data is InviteResponse {
|
||||
if (!(data instanceof Object)) return false;
|
||||
if ((data as Partial<InviteResponse>)?.cmd !== "INVITE_BROWSER") return false;
|
||||
if (typeof (data as Partial<InviteResponse>)?.args?.code !== "string") return false;
|
||||
if (typeof (data as Partial<InviteResponse>)?.nonce !== "string") return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const messages = {
|
||||
/**
|
||||
* A fake, hard-coded Discord command to spoof the presence of
|
||||
* official Discord client (which makes browser to actually start a
|
||||
* communication with the ArmCord).
|
||||
*/
|
||||
handShake: {
|
||||
/** Message command. */
|
||||
cmd: "DISPATCH",
|
||||
/** Message data. */
|
||||
data: {
|
||||
/** Message scheme version. */
|
||||
v: 1,
|
||||
/** Client properties. */
|
||||
config: {
|
||||
/** Discord CDN host (hard-coded for `dicscord.com` instance). */
|
||||
cdn_host: "cdn.discordapp.com",
|
||||
/** API endpoint (hard-coded for `dicscord.com` instance). */
|
||||
api_endpoint: "//discord.com/api",
|
||||
/** Client type. Can be (probably) `production` or `canary`. */
|
||||
environment: "production"
|
||||
}
|
||||
},
|
||||
evt: "READY",
|
||||
nonce: null
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Tries to reserve the server at given port.
|
||||
*
|
||||
* @returns `Promise`, which always resolves (either to `Server<WebSocket>` on
|
||||
* success or `null` on failure).
|
||||
*/
|
||||
async function getServer(port: number) {
|
||||
const {WebSocketServer} = await import("ws");
|
||||
return new Promise<Server<WebSocket> | null>((resolve) => {
|
||||
const wss = new WebSocketServer({host: "127.0.0.1", port});
|
||||
wss.once("listening", () => resolve(wss));
|
||||
wss.once("error", () => resolve(null));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to start a WebSocket server at given port range. If it suceed, it will
|
||||
* listen to the browser requests which are meant to be sent to official
|
||||
* Discord client.
|
||||
*
|
||||
* Currently it supports only the invitation link requests.
|
||||
*
|
||||
*/
|
||||
export default async function startServer() {
|
||||
function isJsonSyntaxCorrect(string: string) {
|
||||
try {
|
||||
JSON.parse(string);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/** Known Discord instances, including the official ones. */
|
||||
const knownInstancesList = [
|
||||
["Discord", new URL("https://discord.com/app")],
|
||||
["Discord Canary", new URL("https://canary.discord.com/app")],
|
||||
["Discord PTB", new URL("https://ptb.discord.com/app")],
|
||||
["Fosscord", new URL("https://dev.fosscord.com/app")]
|
||||
] as const;
|
||||
|
||||
let wss = null,
|
||||
wsPort = 6463;
|
||||
for (const port of range(6463, 6472)) {
|
||||
wss = await getServer(port);
|
||||
if (wss !== null) {
|
||||
void wsLog("ArmCord is listening at " + port.toString());
|
||||
wsPort = port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (wss === null) return;
|
||||
let lock = false;
|
||||
wss.on("connection", (wss, request) => {
|
||||
const origin = request.headers.origin ?? "https://discord.com";
|
||||
let known = false;
|
||||
for (const instance of knownInstancesList) {
|
||||
if (instance[1].origin === origin) known = true;
|
||||
}
|
||||
if (!known) return;
|
||||
wss.send(JSON.stringify(messages.handShake));
|
||||
wss.once("message", (data, isBinary) => {
|
||||
if (lock) return;
|
||||
lock = true;
|
||||
let parsedData: unknown = data;
|
||||
if (!isBinary) parsedData = data.toString();
|
||||
if (isJsonSyntaxCorrect(parsedData as string)) parsedData = JSON.parse(parsedData as string);
|
||||
if (isInviteResponse(parsedData)) {
|
||||
// Replies to browser, so it finds the communication successful.
|
||||
wss.send(
|
||||
JSON.stringify({
|
||||
cmd: parsedData.cmd,
|
||||
data: {
|
||||
invite: null,
|
||||
code: parsedData.args.code
|
||||
},
|
||||
evt: null,
|
||||
nonce: parsedData.nonce
|
||||
})
|
||||
);
|
||||
createInviteWindow();
|
||||
const child = inviteWindow;
|
||||
if (child === undefined) return;
|
||||
void child.loadURL(origin + "/invite/" + parsedData.args.code);
|
||||
child.webContents.once("did-finish-load", () => {
|
||||
child.show();
|
||||
});
|
||||
child.webContents.once("will-navigate", () => {
|
||||
lock = false;
|
||||
child.close();
|
||||
});
|
||||
child.on("close", (e) => {
|
||||
lock = false;
|
||||
});
|
||||
// Blocks requests to ArmCord's WS, to prevent loops.
|
||||
child.webContents.session.webRequest.onBeforeRequest(
|
||||
{
|
||||
urls: ["ws://127.0.0.1:" + wsPort.toString() + "/*"]
|
||||
},
|
||||
(_details, callback) => callback({cancel: true})
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import * as fs from "fs";
|
||||
import {app, Menu, Tray, nativeImage} from "electron";
|
||||
import {mainWindow} from "./window";
|
||||
import {createInviteWindow, mainWindow} from "./window";
|
||||
import {getConfig, getConfigLocation, setWindowState, getDisplayVersion} from "./utils";
|
||||
import * as path from "path";
|
||||
import {createSettingsWindow} from "./settings/main";
|
||||
|
@ -113,8 +113,7 @@ app.whenReady().then(async () => {
|
|||
{
|
||||
label: "Support Discord Server",
|
||||
click: function () {
|
||||
mainWindow.show();
|
||||
mainWindow.loadURL("https://discord.gg/TnhxcqynZ2");
|
||||
createInviteWindow("TnhxcqynZ2");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
92
src/utils.ts
92
src/utils.ts
|
@ -1,10 +1,10 @@
|
|||
import * as fs from "fs";
|
||||
import {app, dialog, session} from "electron";
|
||||
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)
|
||||
import fetch from "cross-fetch";
|
||||
import extract from "extract-zip";
|
||||
import util from "util";
|
||||
const streamPipeline = util.promisify(require("stream").pipeline);
|
||||
export var firstRun: boolean;
|
||||
export var contentPath: string;
|
||||
export var transparency: boolean;
|
||||
|
@ -77,7 +77,6 @@ export function getDisplayVersion() {
|
|||
}
|
||||
}
|
||||
export async function injectJS(inject: string) {
|
||||
|
||||
const js = await (await fetch(`${inject}`)).text();
|
||||
|
||||
const el = document.createElement("script");
|
||||
|
@ -125,7 +124,7 @@ export async function injectElectronFlags() {
|
|||
console.log("No performance modes set");
|
||||
}
|
||||
if ((await getConfig("windowStyle")) == "transparent" && process.platform === "win32") {
|
||||
import("@pyke/vibe").then(vibe => {
|
||||
import("@pyke/vibe").then((vibe) => {
|
||||
console.log("Transparent mode enabled");
|
||||
vibe.setup(app);
|
||||
transparency = true;
|
||||
|
@ -286,66 +285,71 @@ 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
|
||||
if ((await getConfig("noBundleUpdates")) == undefined ?? false) {
|
||||
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."
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.log("[Mod loader] Skipping mod bundle update");
|
||||
}
|
||||
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"
|
||||
if ((await getConfig("mods")) == "none") {
|
||||
modInstallState = "none";
|
||||
import("./extensions/plugin");
|
||||
console.log("[Mod loader] Skipping")
|
||||
console.log("[Mod loader] Skipping");
|
||||
} else {
|
||||
const pluginFolder = app.getPath("userData") + "/plugins/";
|
||||
if (!fs.existsSync(pluginFolder + "loader")) {
|
||||
try {
|
||||
modInstallState = "installing"
|
||||
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()
|
||||
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)
|
||||
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()
|
||||
modInstallState = "modDownload";
|
||||
updateModBundle();
|
||||
import("./extensions/plugin");
|
||||
modInstallState = "done"
|
||||
modInstallState = "done";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,11 @@ import {
|
|||
setConfig,
|
||||
setLang,
|
||||
setWindowState,
|
||||
transparency,
|
||||
transparency
|
||||
} from "./utils";
|
||||
import {registerIpc} from "./ipc";
|
||||
import {setMenu} from "./menu";
|
||||
import * as fs from "fs";
|
||||
import startServer from "./socket";
|
||||
import contextMenu from "electron-context-menu";
|
||||
import os from "os";
|
||||
import {tray} from "./tray";
|
||||
|
@ -51,9 +50,9 @@ contextMenu({
|
|||
});
|
||||
async function doAfterDefiningTheWindow() {
|
||||
if (transparency && process.platform === "win32") {
|
||||
import("@pyke/vibe").then(vibe => {
|
||||
import("@pyke/vibe").then((vibe) => {
|
||||
vibe.applyEffect(mainWindow, "acrylic");
|
||||
vibe.forceTheme(mainWindow, 'dark');
|
||||
vibe.forceTheme(mainWindow, "dark");
|
||||
mainWindow.show();
|
||||
});
|
||||
}
|
||||
|
@ -85,7 +84,7 @@ async function doAfterDefiningTheWindow() {
|
|||
}
|
||||
mainWindow.webContents.setWindowOpenHandler(({url}) => {
|
||||
// Allow about:blank (used by Vencord QuickCss popup)
|
||||
if (url === "about:blank") return { action: "allow" };
|
||||
if (url === "about:blank") return {action: "allow"};
|
||||
|
||||
if (url.startsWith("https:" || url.startsWith("http:") || url.startsWith("mailto:"))) {
|
||||
shell.openExternal(url);
|
||||
|
@ -205,7 +204,9 @@ async function doAfterDefiningTheWindow() {
|
|||
});
|
||||
console.log(contentPath);
|
||||
if ((await getConfig("inviteWebsocket")) == true) {
|
||||
await startServer();
|
||||
//@ts-ignore
|
||||
require("arrpc");
|
||||
//await startServer();
|
||||
}
|
||||
if (firstRun) {
|
||||
await setLang(Intl.DateTimeFormat().resolvedOptions().locale);
|
||||
|
@ -290,7 +291,7 @@ export function createTransparentWindow() {
|
|||
});
|
||||
doAfterDefiningTheWindow();
|
||||
}
|
||||
export function createInviteWindow() {
|
||||
export function createInviteWindow(code: string) {
|
||||
inviteWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
|
@ -304,5 +305,16 @@ export function createInviteWindow() {
|
|||
spellcheck: true
|
||||
}
|
||||
});
|
||||
inviteWindow.hide();
|
||||
var formInviteURL = `https://discord.com/invite/${code}`;
|
||||
inviteWindow.webContents.session.webRequest.onBeforeRequest((details, callback) => {
|
||||
if (details.url.includes("ws://")) return callback({cancel: true});
|
||||
return callback({});
|
||||
});
|
||||
inviteWindow.loadURL(formInviteURL);
|
||||
inviteWindow.webContents.once("did-finish-load", () => {
|
||||
inviteWindow.show();
|
||||
inviteWindow.webContents.once("will-navigate", () => {
|
||||
inviteWindow.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -31,4 +31,4 @@
|
|||
"downlevelIteration": false, // This flag adds extra support when targeting ES3, but adds extra bloat otherwise.
|
||||
"importHelpers": false // Reduce the amount of bloat that comes from downlevelIteration (when polyfills are redeclared).
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue