1- const { app, BrowserWindow, Tray, Menu, ipcMain } = require ( 'electron' ) ;
1+ const { app, BrowserWindow, Tray, Menu, dialog, ipcMain } = require ( 'electron' ) ;
2+ require ( 'dotenv' ) . config ( ) ;
23const path = require ( 'path' ) ;
34const fs = require ( 'fs' ) ;
45const Registry = require ( 'winreg' ) ;
6+ const DiscordRPC = require ( 'discord-rpc' ) ;
57
68let mainWindow ;
79let tray = null ;
810
11+ const clientId = process . env . DISCORD_CLIENT_ID ;
12+ if ( ! clientId ) {
13+ console . error ( 'DISCORD_CLIENT_ID not found in .env file. Discord RPC will not work.' ) ;
14+ }
15+
16+ const rpc = new DiscordRPC . Client ( { transport : 'ipc' } ) ;
17+ let rpcReady = false ;
18+
19+ if ( clientId ) {
20+ DiscordRPC . register ( clientId ) ;
21+
22+ rpc . on ( 'ready' , ( ) => {
23+ console . log ( 'Discord RPC is ready' ) ;
24+ rpcReady = true ;
25+ updateDiscordActivity ( ) ;
26+ } ) ;
27+
28+ rpc . on ( 'error' , ( err ) => {
29+ console . error ( 'Discord RPC error:' , err ) ;
30+ } ) ;
31+
32+ rpc . login ( { clientId } ) . catch ( console . error ) ;
33+ }
34+
35+ function updateDiscordActivity ( clientId , theme ) {
36+ if ( ! rpcReady ) return ;
37+ rpc . setActivity ( {
38+ details : `Using ${ theme } theme` ,
39+ state : `On ${ clientId } Client Page` ,
40+ startTimestamp : Math . floor ( Date . now ( ) / 1000 ) ,
41+ largeImageKey : 'twl_main' ,
42+ largeImageText : '@noxygalaxy' ,
43+ instance : false ,
44+ } ) ;
45+ console . log ( `Discord activity updated for ${ clientId } with ${ theme } theme` ) ;
46+ }
47+
48+ const configPath = path . join ( app . getPath ( 'appData' ) , 'TWLauncher' , 'twlconfig.json' ) ;
49+ let config = { installPath : path . join ( app . getPath ( 'appData' ) , 'TWLauncher' , 'clients' ) , theme : 'default' } ;
50+
51+ if ( fs . existsSync ( configPath ) ) {
52+ config = JSON . parse ( fs . readFileSync ( configPath , 'utf8' ) ) ;
53+ }
54+
55+ function saveConfig ( ) {
56+ fs . writeFileSync ( configPath , JSON . stringify ( config , null , 2 ) ) ;
57+ }
58+
959function createWindow ( ) {
1060 mainWindow = new BrowserWindow ( {
1161 width : 1280 ,
@@ -26,6 +76,10 @@ function createWindow() {
2676 mainWindow . hide ( ) ;
2777 } ) ;
2878
79+ mainWindow . webContents . on ( 'did-finish-load' , ( ) => {
80+ mainWindow . webContents . send ( 'apply-theme' , config . theme ) ;
81+ } ) ;
82+
2983 createTray ( ) ;
3084}
3185
@@ -204,6 +258,42 @@ function launchGame(id) {
204258 mainWindow . webContents . send ( 'launch-game' , id ) ;
205259}
206260
261+ ipcMain . handle ( 'change-install-path' , async ( ) => {
262+ const result = await dialog . showOpenDialog ( mainWindow , {
263+ properties : [ 'openDirectory' ] ,
264+ title : 'Select Installation Directory'
265+ } ) ;
266+ if ( ! result . canceled && result . filePaths . length > 0 ) {
267+ config . installPath = result . filePaths [ 0 ] ;
268+ saveConfig ( ) ;
269+ return config . installPath ;
270+ }
271+ return null ;
272+ } ) ;
273+
274+ ipcMain . handle ( 'get-install-path' , ( ) => {
275+ return config . installPath ;
276+ } ) ;
277+
278+ ipcMain . on ( 'save-settings' , ( event , { installPath, theme } ) => {
279+ config . installPath = installPath ;
280+ config . theme = theme ;
281+ saveConfig ( ) ;
282+ mainWindow . webContents . send ( 'apply-theme' , theme ) ;
283+ } ) ;
284+
285+ ipcMain . on ( 'select-client' , ( event , clientId ) => {
286+ mainWindow . webContents . send ( 'client-selected' , clientId ) ;
287+ } ) ;
288+
289+ ipcMain . handle ( 'get-initial-theme' , ( ) => {
290+ return config . theme ;
291+ } ) ;
292+
293+ ipcMain . on ( 'update-discord-rpc' , ( event , { clientId, theme } ) => {
294+ updateDiscordActivity ( clientId , theme ) ;
295+ } ) ;
296+
207297ipcMain . on ( 'minimize-window' , ( ) => {
208298 mainWindow . minimize ( ) ;
209299} ) ;
@@ -215,6 +305,9 @@ ipcMain.on('hide-window', () => {
215305 content : 'Launcher will work in background, to close it right click on the tray icon' ,
216306 icon : path . join ( __dirname , 'src' , 'assets' , 'logos' , 'twl.png' ) ,
217307 } ) ;
308+ if ( rpcReady ) {
309+ rpc . destroy ( ) ;
310+ }
218311} ) ;
219312
220313ipcMain . on ( 'launch-game' , async ( ) => {
@@ -223,8 +316,7 @@ ipcMain.on('launch-game', async () => {
223316} ) ;
224317
225318app . whenReady ( ) . then ( ( ) => {
226- const appDataPath = app . getPath ( 'appData' ) ;
227- const clientsPath = path . join ( appDataPath , 'TWLauncher' , 'clients' ) ;
319+ const clientsPath = config . installPath ;
228320
229321 if ( ! fs . existsSync ( clientsPath ) ) {
230322 fs . mkdirSync ( clientsPath , { recursive : true } ) ;
0 commit comments