Skip to content

Commit 0333155

Browse files
v3.5.0
1 parent 1377ece commit 0333155

7 files changed

Lines changed: 438 additions & 45 deletions

File tree

Click_stereo.ogg.mp3

6.16 KB
Binary file not shown.

index.html

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,10 @@
195195
<input type="text" id="install-path-input" class="mc-input nav-item !mb-0" placeholder="Default: Documents/LegacyClient" tabindex="0">
196196
<div class="btn-mc btn-mini nav-item !w-[60px] !h-[48px]" onclick="browseInstallDir()" tabindex="0">...</div>
197197
</div>
198-
<div class="btn-mc w-full !h-[40px] !text-lg !mb-0 nav-item" onclick="openGameDir()" tabindex="0">OPEN FOLDER</div>
198+
<div class="flex gap-2">
199+
<div class="btn-mc flex-grow !h-[40px] !text-lg !mb-0 nav-item" onclick="openGameDir()" tabindex="0">GAME FOLDER</div>
200+
<div class="btn-mc flex-grow !h-[40px] !text-lg !mb-0 nav-item" onclick="openScreenshotsGallery()" tabindex="0">SCREENSHOTS</div>
201+
</div>
199202
</div>
200203

201204
<div class="mc-input-group">
@@ -232,7 +235,10 @@
232235

233236
<div class="mc-input-group">
234237
<label class="mc-label">Launcher Music Volume:</label>
235-
<input type="range" id="volume-slider" min="0" max="1" step="0.05" value="1" class="nav-item w-full" tabindex="0">
238+
<div class="mc-slider-container">
239+
<input type="range" id="volume-slider" min="0" max="1" step="0.01" value="1" class="mc-slider nav-item w-full" tabindex="0">
240+
<div id="volume-percent" class="mc-slider-percent">100%</div>
241+
</div>
236242
</div>
237243

238244
<div class="grid grid-cols-2 gap-4 w-full mt-2">
@@ -293,6 +299,21 @@
293299
</div>
294300
</div>
295301

302+
<div class="modal-overlay" id="gallery-modal">
303+
<div class="modal-box" style="max-width: 1000px; width: 85vw; height: 85vh;">
304+
<div class="modal-title">SCREENSHOTS GALLERY</div>
305+
306+
<div id="gallery-container" class="w-full flex-grow overflow-y-auto mb-6 border-2 border-[#555] bg-black p-4 grid grid-cols-2 md:grid-cols-3 gap-4 auto-rows-max">
307+
<!-- Screenshots will be dynamically loaded here -->
308+
</div>
309+
310+
<div class="flex gap-4 w-full">
311+
<div class="btn-mc flex-grow nav-item" onclick="openScreenshotsDir()" tabindex="0">OPEN FOLDER</div>
312+
<div class="btn-mc flex-grow nav-item" onclick="toggleGallery(false)" tabindex="0">DONE</div>
313+
</div>
314+
</div>
315+
</div>
316+
296317
<div class="modal-overlay" id="profile-modal">
297318
<div class="modal-box">
298319
<div class="modal-title">PLAYER PROFILE</div>

main.js

Lines changed: 108 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { app, BrowserWindow, shell, ipcMain, dialog } = require('electron');
1+
const { app, BrowserWindow, shell, ipcMain, dialog, globalShortcut, desktopCapturer } = require('electron');
22
const path = require('path');
33
const Store = require('electron-store');
44
const fs = require('fs');
@@ -7,9 +7,11 @@ const extractZip = require('extract-zip');
77
const { exec } = require('child_process');
88

99
const store = new Store();
10+
let mainWindow = null;
11+
let isGameRunning = false;
1012

1113
function createWindow() {
12-
const win = new BrowserWindow({
14+
mainWindow = new BrowserWindow({
1315
width: 1280,
1416
height: 720,
1517
minWidth: 1024,
@@ -27,22 +29,115 @@ function createWindow() {
2729
}
2830
});
2931

30-
win.loadFile('index.html');
32+
mainWindow.loadFile('index.html');
3133

32-
ipcMain.on('window-minimize', () => win.minimize());
34+
ipcMain.on('window-minimize', () => mainWindow.minimize());
3335
ipcMain.on('window-maximize', () => {
34-
if (win.isMaximized()) {
35-
win.unmaximize();
36+
if (mainWindow.isMaximized()) {
37+
mainWindow.unmaximize();
3638
} else {
37-
win.maximize();
39+
mainWindow.maximize();
3840
}
3941
});
40-
ipcMain.on('window-close', () => win.close());
42+
ipcMain.on('window-close', () => mainWindow.close());
4143
ipcMain.on('window-fullscreen', () => {
42-
win.setFullScreen(!win.isFullScreen());
44+
mainWindow.setFullScreen(!mainWindow.isFullScreen());
4345
});
4446
ipcMain.on('window-set-fullscreen', (event, enabled) => {
45-
win.setFullScreen(Boolean(enabled));
47+
mainWindow.setFullScreen(Boolean(enabled));
48+
});
49+
50+
ipcMain.handle('take-screenshot', async (event) => {
51+
try {
52+
const screenshotsDir = path.join(app.getPath('userData'), 'Screenshots');
53+
if (!fs.existsSync(screenshotsDir)) {
54+
fs.mkdirSync(screenshotsDir, { recursive: true });
55+
}
56+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
57+
const fileName = `screenshot-${timestamp}.png`;
58+
const filePath = path.join(screenshotsDir, fileName);
59+
60+
if (isGameRunning) {
61+
const sources = await desktopCapturer.getSources({
62+
types: ['window', 'screen'],
63+
thumbnailSize: { width: 3840, height: 2160 } // High res for screenshot
64+
});
65+
66+
// Find Minecraft window or fallback to primary screen
67+
const source = sources.find(s => s.name.toLowerCase().includes('minecraft')) ||
68+
sources.find(s => s.id.startsWith('screen'));
69+
70+
if (source) {
71+
fs.writeFileSync(filePath, source.thumbnail.toPNG());
72+
return filePath;
73+
}
74+
}
75+
76+
// Fallback to launcher capture if game isn't running or not found
77+
const win = BrowserWindow.fromWebContents(event.sender) || mainWindow;
78+
if (!win) throw new Error("Window not found");
79+
const image = await win.capturePage();
80+
fs.writeFileSync(filePath, image.toPNG());
81+
return filePath;
82+
} catch (err) {
83+
console.error("Screenshot capture error:", err);
84+
throw err;
85+
}
86+
});
87+
88+
ipcMain.on('game-running-state', (event, running) => {
89+
isGameRunning = running;
90+
if (running) {
91+
globalShortcut.register('F2', () => {
92+
if (mainWindow) {
93+
mainWindow.webContents.send('trigger-screenshot');
94+
}
95+
});
96+
} else {
97+
globalShortcut.unregister('F2');
98+
}
99+
});
100+
101+
ipcMain.handle('list-screenshots', async () => {
102+
const screenshotsDir = path.join(app.getPath('userData'), 'Screenshots');
103+
if (!fs.existsSync(screenshotsDir)) {
104+
return [];
105+
}
106+
const files = fs.readdirSync(screenshotsDir);
107+
return files
108+
.filter(f => f.toLowerCase().endsWith('.png'))
109+
.sort((a, b) => {
110+
try {
111+
// Extract timestamp from 'screenshot-YYYY-MM-DDTHH-mm-ss-SSSZ.png'
112+
const timeA = a.replace('screenshot-', '').replace('.png', '').replace(/-/g, ':');
113+
const timeB = b.replace('screenshot-', '').replace('.png', '').replace(/-/g, ':');
114+
return new Date(timeB) - new Date(timeA);
115+
} catch (e) {
116+
return 0;
117+
}
118+
})
119+
.map(f => ({
120+
name: f,
121+
path: path.join(screenshotsDir, f),
122+
url: `file://${path.join(screenshotsDir, f)}`
123+
}));
124+
});
125+
126+
ipcMain.handle('delete-screenshot', async (event, fileName) => {
127+
const filePath = path.join(app.getPath('userData'), 'Screenshots', fileName);
128+
if (fs.existsSync(filePath)) {
129+
fs.unlinkSync(filePath);
130+
return true;
131+
}
132+
return false;
133+
});
134+
135+
ipcMain.handle('open-screenshots-dir', async () => {
136+
const screenshotsDir = path.join(app.getPath('userData'), 'Screenshots');
137+
if (!fs.existsSync(screenshotsDir)) {
138+
fs.mkdirSync(screenshotsDir, { recursive: true });
139+
}
140+
shell.openPath(screenshotsDir);
46141
});
47142

48143
ipcMain.handle('store-get', (event, key) => store.get(key));
@@ -55,10 +150,10 @@ function createWindow() {
55150
return result.filePaths[0];
56151
});
57152

58-
win.on('maximize', () => win.webContents.send('window-is-maximized', true));
59-
win.on('unmaximize', () => win.webContents.send('window-is-maximized', false));
153+
mainWindow.on('maximize', () => mainWindow.webContents.send('window-is-maximized', true));
154+
mainWindow.on('unmaximize', () => mainWindow.webContents.send('window-is-maximized', false));
60155

61-
win.webContents.setWindowOpenHandler(({ url }) => {
156+
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
62157
shell.openExternal(url);
63158
return { action: 'deny' };
64159
});

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "legacylauncher",
3-
"version": "3.0.1",
3+
"version": "3.5.0",
44
"description": "",
55
"main": "main.js",
66
"scripts": {
@@ -30,7 +30,15 @@
3030
"flatpak"
3131
],
3232
"category": "Game",
33-
"icon": "512x512.png"
33+
"icon": "512x512.png",
34+
"desktop": {
35+
"Name": "Minecraft LCE Launcher",
36+
"GenericName": "Minecraft Launcher",
37+
"Comment": "A Minecraft: Legacy Console Edition launcher",
38+
"Categories": "Game;Emulation;",
39+
"StartupNotify": "true"
40+
},
41+
"executableName": "legacylauncher"
3442
},
3543
"mac": {
3644
"target": [

0 commit comments

Comments
 (0)