mirror of
https://github.com/amiayweb/Hytale-F2P.git
synced 2026-02-26 09:31:45 -03:00
Merge branch 'develop' of https://github.com/amiayweb/Hytale-F2P into develop
This commit is contained in:
@@ -635,20 +635,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Installation effects overlay -->
|
|
||||||
<div id="installationEffects" class="installation-effects" style="display: none;">
|
|
||||||
<div class="space-effects">
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="chatUsernameModal" class="chat-username-modal" style="display: none;">
|
<div id="chatUsernameModal" class="chat-username-modal" style="display: none;">
|
||||||
<div class="chat-username-modal-content">
|
<div class="chat-username-modal-content">
|
||||||
<div class="chat-username-modal-header">
|
<div class="chat-username-modal-header">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
let CF_API_KEY = "$2a$10$bqk254NMZOWVTzLVJCcxEOmhcyUujKxA5xk.kQCN9q0KNYFJd5b32";
|
let API_KEY = "$2a$10$bqk254NMZOWVTzLVJCcxEOmhcyUujKxA5xk.kQCN9q0KNYFJd5b32";
|
||||||
const CURSEFORGE_API = 'https://api.curseforge.com/v1';
|
const CURSEFORGE_API = 'https://api.curseforge.com/v1';
|
||||||
const HYTALE_GAME_ID = 70216;
|
const HYTALE_GAME_ID = 70216;
|
||||||
|
|
||||||
@@ -12,7 +12,9 @@ let modsTotalPages = 1;
|
|||||||
|
|
||||||
export async function initModsManager() {
|
export async function initModsManager() {
|
||||||
try {
|
try {
|
||||||
console.log('Loaded API Key:', CF_API_KEY ? 'Yes' : 'No');
|
if (window.electronAPI && window.electronAPI.getEnvVar) {
|
||||||
|
console.log('Loaded API Key:', API_KEY ? 'Yes' : 'No');
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to load API Key:', err);
|
console.error('Failed to load API Key:', err);
|
||||||
}
|
}
|
||||||
@@ -194,7 +196,7 @@ async function loadBrowseMods() {
|
|||||||
browseContainer.innerHTML = `<div class="loading-mods"><div class="loading-spinner"></div><span>${window.i18n ? window.i18n.t('mods.loadingMods') : 'Loading mods from CurseForge...'}</span></div>`;
|
browseContainer.innerHTML = `<div class="loading-mods"><div class="loading-spinner"></div><span>${window.i18n ? window.i18n.t('mods.loadingMods') : 'Loading mods from CurseForge...'}</span></div>`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!CF_API_KEY || CF_API_KEY.length < 10) {
|
if (!API_KEY || API_KEY.length < 10) {
|
||||||
browseContainer.innerHTML = `
|
browseContainer.innerHTML = `
|
||||||
<div class=\"empty-browse-mods\">
|
<div class=\"empty-browse-mods\">
|
||||||
<i class=\"fas fa-key\"></i>
|
<i class=\"fas fa-key\"></i>
|
||||||
@@ -221,7 +223,7 @@ async function loadBrowseMods() {
|
|||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
'x-api-key': CF_API_KEY,
|
'x-api-key': API_KEY,
|
||||||
'Accept': 'application/json'
|
'Accept': 'application/json'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -207,11 +207,6 @@ function setupSettingsElements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (closeLauncherCheck) {
|
|
||||||
closeLauncherCheck.addEventListener('change', saveCloseLauncher);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UUID event listeners
|
// UUID event listeners
|
||||||
if (copyUuidBtn) {
|
if (copyUuidBtn) {
|
||||||
copyUuidBtn.addEventListener('click', copyCurrentUuid);
|
copyUuidBtn.addEventListener('click', copyCurrentUuid);
|
||||||
@@ -397,31 +392,6 @@ async function loadCloseLauncher() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function saveCloseLauncher() {
|
|
||||||
try {
|
|
||||||
if (window.electronAPI && window.electronAPI.saveCloseLauncher && closeLauncherCheck) {
|
|
||||||
const enabled = closeLauncherCheck.checked;
|
|
||||||
await window.electronAPI.saveCloseLauncher(enabled);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error saving close launcher setting:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadCloseLauncher() {
|
|
||||||
try {
|
|
||||||
if (window.electronAPI && window.electronAPI.loadCloseLauncher) {
|
|
||||||
const enabled = await window.electronAPI.loadCloseLauncher();
|
|
||||||
if (closeLauncherCheck) {
|
|
||||||
closeLauncherCheck.checked = enabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error loading close launcher setting:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function savePlayerName() {
|
async function savePlayerName() {
|
||||||
try {
|
try {
|
||||||
if (!window.electronAPI || !settingsPlayerName) return;
|
if (!window.electronAPI || !settingsPlayerName) return;
|
||||||
|
|||||||
@@ -638,9 +638,6 @@ function setupUI() {
|
|||||||
// Setup retry button
|
// Setup retry button
|
||||||
setupRetryButton();
|
setupRetryButton();
|
||||||
|
|
||||||
// Setup draggable progress bar
|
|
||||||
setupProgressDrag();
|
|
||||||
|
|
||||||
lockPlayButton(true);
|
lockPlayButton(true);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -741,6 +738,7 @@ window.LauncherUI = {
|
|||||||
|
|
||||||
// Make installation effects globally available
|
// Make installation effects globally available
|
||||||
|
|
||||||
|
|
||||||
// Draggable progress bar functionality
|
// Draggable progress bar functionality
|
||||||
function setupProgressDrag() {
|
function setupProgressDrag() {
|
||||||
if (!progressOverlay) return;
|
if (!progressOverlay) return;
|
||||||
|
|||||||
2
PKGBUILD
2
PKGBUILD
@@ -29,5 +29,5 @@ package() {
|
|||||||
mkdir -p "$pkgdir/opt/$_pkgname"
|
mkdir -p "$pkgdir/opt/$_pkgname"
|
||||||
cp -r "$_pkgname/dist/linux-unpacked/"* "$pkgdir/opt/$_pkgname"
|
cp -r "$_pkgname/dist/linux-unpacked/"* "$pkgdir/opt/$_pkgname"
|
||||||
install -Dm644 "$_pkgname.desktop" "$pkgdir/usr/share/applications/$_pkgname.desktop"
|
install -Dm644 "$_pkgname.desktop" "$pkgdir/usr/share/applications/$_pkgname.desktop"
|
||||||
install -Dm644 "$_pkgname/icon.png" "$pkgdir/usr/share/icons/hicolor/512x512/apps/$_pkgname.png"
|
install -Dm644 "$_pkgname/GUI/icon.png" "$pkgdir/usr/share/icons/hicolor/256x256/apps/$_pkgname.png"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,6 @@ class AppUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupAutoUpdater() {
|
setupAutoUpdater() {
|
||||||
// Enable dev mode for testing (reads dev-app-update.yml)
|
|
||||||
// Only enable in development, not in production builds
|
|
||||||
if (process.env.NODE_ENV === 'development' || !app.isPackaged) {
|
|
||||||
autoUpdater.forceDevUpdateConfig = true;
|
|
||||||
console.log('Dev update mode enabled - using dev-app-update.yml');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure logger for electron-updater
|
// Configure logger for electron-updater
|
||||||
// Create a compatible logger interface
|
// Create a compatible logger interface
|
||||||
|
|||||||
@@ -406,5 +406,6 @@ module.exports = {
|
|||||||
getJavaDetection,
|
getJavaDetection,
|
||||||
downloadJRE,
|
downloadJRE,
|
||||||
extractJRE,
|
extractJRE,
|
||||||
|
retryJREDownload,
|
||||||
JAVA_EXECUTABLE
|
JAVA_EXECUTABLE
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const { getModsPath, getProfilesDir } = require('../core/paths');
|
|||||||
const { saveModsToConfig, loadModsFromConfig } = require('../core/config');
|
const { saveModsToConfig, loadModsFromConfig } = require('../core/config');
|
||||||
const profileManager = require('./profileManager');
|
const profileManager = require('./profileManager');
|
||||||
|
|
||||||
const CF_API_KEY = "$2a$10$bqk254NMZOWVTzLVJCcxEOmhcyUujKxA5xk.kQCN9q0KNYFJd5b32";
|
const API_KEY = "$2a$10$bqk254NMZOWVTzLVJCcxEOmhcyUujKxA5xk.kQCN9q0KNYFJd5b32";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the physical mods path for a specific profile.
|
* Get the physical mods path for a specific profile.
|
||||||
@@ -120,7 +120,7 @@ async function downloadMod(modInfo) {
|
|||||||
if (!downloadUrl && modInfo.fileId && modInfo.modId) {
|
if (!downloadUrl && modInfo.fileId && modInfo.modId) {
|
||||||
const response = await axios.get(`https://api.curseforge.com/v1/mods/${modInfo.modId || modInfo.curseForgeId}/files/${modInfo.fileId || modInfo.curseForgeFileId}`, {
|
const response = await axios.get(`https://api.curseforge.com/v1/mods/${modInfo.modId || modInfo.curseForgeId}/files/${modInfo.fileId || modInfo.curseForgeFileId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'x-api-key': modInfo.apiKey || CF_API_KEY,
|
'x-api-key': modInfo.apiKey || API_KEY,
|
||||||
'Accept': 'application/json'
|
'Accept': 'application/json'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -393,7 +393,7 @@ async function syncModsForCurrentProfile() {
|
|||||||
...mod,
|
...mod,
|
||||||
modId: mod.curseForgeId,
|
modId: mod.curseForgeId,
|
||||||
fileId: mod.curseForgeFileId || mod.fileId,
|
fileId: mod.curseForgeFileId || mod.fileId,
|
||||||
apiKey: CF_API_KEY
|
apiKey: API_KEY
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`[ModManager] Auto-repair failed for "${mod.name}": ${err.message}`);
|
console.error(`[ModManager] Auto-repair failed for "${mod.name}": ${err.message}`);
|
||||||
|
|||||||
@@ -103,40 +103,36 @@ async function downloadFile(url, dest, progressCallback, maxRetries = 5) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
||||||
'Accept': '*/*',
|
'Accept': '*/*'
|
||||||
'Accept-Language': 'en-US,en;q=0.9',
|
|
||||||
'Referer': 'https://launcher.hytale.com/',
|
|
||||||
'Connection': 'keep-alive'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add Range header for resume capability
|
// Add Range header ONLY if resuming (startByte > 0)
|
||||||
if (startByte > 0) {
|
if (startByte > 0) {
|
||||||
headers['Range'] = `bytes=${startByte}-`;
|
headers['Range'] = `bytes=${startByte}-`;
|
||||||
|
console.log(`Adding Range header: bytes=${startByte}-`);
|
||||||
|
} else {
|
||||||
|
console.log('Fresh download, no Range header');
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: url,
|
url: url,
|
||||||
responseType: 'stream',
|
responseType: 'stream',
|
||||||
timeout: 60000, // 60 secondes timeout
|
timeout: 60000,
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
// Configuration Axios pour la robustesse réseau
|
|
||||||
validateStatus: function (status) {
|
validateStatus: function (status) {
|
||||||
// Accept both 200 (full download) and 206 (partial content for resume)
|
|
||||||
return (status >= 200 && status < 300) || status === 206;
|
return (status >= 200 && status < 300) || status === 206;
|
||||||
},
|
},
|
||||||
// Retry configuration
|
|
||||||
maxRedirects: 5,
|
maxRedirects: 5,
|
||||||
// Network resilience
|
family: 4
|
||||||
family: 4 // Force IPv4
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentLength = response.headers['content-length'];
|
const contentLength = response.headers['content-length'];
|
||||||
const totalSize = contentLength ? parseInt(contentLength, 10) + startByte : 0; // Adjust for resume
|
const totalSize = contentLength ? parseInt(contentLength, 10) + startByte : 0;
|
||||||
let downloaded = startByte; // Start with existing bytes
|
let downloaded = startByte;
|
||||||
lastProgressTime = Date.now(); // Update time after response received
|
lastProgressTime = Date.now();
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
// Check network status before attempting download
|
// Check network status before attempting download
|
||||||
@@ -344,8 +340,7 @@ async function downloadFile(url, dest, progressCallback, maxRetries = 5) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Si on arrive ici, le téléchargement a réussi
|
return dest;
|
||||||
return;
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
lastError = error;
|
lastError = error;
|
||||||
@@ -368,13 +363,16 @@ async function downloadFile(url, dest, progressCallback, maxRetries = 5) {
|
|||||||
// If file is substantial size (> 1.5GB), treat as success and break
|
// If file is substantial size (> 1.5GB), treat as success and break
|
||||||
if (sizeInMB >= 1500) {
|
if (sizeInMB >= 1500) {
|
||||||
console.log('File appears to be complete despite error, treating as success');
|
console.log('File appears to be complete despite error, treating as success');
|
||||||
return; // Exit the retry loop successfully
|
return dest; // Exit the retry loop successfully
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced file cleanup with validation
|
// Enhanced file cleanup with validation
|
||||||
if (fs.existsSync(dest)) {
|
if (fs.existsSync(dest)) {
|
||||||
try {
|
try {
|
||||||
|
// HTTP 416 = Range Not Satisfiable, delete corrupted partial file
|
||||||
|
const isRangeError = error.message && error.message.includes('416');
|
||||||
|
|
||||||
// Check if file is corrupted (small or invalid) or if error is non-resumable
|
// Check if file is corrupted (small or invalid) or if error is non-resumable
|
||||||
const partialStats = fs.statSync(dest);
|
const partialStats = fs.statSync(dest);
|
||||||
const isResumableError = error.message && (
|
const isResumableError = error.message && (
|
||||||
@@ -387,13 +385,14 @@ async function downloadFile(url, dest, progressCallback, maxRetries = 5) {
|
|||||||
// Check if download appears to be complete (close to expected PWR size)
|
// Check if download appears to be complete (close to expected PWR size)
|
||||||
const isPossiblyComplete = partialStats.size >= 1500 * 1024 * 1024; // >= 1.5GB
|
const isPossiblyComplete = partialStats.size >= 1500 * 1024 * 1024; // >= 1.5GB
|
||||||
|
|
||||||
if (partialStats.size < 1024 * 1024 || (!isResumableError && !isPossiblyComplete)) {
|
if (isRangeError || partialStats.size < 1024 * 1024 || (!isResumableError && !isPossiblyComplete)) {
|
||||||
// Delete if file is too small OR error is non-resumable AND not possibly complete
|
// Delete if HTTP 416 OR file is too small OR error is non-resumable AND not possibly complete
|
||||||
console.log(`[Cleanup] Removing PWR file (${!isResumableError && !isPossiblyComplete ? 'non-resumable error' : 'too small'}): ${(partialStats.size / 1024 / 1024).toFixed(2)} MB`);
|
const reason = isRangeError ? 'HTTP 416 range error' : (!isResumableError && !isPossiblyComplete ? 'non-resumable error' : 'too small');
|
||||||
|
console.log(`[Cleanup] Removing file (${reason}): ${(partialStats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||||
fs.unlinkSync(dest);
|
fs.unlinkSync(dest);
|
||||||
} else {
|
} else {
|
||||||
// Keep the file for resume on resumable errors or if possibly complete
|
// Keep the file for resume on resumable errors or if possibly complete
|
||||||
console.log(`[Resume] Keeping PWR file (${isPossiblyComplete ? 'possibly complete' : 'for resume'}): ${(partialStats.size / 1024 / 1024).toFixed(2)} MB`);
|
console.log(`[Resume] Keeping file (${isPossiblyComplete ? 'possibly complete' : 'for resume'}): ${(partialStats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||||
}
|
}
|
||||||
} catch (cleanupError) {
|
} catch (cleanupError) {
|
||||||
console.warn('Could not handle partial file:', cleanupError.message);
|
console.warn('Could not handle partial file:', cleanupError.message);
|
||||||
@@ -554,6 +553,17 @@ async function retryDownload(url, dest, progressCallback, previousError = null)
|
|||||||
fs.mkdirSync(destDir, { recursive: true });
|
fs.mkdirSync(destDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CRITICAL: Delete partial file before manual retry to avoid HTTP 416
|
||||||
|
if (fs.existsSync(dest)) {
|
||||||
|
try {
|
||||||
|
const stats = fs.statSync(dest);
|
||||||
|
console.log(`[Retry] Deleting partial file before retry: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||||
|
fs.unlinkSync(dest);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Could not delete partial file:', err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await downloadFile(url, dest, progressCallback, additionalRetries);
|
await downloadFile(url, dest, progressCallback, additionalRetries);
|
||||||
console.log('Manual retry successful');
|
console.log('Manual retry successful');
|
||||||
|
|||||||
15
main.js
15
main.js
@@ -1,4 +1,5 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
require('dotenv').config({ path: path.join(__dirname, '.env') });
|
||||||
const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');
|
const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');
|
||||||
const { autoUpdater } = require('electron-updater');
|
const { autoUpdater } = require('electron-updater');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@@ -446,6 +447,13 @@ ipcMain.handle('launch-game', async (event, playerName, javaPath, installPath, g
|
|||||||
|
|
||||||
ipcMain.handle('install-game', async (event, playerName, javaPath, installPath, branch) => {
|
ipcMain.handle('install-game', async (event, playerName, javaPath, installPath, branch) => {
|
||||||
try {
|
try {
|
||||||
|
console.log(`[IPC] install-game called with parameters:`);
|
||||||
|
console.log(` - playerName: ${playerName}`);
|
||||||
|
console.log(` - javaPath: ${javaPath}`);
|
||||||
|
console.log(` - installPath: ${installPath}`);
|
||||||
|
console.log(` - branch: ${branch}`);
|
||||||
|
console.log(`[IPC] branch type: ${typeof branch}, value: ${JSON.stringify(branch)}`);
|
||||||
|
|
||||||
// Signal installation start
|
// Signal installation start
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
mainWindow.webContents.send('installation-start');
|
mainWindow.webContents.send('installation-start');
|
||||||
@@ -625,6 +633,7 @@ ipcMain.handle('load-close-launcher', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('select-install-path', async () => {
|
ipcMain.handle('select-install-path', async () => {
|
||||||
|
|
||||||
const result = await dialog.showOpenDialog(mainWindow, {
|
const result = await dialog.showOpenDialog(mainWindow, {
|
||||||
properties: ['openDirectory'],
|
properties: ['openDirectory'],
|
||||||
title: 'Select Installation Folder'
|
title: 'Select Installation Folder'
|
||||||
@@ -742,8 +751,8 @@ ipcMain.handle('retry-download', async (event, retryData) => {
|
|||||||
console.log('[IPC] Full JRE retry data:', JSON.stringify(retryData, null, 2));
|
console.log('[IPC] Full JRE retry data:', JSON.stringify(retryData, null, 2));
|
||||||
|
|
||||||
const { retryJREDownload } = require('./backend/managers/javaManager');
|
const { retryJREDownload } = require('./backend/managers/javaManager');
|
||||||
await retryJREDownload(retryData.jreUrl, jreCacheFile, progressCallback);
|
|
||||||
const jreCacheFile = path.join(retryData.cacheDir, retryData.fileName);
|
const jreCacheFile = path.join(retryData.cacheDir, retryData.fileName);
|
||||||
|
await retryJREDownload(retryData.jreUrl, jreCacheFile, progressCallback);
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
@@ -930,6 +939,10 @@ ipcMain.handle('get-local-app-data', async () => {
|
|||||||
return process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
|
return process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('get-env-var', async (event, key) => {
|
||||||
|
return process.env[key];
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.handle('get-user-id', async () => {
|
ipcMain.handle('get-user-id', async () => {
|
||||||
try {
|
try {
|
||||||
const { getOrCreatePlayerId } = require('./backend/launcher');
|
const { getOrCreatePlayerId } = require('./backend/launcher');
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
"adm-zip": "^0.5.10",
|
"adm-zip": "^0.5.10",
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.6.0",
|
||||||
"discord-rpc": "^4.0.1",
|
"discord-rpc": "^4.0.1",
|
||||||
|
"dotenv": "^17.2.3",
|
||||||
"electron-updater": "^6.7.3",
|
"electron-updater": "^6.7.3",
|
||||||
"fs-extra": "^11.3.3",
|
"fs-extra": "^11.3.3",
|
||||||
"tar": "^6.2.1",
|
"tar": "^6.2.1",
|
||||||
@@ -68,7 +69,8 @@
|
|||||||
"preload.js",
|
"preload.js",
|
||||||
"backend/**/*",
|
"backend/**/*",
|
||||||
"GUI/**/*",
|
"GUI/**/*",
|
||||||
"package.json"
|
"package.json",
|
||||||
|
".env"
|
||||||
],
|
],
|
||||||
"win": {
|
"win": {
|
||||||
"target": [
|
"target": [
|
||||||
@@ -80,7 +82,7 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "build/icon.ico"
|
"icon": "icon.ico"
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
"target": [
|
"target": [
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||||||
openGameLocation: () => ipcRenderer.invoke('open-game-location'),
|
openGameLocation: () => ipcRenderer.invoke('open-game-location'),
|
||||||
saveSettings: (settings) => ipcRenderer.invoke('save-settings', settings),
|
saveSettings: (settings) => ipcRenderer.invoke('save-settings', settings),
|
||||||
loadSettings: () => ipcRenderer.invoke('load-settings'),
|
loadSettings: () => ipcRenderer.invoke('load-settings'),
|
||||||
|
getEnvVar: (key) => ipcRenderer.invoke('get-env-var', key),
|
||||||
getLocalAppData: () => ipcRenderer.invoke('get-local-app-data'),
|
getLocalAppData: () => ipcRenderer.invoke('get-local-app-data'),
|
||||||
getModsPath: () => ipcRenderer.invoke('get-mods-path'),
|
getModsPath: () => ipcRenderer.invoke('get-mods-path'),
|
||||||
loadInstalledMods: (modsPath) => ipcRenderer.invoke('load-installed-mods', modsPath),
|
loadInstalledMods: (modsPath) => ipcRenderer.invoke('load-installed-mods', modsPath),
|
||||||
@@ -129,5 +130,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||||||
},
|
},
|
||||||
onUpdateDownloaded: (callback) => {
|
onUpdateDownloaded: (callback) => {
|
||||||
ipcRenderer.on('update-downloaded', (event, data) => callback(data));
|
ipcRenderer.on('update-downloaded', (event, data) => callback(data));
|
||||||
|
},
|
||||||
|
onUpdateError: (callback) => {
|
||||||
|
ipcRenderer.on('update-error', (event, data) => callback(data));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user