mirror of
https://github.com/gradenGnostic/LegacyLauncher.git
synced 2026-08-20 04:28:19 +00:00
bug fixes
This commit is contained in:
parent
944fdc5232
commit
f5d44043a7
|
|
@ -1,7 +1,6 @@
|
||||||
# LegacyLauncher
|
# LegacyLauncher
|
||||||
|
|
||||||
A custom launcher for Minecraft Legacy Console Edition.
|
A custom launcher for Minecraft Legacy Console Edition.
|
||||||
<img width="1276" height="718" alt="image" src="https://github.com/user-attachments/assets/abc487f1-9919-429b-8311-5b2dd637b35f" />
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
|
||||||
15
index.html
15
index.html
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>LegacyLauncher</title>
|
<title>LegacyLauncher</title>
|
||||||
<link rel="icon" type="image/png" href="256x256.png">
|
<link rel="icon" type="image/png" href="512x512.png">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -139,14 +139,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-overlay" id="update-modal">
|
<div class="modal-overlay" id="update-modal">
|
||||||
<div class="modal-box">
|
<div class="modal-box relative">
|
||||||
|
<div class="modal-close-btn" id="btn-close-update">×</div>
|
||||||
<div class="modal-title">UPDATE AVAILABLE</div>
|
<div class="modal-title">UPDATE AVAILABLE</div>
|
||||||
<p id="update-modal-text" style="color: #333; font-size: 22px; text-align: center; margin-bottom: 30px; text-shadow: 1px 1px 0 #fff; line-height: 1.4;">
|
<div id="update-modal-text" class="modal-body-text">
|
||||||
A new version is available. Would you like to update now?
|
A new version is available. Would you like to update now?
|
||||||
</p>
|
</div>
|
||||||
<div class="flex flex-col gap-4 w-full">
|
<div class="flex gap-4 w-full">
|
||||||
<div class="btn-mc w-full" id="btn-confirm-update">UPDATE NOW</div>
|
<div class="btn-mc flex-grow" id="btn-confirm-update">UPDATE NOW</div>
|
||||||
<div class="btn-mc w-full" id="btn-skip-update">LATER (LAUNCH OLD)</div>
|
<div class="btn-mc flex-grow" id="btn-skip-update">LATER</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
2
main.js
2
main.js
|
|
@ -17,7 +17,7 @@ function createWindow() {
|
||||||
center: true,
|
center: true,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
frame: false,
|
frame: false,
|
||||||
icon: path.join(__dirname, '256x256.png'),
|
icon: path.join(__dirname, '512x512.png'),
|
||||||
transparent: true,
|
transparent: true,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
|
|
|
||||||
66
renderer.js
66
renderer.js
|
|
@ -304,12 +304,13 @@ async function launchGame() {
|
||||||
setProcessingState(true);
|
setProcessingState(true);
|
||||||
await handleElectronFlow(asset.browser_download_url);
|
await handleElectronFlow(asset.browser_download_url);
|
||||||
setProcessingState(false);
|
setProcessingState(false);
|
||||||
} else {
|
} else if (choice === 'launch') {
|
||||||
setProcessingState(true);
|
setProcessingState(true);
|
||||||
updateProgress(100, "Launching Existing...");
|
updateProgress(100, "Launching Existing...");
|
||||||
await launchLocalClient();
|
await launchLocalClient();
|
||||||
setProcessingState(false);
|
setProcessingState(false);
|
||||||
}
|
}
|
||||||
|
// if 'cancel', do nothing
|
||||||
} else {
|
} else {
|
||||||
setProcessingState(true);
|
setProcessingState(true);
|
||||||
await handleElectronFlow(asset.browser_download_url);
|
await handleElectronFlow(asset.browser_download_url);
|
||||||
|
|
@ -325,6 +326,7 @@ async function promptUpdate(newTag) {
|
||||||
const modal = document.getElementById('update-modal');
|
const modal = document.getElementById('update-modal');
|
||||||
const confirmBtn = document.getElementById('btn-confirm-update');
|
const confirmBtn = document.getElementById('btn-confirm-update');
|
||||||
const skipBtn = document.getElementById('btn-skip-update');
|
const skipBtn = document.getElementById('btn-skip-update');
|
||||||
|
const closeBtn = document.getElementById('btn-close-update');
|
||||||
const installedTag = await Store.get('installed_version_tag', "Unknown");
|
const installedTag = await Store.get('installed_version_tag', "Unknown");
|
||||||
|
|
||||||
document.getElementById('update-modal-text').innerHTML =
|
document.getElementById('update-modal-text').innerHTML =
|
||||||
|
|
@ -340,11 +342,13 @@ async function promptUpdate(newTag) {
|
||||||
setTimeout(() => modal.style.display = 'none', 300);
|
setTimeout(() => modal.style.display = 'none', 300);
|
||||||
confirmBtn.onclick = null;
|
confirmBtn.onclick = null;
|
||||||
skipBtn.onclick = null;
|
skipBtn.onclick = null;
|
||||||
|
closeBtn.onclick = null;
|
||||||
resolve(result);
|
resolve(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
confirmBtn.onclick = () => cleanup('update');
|
confirmBtn.onclick = () => cleanup('update');
|
||||||
skipBtn.onclick = () => cleanup('launch');
|
skipBtn.onclick = () => cleanup('launch');
|
||||||
|
closeBtn.onclick = () => cleanup('cancel');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,26 +371,19 @@ async function checkForUpdatesManual() {
|
||||||
// Prompt user to update/install; Update path will reinstall (delete existing LegacyClient)
|
// Prompt user to update/install; Update path will reinstall (delete existing LegacyClient)
|
||||||
const choice = await promptUpdate(rel.tag_name);
|
const choice = await promptUpdate(rel.tag_name);
|
||||||
if (choice === 'update') {
|
if (choice === 'update') {
|
||||||
// Delete existing LegacyClient folder if present to ensure clean install
|
|
||||||
try {
|
|
||||||
const extractDir = require('path').join(require('os').homedir(), 'Documents', 'LegacyClient');
|
|
||||||
if (require('fs').existsSync(extractDir)) {
|
|
||||||
require('fs').rmSync(extractDir, { recursive: true, force: true });
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// ignore cleanup errors
|
|
||||||
}
|
|
||||||
// Re-download and install (and launch, as install flow does)
|
// Re-download and install (and launch, as install flow does)
|
||||||
|
// handleElectronFlow now manages clean installation while preserving user data
|
||||||
setProcessingState(true);
|
setProcessingState(true);
|
||||||
await handleElectronFlow(asset.browser_download_url);
|
await handleElectronFlow(asset.browser_download_url);
|
||||||
setProcessingState(false);
|
setProcessingState(false);
|
||||||
} else {
|
} else if (choice === 'launch') {
|
||||||
// User chose to launch existing/older version
|
// User chose to launch existing/older version
|
||||||
setProcessingState(true);
|
setProcessingState(true);
|
||||||
updateProgress(100, "Launching Existing...");
|
updateProgress(100, "Launching Existing...");
|
||||||
await launchLocalClient();
|
await launchLocalClient();
|
||||||
setProcessingState(false);
|
setProcessingState(false);
|
||||||
}
|
}
|
||||||
|
// if 'cancel', do nothing
|
||||||
updatePlayButtonText();
|
updatePlayButtonText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,16 +475,63 @@ async function handleElectronFlow(url) {
|
||||||
const docDir = path.join(homeDir, 'Documents');
|
const docDir = path.join(homeDir, 'Documents');
|
||||||
const zipPath = path.join(docDir, TARGET_FILE);
|
const zipPath = path.join(docDir, TARGET_FILE);
|
||||||
const extractDir = path.join(docDir, 'LegacyClient');
|
const extractDir = path.join(docDir, 'LegacyClient');
|
||||||
|
const backupDir = path.join(docDir, 'LegacyClient_Backup');
|
||||||
|
|
||||||
updateProgress(5, "Downloading " + TARGET_FILE + "...");
|
updateProgress(5, "Downloading " + TARGET_FILE + "...");
|
||||||
await downloadFile(url, zipPath);
|
await downloadFile(url, zipPath);
|
||||||
|
|
||||||
updateProgress(75, "Extracting Archive...");
|
updateProgress(75, "Extracting Archive...");
|
||||||
|
|
||||||
|
// Files to preserve when updating
|
||||||
|
const preserveList = [
|
||||||
|
'options.txt',
|
||||||
|
'servers.txt',
|
||||||
|
'username.txt',
|
||||||
|
'settings.dat',
|
||||||
|
path.join('Windows64', 'GameHDD')
|
||||||
|
];
|
||||||
|
|
||||||
|
if (fs.existsSync(extractDir)) {
|
||||||
|
// Backup preserved files
|
||||||
|
if (fs.existsSync(backupDir)) fs.rmSync(backupDir, { recursive: true, force: true });
|
||||||
|
fs.mkdirSync(backupDir, { recursive: true });
|
||||||
|
|
||||||
|
for (const item of preserveList) {
|
||||||
|
const src = path.join(extractDir, item);
|
||||||
|
const dest = path.join(backupDir, item);
|
||||||
|
if (fs.existsSync(src)) {
|
||||||
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
||||||
|
fs.renameSync(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Clean install: remove old client files
|
||||||
|
try {
|
||||||
|
fs.rmSync(extractDir, { recursive: true, force: true });
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Cleanup error:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(extractDir)) {
|
if (!fs.existsSync(extractDir)) {
|
||||||
fs.mkdirSync(extractDir, { recursive: true });
|
fs.mkdirSync(extractDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
await extractZip(zipPath, { dir: extractDir });
|
await extractZip(zipPath, { dir: extractDir });
|
||||||
|
|
||||||
|
// Restore preserved files
|
||||||
|
if (fs.existsSync(backupDir)) {
|
||||||
|
for (const item of preserveList) {
|
||||||
|
const src = path.join(backupDir, item);
|
||||||
|
const dest = path.join(extractDir, item);
|
||||||
|
if (fs.existsSync(src)) {
|
||||||
|
if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true, force: true });
|
||||||
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
||||||
|
fs.renameSync(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs.rmSync(backupDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
|
||||||
const execName = await Store.get('legacy_exec_path', DEFAULT_EXEC);
|
const execName = await Store.get('legacy_exec_path', DEFAULT_EXEC);
|
||||||
const fullPath = path.join(extractDir, execName);
|
const fullPath = path.join(extractDir, execName);
|
||||||
|
|
||||||
|
|
|
||||||
31
style.css
31
style.css
|
|
@ -439,6 +439,23 @@ body {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-shadow: inset 4px 4px 0 #fff;
|
box-shadow: inset 4px 4px 0 #fff;
|
||||||
animation: modalPop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
animation: modalPop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 15px;
|
||||||
|
font-size: 32px;
|
||||||
|
color: #444;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.1s;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close-btn:hover {
|
||||||
|
color: #c42b1c;
|
||||||
|
text-shadow: 1px 1px 0 #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes modalPop {
|
@keyframes modalPop {
|
||||||
|
|
@ -454,6 +471,20 @@ body {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-body-text {
|
||||||
|
color: #333;
|
||||||
|
font-size: 22px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
text-shadow: 1px 1px 0 #fff;
|
||||||
|
line-height: 1.6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body-text b {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
.mc-input-group {
|
.mc-input-group {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue