From 6369c0e8af4c31e95f71a2434ddf1725670ce6b9 Mon Sep 17 00:00:00 2001 From: HorizonCode Date: Sun, 14 Jan 2024 00:21:33 +0100 Subject: [PATCH] added discord rpc --- appInfo.js | 4 ++ main.js | 36 ++++++++++++-- package-lock.json | 94 ++++++++++++++++++++++++++++++++++--- package.json | 1 + src/discord/richPresence.js | 56 ++++++++++++++++++++++ src/util/osuUtil.js | 1 - 6 files changed, 180 insertions(+), 12 deletions(-) create mode 100644 appInfo.js create mode 100644 src/discord/richPresence.js diff --git a/appInfo.js b/appInfo.js new file mode 100644 index 0000000..1cf86c1 --- /dev/null +++ b/appInfo.js @@ -0,0 +1,4 @@ +const appName = "EZPPLauncher"; +const appVersion = "2.0.0"; + +module.exports = { appName, appVersion }; \ No newline at end of file diff --git a/main.js b/main.js index b8d2278..32af188 100644 --- a/main.js +++ b/main.js @@ -12,6 +12,7 @@ const { formatBytes } = require("./src/util/formattingUtil"); const windowName = require("get-window-by-name"); const { existsSync } = require("fs"); const { runFileDetached } = require("./src/util/executeUtil"); +const richPresence = require("./src/discord/richPresence"); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. @@ -19,6 +20,7 @@ let mainWindow; let osuCheckInterval; let userOsuPath; let osuLoaded = false; +let lastOsuStatus = ""; let currentUser = undefined; @@ -44,6 +46,26 @@ function startOsuStatus() { } }, 3000); } + + const windowTitle = firstInstance.processTitle; + if (lastOsuStatus == windowTitle) return; + lastOsuStatus = windowTitle; + if (!windowTitle.includes("-")) { + richPresence.updateStatus({ + details: undefined, + state: "Idle..." + }) + } else { + const components = windowTitle.split(" - "); + const splitTitle = [components.shift(), components.join(" - ")] + const currentMap = splitTitle[1]; + if (!currentMap.endsWith(".osu")) { + richPresence.updateStatus({ + state: "Playing...", + details: currentMap + }) + } + } } }, 1000); } @@ -291,9 +313,9 @@ function registerIPCPipes() { status: "Preparing launch...", }); - //TODO: save credentials to osu!.%username%.cfg + const userConfig = getUserConfig(osuPath); + richPresence.updateVersion(await userConfig.get("LastVersion")); if (currentUser) { - const userConfig = getUserConfig(osuPath); await userConfig.set("Username", currentUser.username); await userConfig.set("Password", currentUser.password); } @@ -305,6 +327,11 @@ function registerIPCPipes() { const onExitHook = () => { mainWindow.show(); stopOsuStatus(); + richPresence.updateVersion(); + richPresence.updateStatus({ + state: "Idle in Launcher...", + details: undefined + }) mainWindow.webContents.send("ezpplauncher:launchstatus", { status: "Waiting for cleanup...", }); @@ -366,7 +393,7 @@ function createWindow() { } registerIPCPipes(); - + richPresence.connect(); // Uncomment the following line of code when app is ready to be packaged. // loadURL(mainWindow); @@ -397,9 +424,10 @@ function createWindow() { app.on("ready", createWindow); // Quit when all windows are closed. -app.on("window-all-closed", function () { +app.on("window-all-closed", async function () { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q + await richPresence.disconnect(); if (process.platform !== "darwin") app.quit(); }); diff --git a/package-lock.json b/package-lock.json index f5453a6..e44ad7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "better-sqlite3": "^9.2.2", "crypto": "^1.0.1", "custom-electron-titlebar": "^4.2.7", + "discord-auto-rpc": "^1.0.17", "electron-serve": "^1.1.0", "get-window-by-name": "^2.0.0", "svelte-french-toast": "^1.2.0" @@ -1688,11 +1689,24 @@ "@types/ms": "*" } }, + "node_modules/@types/discord-rpc": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/discord-rpc/-/discord-rpc-4.0.8.tgz", + "integrity": "sha512-1tZf217Natkj+TziNXRRLwNmdm5GNa1bnrQr8VWowquo/Su5hMjdhobj8URxW1COMk2da28XCU1ahsYCAlxirA==", + "dependencies": { + "@types/events": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, + "node_modules/@types/events": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.3.tgz", + "integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==" + }, "node_modules/@types/fs-extra": { "version": "9.0.13", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", @@ -3452,6 +3466,27 @@ "node": ">=8" } }, + "node_modules/discord-auto-rpc": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/discord-auto-rpc/-/discord-auto-rpc-1.0.17.tgz", + "integrity": "sha512-ZTK8azvfapMmwjxLAowHuOSglAens7UtBuQnL8b4VDmqzPM0K8ze1A/uPViWkJ8ROEOjZeHoK3zu0jwsQKGavQ==", + "dependencies": { + "@types/discord-rpc": "^4.0.2", + "discord-rpc": "^3.2.0" + } + }, + "node_modules/discord-rpc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-3.2.0.tgz", + "integrity": "sha512-KJv0EVbGMlr04HoG6f5b3wD7X9kSHzQ2Ed2qfHSDvYJ1MkE8RbCQmMcQQrSvAxpfsqZgUjB/bsfi/mjyicCH+A==", + "dependencies": { + "node-fetch": "^2.6.1", + "ws": "^7.3.1" + }, + "peerDependencies": { + "register-scheme": "github:devsnek/node-register-scheme" + } + }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -3790,7 +3825,6 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, "optional": true, "dependencies": { "iconv-lite": "^0.6.2" @@ -4685,7 +4719,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, + "devOptional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -5702,9 +5736,7 @@ "node_modules/node-addon-api": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "dev": true, - "optional": true + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" }, "node_modules/node-api-version": { "version": "0.2.0", @@ -5730,6 +5762,25 @@ "node": ">=10" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-gyp": { "version": "9.4.1", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", @@ -6999,6 +7050,17 @@ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true }, + "node_modules/register-scheme": { + "version": "0.0.2", + "resolved": "git+ssh://git@github.com/devsnek/node-register-scheme.git#e7cc9a63a1f512565da44cb57316d9fb10750e17", + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bindings": "^1.3.0", + "node-addon-api": "^1.3.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7544,7 +7606,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "devOptional": true }, "node_modules/sander": { "version": "0.5.1", @@ -8810,6 +8872,11 @@ "node": ">=6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -9076,6 +9143,20 @@ "defaults": "^1.0.3" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -9144,7 +9225,6 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, "engines": { "node": ">=8.3.0" }, diff --git a/package.json b/package.json index 8fdbf5b..f2c13a1 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "better-sqlite3": "^9.2.2", "crypto": "^1.0.1", "custom-electron-titlebar": "^4.2.7", + "discord-auto-rpc": "^1.0.17", "electron-serve": "^1.1.0", "get-window-by-name": "^2.0.0", "svelte-french-toast": "^1.2.0" diff --git a/src/discord/richPresence.js b/src/discord/richPresence.js new file mode 100644 index 0000000..642c15b --- /dev/null +++ b/src/discord/richPresence.js @@ -0,0 +1,56 @@ +const DiscordRPC = require("discord-auto-rpc"); +const { appName, appVersion } = require("../../appInfo"); + +const clientId = "1032772293220384808"; +let richPresence; + +let currentStatus = { + details: " ", + state: "Idle in Launcher...", + startTimestamp: new Date(), + largeImageKey: "ezppfarm", + largeImageText: `${appName} ${appVersion}`, + smallImageKey: " ", + smallImageText: " ", + buttons: [ + { + label: "Download the Launcher", + url: "https://git.ez-pp.farm/EZPPFarm/EZPPLauncher/releases/latest" + }, + { + label: "Join EZPPFarm", + url: "https://ez-pp.farm/discord" + } + ], + instance: false + +} + +module.exports = { + connect: () => { + if (!richPresence) { + richPresence = new DiscordRPC.AutoClient({ transport: "ipc" }); + richPresence.endlessLogin({ clientId }); + richPresence.once("ready", () => { + setInterval(() => { + richPresence.setActivity(currentStatus); + }, 2500) + }); + } + }, + disconnect: async () => { + if (richPresence) { + await richPresence.clearActivity(); + await richPresence.destroy(); + richPresence = null; + } + }, + updateStatus: ({ state, details }) => { + currentStatus.state = state ?? " "; + currentStatus.details = details ?? " "; + }, + updateVersion: (osuVersion) => { + currentStatus.smallImageKey = osuVersion ? "osu" : " "; + currentStatus.smallImageText = osuVersion ? `osu! ${osuVersion}` : " "; + } +} \ No newline at end of file diff --git a/src/util/osuUtil.js b/src/util/osuUtil.js index fc41b97..2d1d94c 100644 --- a/src/util/osuUtil.js +++ b/src/util/osuUtil.js @@ -353,7 +353,6 @@ async function replaceUIFile(osuPath, revert) { await fs.promises.rename(oldOsuUIFile, ezppUIFile); await fs.promises.rename(path.join(osuPath, "osu!ui.dll.bak"), oldOsuUIFile); } - } module.exports = { isValidOsuFolder, getUserConfig, getGlobalConfig, getUpdateFiles, getFilesThatNeedUpdate, downloadUpdateFiles, runOsuWithDevServer, getPatcherUpdates, downloadPatcherUpdates, downloadUIFiles, getUIFiles, replaceUIFile };