fix: discord RPC on Linux, creating symlink between Discord and Freedom Loader at start if needed

This commit is contained in:
MasterAcnolo
2026-08-08 10:51:10 +02:00
committed by MasterAcnolo
parent 1690cc18b2
commit ce2a0485ab

View File

@@ -1,6 +1,8 @@
const config = require('../config'); const config = require('../config');
const RPC = require("discord-rpc"); const RPC = require("discord-rpc");
const { logger } = require("../server/logger"); const { logger } = require("../server/logger");
const fs = require("fs");
const path = require("path");
/** /**
* Discord Application Client ID used to authenticate the RPC connection. * Discord Application Client ID used to authenticate the RPC connection.
@@ -20,6 +22,51 @@ const rpc = new RPC.Client({ transport: "ipc" });
*/ */
let intervalId; let intervalId;
/**
* Automagically fixes Discord RPC on Linux for Sandboxed versions (Flatpak & Snap).
* It creates a symlink from the sandbox IPC socket to the standard system location.
*
* @returns {void}
*/
function fixLinuxDiscordRPC() {
// Only execute on Linux
if (process.platform !== "linux") return;
/**
* Get the user's runtime directory (e.g., /run/user/1000).
* @type {string}
*/
const xdgDir = process.env.XDG_RUNTIME_DIR || `/run/user/${process.getuid()}`;
const standardSocket = path.join(xdgDir, "discord-ipc-0");
// If the standard socket already exists (Native Discord), do nothing.
if (fs.existsSync(standardSocket)) return;
/**
* Paths for known sandboxed Discord IPC sockets.
*/
const flatpakSocket = path.join(xdgDir, "app/com.discordapp.Discord/discord-ipc-0");
const snapSocket = path.join(xdgDir, "snap.discord/discord-ipc-0");
let targetSocket = null;
if (fs.existsSync(flatpakSocket)) {
targetSocket = flatpakSocket;
} else if (fs.existsSync(snapSocket)) {
targetSocket = snapSocket;
}
// If a sandboxed socket is found, create the symlink stealthily.
if (targetSocket) {
try {
fs.symlinkSync(targetSocket, standardSocket);
logger.info(`Discord RPC bridge created automatically targeting: ${targetSocket}`);
} catch (err) {
logger.warn(`Failed to create Discord RPC bridge: ${err.message}`);
}
}
}
/** /**
* Initializes Discord Rich Presence (RPC) connection. * Initializes Discord Rich Presence (RPC) connection.
* *
@@ -32,6 +79,11 @@ let intervalId;
*/ */
function startRPC() { function startRPC() {
/**
* Patch that create Simlinks for Linux environment;
*/
fixLinuxDiscordRPC();
/** /**
* Rich Presence payload describing current application state * Rich Presence payload describing current application state
* shown in Discord user profile. * shown in Discord user profile.
@@ -60,28 +112,30 @@ function startRPC() {
* *
* Responsibilities: * Responsibilities:
* - Clear any running intervals * - Clear any running intervals
* - Remove current activity from Discord * - Remove current activity from Discord if connected
* - Destroy RPC transport connection * - Destroy RPC transport connection
* - Handle cleanup errors safely * - Handle cleanup errors safely
*/ */
async function stopRPC() { async function stopRPC() {
if (rpc) {
try { try {
if (intervalId) clearInterval(intervalId); if (intervalId) clearInterval(intervalId);
/** /**
* Ensures RPC connection exists before attempting cleanup. * Ensures RPC connection AND the underlying socket exist
* before attempting to clear activity to prevent crash.
*/ */
if (rpc && rpc.transport) { if (rpc.transport && rpc.transport.socket) {
await rpc.clearActivity() await rpc.clearActivity();
await rpc.destroy();
} else{
logger.error("Not Able to close RPC")
} }
await rpc.destroy();
} catch (err) { } catch (err) {
logger.error("Error while closing the RPC:", err); logger.error("Error while closing the RPC:", err);
} }
} }
}
module.exports = { startRPC, stopRPC}; module.exports = { startRPC, stopRPC};