Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b54217989 | ||
|
|
425b94fd93 | ||
|
|
e0bdcb01fb | ||
|
|
c840a49f75 | ||
|
|
c535d8b830 | ||
|
|
248a387f01 |
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Ein Minecraft-Launcher für Windows mit getrennten Instanzen, Mod-Unterstützung und Microsoft-Anmeldung.
|
Ein Minecraft-Launcher für Windows mit getrennten Instanzen, Mod-Unterstützung und Microsoft-Anmeldung.
|
||||||
|
|
||||||
Aktueller Stand: Version 1.0.8
|
Aktueller Stand: Version 1.0.9
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Generated
+141
-3
@@ -1,14 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "aeromc",
|
"name": "aeromc",
|
||||||
"version": "1.0.7",
|
"version": "1.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "aeromc",
|
"name": "aeromc",
|
||||||
"version": "1.0.7",
|
"version": "1.1.0",
|
||||||
"license": "MIT",
|
"license": "SEE LICENSE IN LICENSE",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@xhayper/discord-rpc": "^1.3.4",
|
||||||
"archiver": "^7.0.1",
|
"archiver": "^7.0.1",
|
||||||
"skinview3d": "^3.4.2",
|
"skinview3d": "^3.4.2",
|
||||||
"undici": "^6.28.0",
|
"undici": "^6.28.0",
|
||||||
@@ -37,6 +38,56 @@
|
|||||||
"url": "https://opencollective.com/webpack"
|
"url": "https://opencollective.com/webpack"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@discordjs/collection": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/rest": {
|
||||||
|
"version": "2.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.6.3.tgz",
|
||||||
|
"integrity": "sha512-wvOylxNYJkwKjctS/Mn5GP1w9r3/rzyH+ThD1JlAca6zEdlHs8QWBBUQJpU5Q+W6DoIj/Ljh1IPlZs7hTU+UAg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@discordjs/collection": "^2.1.1",
|
||||||
|
"@discordjs/util": "^1.2.0",
|
||||||
|
"@sapphire/async-queue": "^1.5.3",
|
||||||
|
"@sapphire/snowflake": "^3.5.5",
|
||||||
|
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||||
|
"discord-api-types": "^0.38.50",
|
||||||
|
"magic-bytes.js": "^1.13.0",
|
||||||
|
"tslib": "^2.6.3",
|
||||||
|
"undici": "^6.27.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/util": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-3LKP7F2+atl9vJFhaBjn4nOaSWahZ/yWjOvA4e5pnXkt2qyXRCHLxoBQy81GFtLGCq7K9lPm9R517M1U+/90Qg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"discord-api-types": "^0.38.33"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron/asar": {
|
"node_modules/@electron/asar": {
|
||||||
"version": "3.4.1",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz",
|
||||||
@@ -494,6 +545,26 @@
|
|||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@sapphire/async-queue": {
|
||||||
|
"version": "1.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz",
|
||||||
|
"integrity": "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v14.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sapphire/snowflake": {
|
||||||
|
"version": "3.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.5.tgz",
|
||||||
|
"integrity": "sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v14.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@sindresorhus/is": {
|
"node_modules/@sindresorhus/is": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||||
@@ -662,6 +733,31 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vladfrangu/async_event_emitter": {
|
||||||
|
"version": "2.4.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.7.tgz",
|
||||||
|
"integrity": "sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v14.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@xhayper/discord-rpc": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@xhayper/discord-rpc/-/discord-rpc-1.3.4.tgz",
|
||||||
|
"integrity": "sha512-ff0uEXuibh9wi+l4vOj7xInLUjtlTaQBje/SCyQkeXZ0j2V0y+Zge5PQIQFRHH9TjjGaYJkTofEcQhncM2q7/w==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"@discordjs/rest": "^2.6.1",
|
||||||
|
"@vladfrangu/async_event_emitter": "^2.4.7",
|
||||||
|
"discord-api-types": "^0.38.47",
|
||||||
|
"ws": "^8.20.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@xmldom/xmldom": {
|
"node_modules/@xmldom/xmldom": {
|
||||||
"version": "0.9.10",
|
"version": "0.9.10",
|
||||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz",
|
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz",
|
||||||
@@ -1799,6 +1895,15 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/discord-api-types": {
|
||||||
|
"version": "0.38.53",
|
||||||
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.53.tgz",
|
||||||
|
"integrity": "sha512-HL1zz/UuZ+bbJjA/X8Kbxx9gk8v9rJAbTeWRNYKmIdjwJ7EovjlHgoJTxcLpATfNJ+AonOtMdy3Y5MVIJAAd/A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"workspaces": [
|
||||||
|
"scripts/actions/documentation"
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/dmg-builder": {
|
"node_modules/dmg-builder": {
|
||||||
"version": "24.13.3",
|
"version": "24.13.3",
|
||||||
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz",
|
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz",
|
||||||
@@ -3363,6 +3468,12 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/magic-bytes.js": {
|
||||||
|
"version": "1.13.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.13.1.tgz",
|
||||||
|
"integrity": "sha512-x5sn4UX2k5gCWlcfmoFwG4TPie8+dctESyqOBdhB5p6MsgWXdBKGmt9nXPObj/JI50TTL928lc5Yt1WntMn1bw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/matcher": {
|
"node_modules/matcher": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
|
||||||
@@ -4318,6 +4429,12 @@
|
|||||||
"utf8-byte-length": "^1.0.1"
|
"utf8-byte-length": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
"node_modules/type-fest": {
|
"node_modules/type-fest": {
|
||||||
"version": "0.13.1",
|
"version": "0.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
|
||||||
@@ -4517,6 +4634,27 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.21.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
|
||||||
|
"integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xmlbuilder": {
|
"node_modules/xmlbuilder": {
|
||||||
"version": "15.1.1",
|
"version": "15.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "aeromc",
|
"name": "aeromc",
|
||||||
"productName": "AeroMC",
|
"productName": "AeroMC",
|
||||||
"version": "1.0.8",
|
"version": "1.1.0",
|
||||||
"description": "AeroMC – Instanz-basierter Minecraft-Launcher (à la MultiMC/Prism)",
|
"description": "AeroMC – Instanz-basierter Minecraft-Launcher (à la MultiMC/Prism)",
|
||||||
"homepage": "https://m-viper.de",
|
"homepage": "https://m-viper.de",
|
||||||
"launcherWebsite": "https://aeromc.viper.ipv64.net",
|
"launcherWebsite": "https://aeromc.viper.ipv64.net",
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
"electron-builder": "^24.0.0"
|
"electron-builder": "^24.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@xhayper/discord-rpc": "^1.3.4",
|
||||||
"archiver": "^7.0.1",
|
"archiver": "^7.0.1",
|
||||||
"skinview3d": "^3.4.2",
|
"skinview3d": "^3.4.2",
|
||||||
"undici": "^6.28.0",
|
"undici": "^6.28.0",
|
||||||
|
|||||||
@@ -354,6 +354,10 @@ async function restoreGlobalBackup(options) {
|
|||||||
const settingsFile = path.join(userDataDir, 'settings.json');
|
const settingsFile = path.join(userDataDir, 'settings.json');
|
||||||
const rollbackSettings = path.join(rollbackDir, 'settings.json');
|
const rollbackSettings = path.join(rollbackDir, 'settings.json');
|
||||||
let settingsPreviouslyExisted = false;
|
let settingsPreviouslyExisted = false;
|
||||||
|
// wird erst true, sobald der aktuelle Stand tatsächlich weggesichert wurde -
|
||||||
|
// vorher darf der Rollback nichts anfassen, sonst löscht ein früher Fehler
|
||||||
|
// (z. B. ungültiges Archiv) den unveränderten, intakten Originalbestand
|
||||||
|
let originalMovedAway = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ensureDir(extractDir);
|
ensureDir(extractDir);
|
||||||
@@ -382,6 +386,7 @@ async function restoreGlobalBackup(options) {
|
|||||||
endPercent: 40,
|
endPercent: 40,
|
||||||
detailPrefix: 'Sichere aktuelle Instanzen',
|
detailPrefix: 'Sichere aktuelle Instanzen',
|
||||||
});
|
});
|
||||||
|
originalMovedAway = true;
|
||||||
settingsPreviouslyExisted = fs.existsSync(settingsFile);
|
settingsPreviouslyExisted = fs.existsSync(settingsFile);
|
||||||
if (settingsPreviouslyExisted) fs.copyFileSync(settingsFile, rollbackSettings);
|
if (settingsPreviouslyExisted) fs.copyFileSync(settingsFile, rollbackSettings);
|
||||||
|
|
||||||
@@ -414,6 +419,12 @@ async function restoreGlobalBackup(options) {
|
|||||||
restoredSettings,
|
restoredSettings,
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
// Nur zurückrollen, wenn wir den ursprünglichen Bestand überhaupt schon
|
||||||
|
// angefasst haben (siehe originalMovedAway oben). Schlägt die
|
||||||
|
// Wiederherstellung vorher fehl (ungültiges/beschädigtes Archiv o. Ä.),
|
||||||
|
// ist instancesDir noch der unveränderte Originalbestand - den lassen wir
|
||||||
|
// dann bewusst in Ruhe, statt ihn zu löschen.
|
||||||
|
if (originalMovedAway) {
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(instancesDir)) fs.rmSync(instancesDir, { recursive: true, force: true });
|
if (fs.existsSync(instancesDir)) fs.rmSync(instancesDir, { recursive: true, force: true });
|
||||||
if (fs.existsSync(rollbackInstances)) fs.cpSync(rollbackInstances, instancesDir, { recursive: true });
|
if (fs.existsSync(rollbackInstances)) fs.cpSync(rollbackInstances, instancesDir, { recursive: true });
|
||||||
@@ -424,6 +435,7 @@ async function restoreGlobalBackup(options) {
|
|||||||
else if (!settingsPreviouslyExisted && fs.existsSync(settingsFile)) fs.rmSync(settingsFile, { force: true });
|
else if (!settingsPreviouslyExisted && fs.existsSync(settingsFile)) fs.rmSync(settingsFile, { force: true });
|
||||||
}
|
}
|
||||||
} catch { /* ignore rollback errors */ }
|
} catch { /* ignore rollback errors */ }
|
||||||
|
}
|
||||||
throw err;
|
throw err;
|
||||||
} finally {
|
} finally {
|
||||||
try { fs.rmSync(tmp, { recursive: true, force: true }); } catch { /* ignore */ }
|
try { fs.rmSync(tmp, { recursive: true, force: true }); } catch { /* ignore */ }
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
'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 };
|
||||||
+22
-4
@@ -32,6 +32,7 @@ const crashreports = require('./crashreports');
|
|||||||
const skins = require('./skins');
|
const skins = require('./skins');
|
||||||
const servers = require('./servers');
|
const servers = require('./servers');
|
||||||
const mcping = require('./mcping');
|
const mcping = require('./mcping');
|
||||||
|
const discordpresence = require('./discordpresence');
|
||||||
|
|
||||||
// undici als globales fetch verwenden -> ermöglicht Proxy via setGlobalDispatcher
|
// undici als globales fetch verwenden -> ermöglicht Proxy via setGlobalDispatcher
|
||||||
const undici = require('undici');
|
const undici = require('undici');
|
||||||
@@ -269,7 +270,16 @@ function destroyTray() {
|
|||||||
// Windows-Autostart-Eintrag setzen/entfernen + Tray-Symbol passend ein-/ausblenden
|
// Windows-Autostart-Eintrag setzen/entfernen + Tray-Symbol passend ein-/ausblenden
|
||||||
function applyAutostart(enabled) {
|
function applyAutostart(enabled) {
|
||||||
try {
|
try {
|
||||||
app.setLoginItemSettings({ openAtLogin: !!enabled, args: enabled ? ['--hidden'] : [] });
|
// Gleiches Problem wie bei den Desktop-Verknüpfungen (siehe verknuepfungsArgs
|
||||||
|
// weiter oben): im Entwicklungsmodus zeigt process.execPath nur auf die nackte
|
||||||
|
// electron.exe, die ohne Pfadangabe ihren eigenen leeren Startbildschirm zeigt
|
||||||
|
// statt AeroMC zu laden. Zusätzlich: bei der Portable-Fassung zeigt
|
||||||
|
// process.execPath auf den entpackten Temp-Ordner – der wäre morgen tot,
|
||||||
|
// deshalb wie bei den Verknüpfungen über verknuepfungsZiel() auflösen.
|
||||||
|
const args = enabled
|
||||||
|
? (app.isPackaged ? ['--hidden'] : [path.join(__dirname, '..'), '--hidden'])
|
||||||
|
: [];
|
||||||
|
app.setLoginItemSettings({ openAtLogin: !!enabled, path: verknuepfungsZiel(), args });
|
||||||
} catch { /* z. B. in portabler Umgebung ohne Schreibrechte auf die Registry */ }
|
} catch { /* z. B. in portabler Umgebung ohne Schreibrechte auf die Registry */ }
|
||||||
if (enabled) createTray();
|
if (enabled) createTray();
|
||||||
else destroyTray();
|
else destroyTray();
|
||||||
@@ -288,6 +298,7 @@ app.whenReady().then(() => {
|
|||||||
decrypt: (b) => safeStorage.decryptString(Buffer.from(b, 'base64')),
|
decrypt: (b) => safeStorage.decryptString(Buffer.from(b, 'base64')),
|
||||||
});
|
});
|
||||||
applyProxy(store.getSettings());
|
applyProxy(store.getSettings());
|
||||||
|
discordpresence.configure(store.getSettings());
|
||||||
const autostartAn = !!store.getSettings().autostart;
|
const autostartAn = !!store.getSettings().autostart;
|
||||||
// Autostart-Eintrag/Tray mit der Einstellung synchron halten (falls z. B.
|
// Autostart-Eintrag/Tray mit der Einstellung synchron halten (falls z. B.
|
||||||
// von Hand an der Registry gedreht wurde oder nach einem Update)
|
// von Hand an der Registry gedreht wurde oder nach einem Update)
|
||||||
@@ -353,7 +364,7 @@ app.on('window-all-closed', () => {
|
|||||||
if (process.platform !== 'darwin') app.quit();
|
if (process.platform !== 'darwin') app.quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.on('before-quit', () => { appIsQuitting = true; });
|
app.on('before-quit', () => { appIsQuitting = true; discordpresence.shutdown(); });
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Java-Erkennung (für Anzeige in den Einstellungen)
|
// Java-Erkennung (für Anzeige in den Einstellungen)
|
||||||
@@ -381,6 +392,7 @@ ipcMain.handle('settings:save', (_e, patch) => {
|
|||||||
const s = store.saveSettings(patch);
|
const s = store.saveSettings(patch);
|
||||||
applyProxy(s);
|
applyProxy(s);
|
||||||
if (patch && Object.prototype.hasOwnProperty.call(patch, 'autostart')) applyAutostart(s.autostart);
|
if (patch && Object.prototype.hasOwnProperty.call(patch, 'autostart')) applyAutostart(s.autostart);
|
||||||
|
if (patch && Object.prototype.hasOwnProperty.call(patch, 'discordClientId')) discordpresence.configure(s);
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1926,9 +1938,15 @@ ipcMain.handle('instances:launch', async (_e, id, accountId, launchOpts) => {
|
|||||||
if (evt.phase === 'launch') {
|
if (evt.phase === 'launch') {
|
||||||
launchStart = Date.now();
|
launchStart = Date.now();
|
||||||
if (!gezaehlt) { gezaehlt = true; kontoSpieltJetzt(kontoId); }
|
if (!gezaehlt) { gezaehlt = true; kontoSpieltJetzt(kontoId); }
|
||||||
|
discordpresence.setActivity({
|
||||||
|
details: 'Spielt Minecraft',
|
||||||
|
state: `${inst.name} · ${inst.minecraft.version}`,
|
||||||
|
startTimestamp: launchStart,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (evt.phase === 'exit') {
|
if (evt.phase === 'exit') {
|
||||||
if (gezaehlt) { gezaehlt = false; kontoSpieltNichtMehr(kontoId); }
|
if (gezaehlt) { gezaehlt = false; kontoSpieltNichtMehr(kontoId); }
|
||||||
|
discordpresence.clearActivity();
|
||||||
if (launchStart) {
|
if (launchStart) {
|
||||||
const secs = Math.max(0, Math.round((Date.now() - launchStart) / 1000));
|
const secs = Math.max(0, Math.round((Date.now() - launchStart) / 1000));
|
||||||
launchStart = 0; // Spielzeit nur einmal gutschreiben
|
launchStart = 0; // Spielzeit nur einmal gutschreiben
|
||||||
@@ -1942,11 +1960,11 @@ ipcMain.handle('instances:launch', async (_e, id, accountId, launchOpts) => {
|
|||||||
});
|
});
|
||||||
// Start fehlgeschlagen, obwohl schon gezählt -> Zählung zurücknehmen,
|
// Start fehlgeschlagen, obwohl schon gezählt -> Zählung zurücknehmen,
|
||||||
// sonst bliebe das Konto für immer als "spielt" stehen
|
// sonst bliebe das Konto für immer als "spielt" stehen
|
||||||
if (!res.ok && gezaehlt) { gezaehlt = false; kontoSpieltNichtMehr(kontoId); }
|
if (!res.ok && gezaehlt) { gezaehlt = false; kontoSpieltNichtMehr(kontoId); discordpresence.clearActivity(); }
|
||||||
if (res.ok) store.updateInstance(id, { lastPlayed: new Date().toISOString() });
|
if (res.ok) store.updateInstance(id, { lastPlayed: new Date().toISOString() });
|
||||||
return res;
|
return res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (gezaehlt) { gezaehlt = false; kontoSpieltNichtMehr(kontoId); }
|
if (gezaehlt) { gezaehlt = false; kontoSpieltNichtMehr(kontoId); discordpresence.clearActivity(); }
|
||||||
return { ok: false, message: 'Start fehlgeschlagen: ' + err.message };
|
return { ok: false, message: 'Start fehlgeschlagen: ' + err.message };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ const DEFAULT_SETTINGS = {
|
|||||||
bedrockEnabled: true, // Bedrock-Bereich anzeigen (nur wenn auch installiert)
|
bedrockEnabled: true, // Bedrock-Bereich anzeigen (nur wenn auch installiert)
|
||||||
desktopNotifications: true, // Windows-Meldung bei fertigem Hintergrund-Download/-Backup
|
desktopNotifications: true, // Windows-Meldung bei fertigem Hintergrund-Download/-Backup
|
||||||
autostart: false, // mit Windows starten, im Infobereich statt als Fenster
|
autostart: false, // mit Windows starten, im Infobereich statt als Fenster
|
||||||
|
discordClientId: '', // optional, nur per Hand in settings.json; leer => eingebaute AeroMC-App-ID
|
||||||
bgSkin: '', // '' = aus, 'active' = aktives Konto, sonst Konto-UUID
|
bgSkin: '', // '' = aus, 'active' = aktives Konto, sonst Konto-UUID
|
||||||
bgSkinOpacity: 55, // Deckkraft des Hintergrund-Skins in %
|
bgSkinOpacity: 55, // Deckkraft des Hintergrund-Skins in %
|
||||||
bgSkinPose: 'walking', // Pose des 3D-Renders (falls der Pose-Dienst erreichbar ist)
|
bgSkinPose: 'walking', // Pose des 3D-Renders (falls der Pose-Dienst erreichbar ist)
|
||||||
|
|||||||
Reference in New Issue
Block a user