'use strict'; /* * discordpresence.js – Discord Rich Presence ("Spielt Minecraft über AeroMC") * ----------------------------------------------------------------------------- * Verbindet sich rein lokal über die IPC-Pipe des laufenden Discord-Clients. * SET_ACTIVITY braucht dafür bewusst KEINE Authentifizierung/OAuth (anders als * der Rest der RPC-API) – daher hier absichtlich client.request(...) direkt * statt client.user.setActivity(...), das erst nach einem Login funktioniert. * * Immer aktiv, ohne eigene Einstellung – braucht also keine Zustimmung/kein * Häkchen. Läuft trotzdem komplett unauffällig: ist Discord nicht installiert * oder nicht gestartet, bleibt es einfach inaktiv, ohne den Launcher oder den * Spielstart zu stören – jeder Fehler hier wird bewusst verschluckt. */ const { Client } = require('@xhayper/discord-rpc'); // Von M_Viper unter discord.com/developers/applications angelegte AeroMC-App. // Öffentliche Anwendungs-ID, kein Geheimnis (genau wie DEFAULT_CLIENT_ID bei // der Microsoft-Anmeldung in auth.js) – gilt für alle AeroMC-Nutzer gleich. const DEFAULT_CLIENT_ID = '1538173087730630686'; const LAUNCHER_WEBSITE = 'https://aeromc.viper.ipv64.net/'; let clientId = DEFAULT_CLIENT_ID; let client = null; let connecting = null; function resolveClientId() { return (clientId && String(clientId).trim()) || DEFAULT_CLIENT_ID; } async function connect() { if (client && client.isConnected) return client; if (connecting) return connecting; const id = resolveClientId(); const c = new Client({ clientId: id }); c.on('disconnected', () => { if (client === c) client = null; }); connecting = c.connect() .then(() => { client = c; connecting = null; return c; }) .catch((err) => { connecting = null; throw err; }); return connecting; } /* * activity: { details, state, startTimestamp } * details/state -> die beiden Zeilen unter dem Profilbild in Discord * startTimestamp -> Discord zeigt die Spielzeit dann selbst laufend an */ async function setActivity(activity) { try { const c = await connect(); await c.request('SET_ACTIVITY', { pid: process.pid, activity: { details: activity.details, state: activity.state, timestamps: activity.startTimestamp ? { start: activity.startTimestamp } : undefined, assets: { large_image: 'aeromc_logo', large_text: 'AeroMC Launcher' }, // Discord zeigt Buttons Betrachtern des Profils an (nicht sich selbst) - // maximal 2 sind erlaubt, hier reicht einer. buttons: [{ label: 'AeroMC herunterladen', url: LAUNCHER_WEBSITE }], instance: false, }, }); } catch { // Discord nicht installiert/nicht gestartet o. Ä. - bewusst lautlos } } async function clearActivity() { try { if (!client || !client.isConnected) return; await client.request('SET_ACTIVITY', { pid: process.pid }); } catch { /* egal */ } } async function shutdown() { const c = client; client = null; connecting = null; if (!c) return; try { await c.destroy(); } catch { /* egal */ } } /* * Verbindet direkt beim Start. settings.discordClientId erlaubt weiterhin * (rein optional, per Hand in settings.json) eine eigene App-ID zu setzen - * ohne eigenes Einstellungsfeld, ohne dass es dafür einen Schalter braucht. */ function configure(settings) { const nextId = (settings && settings.discordClientId) || DEFAULT_CLIENT_ID; const idChanged = nextId !== clientId; clientId = nextId; if (idChanged) { shutdown().then(() => connect().catch(() => {})); } else if (!client) { connect().catch(() => {}); } } module.exports = { configure, setActivity, clearActivity, shutdown, DEFAULT_CLIENT_ID };