diff --git a/AUTO-UPDATES.md b/AUTO-UPDATES.md new file mode 100644 index 0000000..1d5ca63 --- /dev/null +++ b/AUTO-UPDATES.md @@ -0,0 +1,284 @@ +# Auto-Updates System + +This document explains how the automatic update system works in the Hytale F2P Launcher. + +## Overview + +The launcher uses [electron-updater](https://www.electron.build/auto-update) to automatically check for, download, and install updates. When a new version is available, users are notified and the update is downloaded in the background. + +## How It Works + +### 1. Update Checking + +- **Automatic Check**: The app automatically checks for updates 3 seconds after startup +- **Manual Check**: Users can manually check for updates through the UI +- **Update Source**: Updates are fetched from GitHub Releases + +### 2. Update Process + +1. **Check for Updates**: The app queries GitHub Releases for a newer version +2. **Notify User**: If an update is available, the user is notified via the UI +3. **Download**: The update is automatically downloaded in the background +4. **Progress Tracking**: Download progress is shown to the user +5. **Install**: When the download completes, the user can choose to install immediately or wait until the app restarts + +### 3. Installation + +- Updates are installed when the app quits (if `autoInstallOnAppQuit` is enabled) +- Users can also manually trigger installation through the UI +- The app will restart automatically after installation + +## Version Detection & Comparison + +### Current Version Source + +The app's current version is read from `package.json`: + +```json +{ + "version": "2.0.2b" +} +``` + +This version is embedded into the built application and is accessible via `app.getVersion()` in Electron. When the app is built, electron-builder also creates an internal `app-update.yml` file in the app's resources that contains this version information. + +### How Version Detection Works + +1. **Current Version**: The app knows its own version from `package.json`, which is: + - Read at build time + - Embedded in the application binary + - Stored in the app's metadata + +2. **Fetching Latest Version**: When checking for updates, electron-updater: + - Queries the GitHub Releases API: `https://api.github.com/repos/amiayweb/Hytale-F2P/releases/latest` + - Or reads the update metadata file: `https://github.com/amiayweb/Hytale-F2P/releases/download/latest/latest.yml` (or `latest-mac.yml` for macOS) + - The metadata file contains: + ```yaml + version: 2.0.3 + releaseDate: '2024-01-15T10:30:00.000Z' + path: Hytale-F2P-Launcher-2.0.3-x64.exe + sha512: ... + ``` + +3. **Version Comparison**: electron-updater uses semantic versioning comparison: + - Compares the **current version** (from `package.json`) with the **latest version** (from GitHub Releases) + - Uses semantic versioning rules: `major.minor.patch` (e.g., `2.0.2` vs `2.0.3`) + - An update is available if the remote version is **greater than** the current version + - Examples: + - Current: `2.0.2` → Remote: `2.0.3` ✅ Update available + - Current: `2.0.2` → Remote: `2.0.2` ❌ No update (same version) + - Current: `2.0.3` → Remote: `2.0.2` ❌ No update (current is newer) + - Current: `2.0.2b` → Remote: `2.0.3` ✅ Update available (prerelease tags are handled) + +4. **Version Format Handling**: + - **Semantic versions** (e.g., `1.0.0`, `2.1.3`) are compared numerically + - **Prerelease versions** (e.g., `2.0.2b`, `2.0.2-beta`) are compared with special handling + - **Non-semantic versions** may cause issues - it's recommended to use semantic versioning + +### Update Metadata Files + +When you build and publish a release, electron-builder generates platform-specific metadata files: + +**Windows/Linux** (`latest.yml`): +```yaml +version: 2.0.3 +files: + - url: Hytale-F2P-Launcher-2.0.3-x64.exe + sha512: abc123... + size: 12345678 +path: Hytale-F2P-Launcher-2.0.3-x64.exe +sha512: abc123... +releaseDate: '2024-01-15T10:30:00.000Z' +``` + +**macOS** (`latest-mac.yml`): +```yaml +version: 2.0.3 +files: + - url: Hytale-F2P-Launcher-2.0.3-arm64-mac.zip + sha512: def456... + size: 23456789 +path: Hytale-F2P-Launcher-2.0.3-arm64-mac.zip +sha512: def456... +releaseDate: '2024-01-15T10:30:00.000Z' +``` + +These files are: +- Automatically generated during build +- Uploaded to GitHub Releases +- Fetched by electron-updater to check for updates +- Used to determine if an update is available and what to download + +### The Check Process in Detail + +When `appUpdater.checkForUpdatesAndNotify()` is called: + +1. **Read Current Version**: Gets version from `app.getVersion()` (which reads from `package.json`) +2. **Fetch Update Info**: + - Makes HTTP request to GitHub Releases API or reads `latest.yml` + - Gets the version number from the metadata +3. **Compare Versions**: + - Uses semantic versioning comparison (e.g., `semver.gt(remoteVersion, currentVersion)`) + - If remote > current: update available + - If remote <= current: no update +4. **Emit Events**: + - `update-available` if newer version found + - `update-not-available` if already up to date +5. **Download if Available**: If `autoDownload` is enabled, starts downloading automatically + +### Example Flow + +``` +App Version: 2.0.2 (from package.json) + ↓ +Check GitHub Releases API + ↓ +Latest Release: 2.0.3 + ↓ +Compare: 2.0.3 > 2.0.2? YES + ↓ +Emit: 'update-available' event + ↓ +Download update automatically + ↓ +Emit: 'update-downloaded' event + ↓ +User can install on next restart +``` + +## Components + +### AppUpdater Class (`backend/appUpdater.js`) + +The main class that handles all update operations: + +- **`checkForUpdatesAndNotify()`**: Checks for updates and shows a system notification if available +- **`checkForUpdates()`**: Manually checks for updates (returns a promise) +- **`quitAndInstall()`**: Quits the app and installs the downloaded update + +### Events + +The AppUpdater emits the following events that the UI can listen to: + +- `update-checking`: Update check has started +- `update-available`: A new update is available +- `update-not-available`: App is up to date +- `update-download-progress`: Download progress updates +- `update-downloaded`: Update has finished downloading +- `update-error`: An error occurred during the update process + +## Configuration + +### Package.json + +The publish configuration in `package.json` tells electron-builder where to publish updates: + +```json +"publish": { + "provider": "github", + "owner": "amiayweb", + "repo": "Hytale-F2P" +} +``` + +This means updates will be fetched from GitHub Releases for the `amiayweb/Hytale-F2P` repository. + +## Publishing Updates + +### For Developers + +1. **Update Version**: Bump the version in `package.json` (e.g., `2.0.2b` → `2.0.3`) + +2. **Build the App**: Run the build command for your platform: + ```bash + npm run build:win # Windows + npm run build:mac # macOS + npm run build:linux # Linux + ``` + +3. **Publish to GitHub**: When building with electron-builder, it will: + - Generate update metadata files (`latest.yml`, `latest-mac.yml`, etc.) + - Upload the built files to GitHub Releases (if configured with `GH_TOKEN`) + - Make them available for auto-update + +4. **Release on GitHub**: Create a GitHub Release with the new version tag + +### Important Notes + +- **macOS Code Signing**: macOS apps **must** be code-signed for auto-updates to work +- **Version Format**: Use semantic versioning (e.g., `1.0.0`, `2.0.1`) for best compatibility +- **Update Files**: electron-builder automatically generates the required metadata files (`latest.yml`, etc.) + +## Testing Updates + +### Development Mode + +To test updates during development, create a `dev-app-update.yml` file in the project root: + +```yaml +owner: amiayweb +repo: Hytale-F2P +provider: github +``` + +Then enable dev mode in the code: +```javascript +autoUpdater.forceDevUpdateConfig = true; +``` + +### Local Testing + +For local testing, you can use a local server (like Minio) or a generic HTTP server to host update files. + +## User Experience + +### What Users See + +1. **On Startup**: The app silently checks for updates in the background +2. **Update Available**: A notification appears if an update is found +3. **Downloading**: Progress bar shows download status +4. **Ready to Install**: User is notified when the update is ready +5. **Installation**: Update installs on app restart or when user clicks "Install Now" + +### User Actions + +- Users can manually check for updates through the settings/update menu +- Users can choose to install immediately or wait until next app launch +- Users can continue using the app while updates download in the background + +## Troubleshooting + +### Updates Not Working + +1. **Check GitHub Releases**: Ensure releases are published on GitHub +2. **Check Version**: Make sure the version in `package.json` is higher than the current release +3. **Check Logs**: Check the app logs for update-related errors +4. **Code Signing (macOS)**: Verify the app is properly code-signed + +### Common Issues + +- **"Update not available"**: Version in `package.json` may not be higher than the current release +- **"Download failed"**: Network issues or GitHub API rate limits +- **"Installation failed"**: Permissions issue or app is running from an unsupported location + +## Technical Details + +### Supported Platforms + +- **Windows**: NSIS installer (auto-update supported) +- **macOS**: DMG + ZIP (auto-update supported, requires code signing) +- **Linux**: AppImage, DEB, RPM, Pacman (auto-update supported) + +### Update Files Generated + +When building, electron-builder generates: +- `latest.yml` (Windows/Linux) +- `latest-mac.yml` (macOS) +- `latest-linux.yml` (Linux) + +These files contain metadata about the latest release and are automatically uploaded to GitHub Releases. + +## References + +- [electron-updater Documentation](https://www.electron.build/auto-update) +- [electron-builder Auto Update Guide](https://www.electron.build/auto-update) diff --git a/TESTING-UPDATES.md b/TESTING-UPDATES.md new file mode 100644 index 0000000..0103272 --- /dev/null +++ b/TESTING-UPDATES.md @@ -0,0 +1,196 @@ +# Testing Auto-Updates + +This guide explains how to test the auto-update system during development. + +## Quick Start + +### Option 1: Test with GitHub Releases (Easiest) + +1. **Set up dev-app-update.yml** (already done): + ```yaml + provider: github + owner: amiayweb + repo: Hytale-F2P + ``` + +2. **Lower your current version** in `package.json`: + - Change version to something lower than what's on GitHub (e.g., `2.0.1` if GitHub has `2.0.3`) + +3. **Run the app in dev mode**: + ```bash + npm run dev + # or + npm start + ``` + +4. **The app will check for updates** 3 seconds after startup + - If a newer version exists on GitHub, it will detect it + - Check the console logs for update messages + +### Option 2: Test with Local HTTP Server + +For more control, you can set up a local server: + +1. **Create a test update server**: + ```bash + # Create a test directory + mkdir -p test-updates + cd test-updates + ``` + +2. **Build a test version** with a higher version number: + ```bash + # In package.json, set version to 2.0.4 + npm run build + ``` + +3. **Copy the generated files** to your test server: + - Copy `dist/latest.yml` (or `latest-mac.yml` for macOS) + - Copy the built installer/package + +4. **Start a simple HTTP server**: + ```bash + # Using Python + python3 -m http.server 8080 + + # Or using Node.js http-server + npx http-server -p 8080 + ``` + +5. **Update dev-app-update.yml** to point to local server: + ```yaml + provider: generic + url: http://localhost:8080 + ``` + +6. **Run the app** and it will check your local server + +## Testing Steps + +### 1. Prepare Test Environment + +**Current version**: `2.0.3` (in package.json) +**Test version**: `2.0.4` (on GitHub or local server) + +### 2. Run the App + +```bash +npm run dev +``` + +### 3. Watch for Update Events + +The app will automatically check for updates 3 seconds after startup. Watch the console for: + +``` +Checking for updates... +Update available: 2.0.4 +``` + +### 4. Check Console Logs + +Look for these messages: +- `Checking for updates...` - Update check started +- `Update available: 2.0.4` - New version found +- `Download speed: ...` - Download progress +- `Update downloaded: 2.0.4` - Download complete + +### 5. Test UI Integration + +The app sends these events to the renderer: +- `update-checking` +- `update-available` (with version info) +- `update-download-progress` (with progress data) +- `update-downloaded` (ready to install) + +You can listen to these in your frontend code to show update notifications. + +## Manual Testing + +### Trigger Manual Update Check + +You can also trigger a manual check via IPC: +```javascript +// In renderer process +const result = await window.electronAPI.invoke('check-for-updates'); +console.log(result); +``` + +### Install Update + +After an update is downloaded: +```javascript +// In renderer process +await window.electronAPI.invoke('quit-and-install-update'); +``` + +## Testing Scenarios + +### Scenario 1: Update Available +1. Set `package.json` version to `2.0.1` +2. Ensure GitHub has version `2.0.3` or higher +3. Run app → Should detect update + +### Scenario 2: Already Up to Date +1. Set `package.json` version to `2.0.3` +2. Ensure GitHub has version `2.0.3` or lower +3. Run app → Should show "no update available" + +### Scenario 3: Prerelease Version +1. Set `package.json` version to `2.0.2b` +2. Ensure GitHub has version `2.0.3` +3. Run app → Should detect update (prerelease < release) + +## Troubleshooting + +### Update Not Detected + +1. **Check dev-app-update.yml exists** in project root +2. **Verify dev mode is enabled** - Check console for "Dev update mode enabled" +3. **Check version numbers** - Remote version must be higher than current +4. **Check network** - App needs internet to reach GitHub/local server +5. **Check logs** - Look for error messages in console + +### Common Errors + +- **"Cannot find module 'electron-updater'"**: Run `npm install` +- **"Update check failed"**: Check network connection or GitHub API access +- **"No update available"**: Version comparison issue - check versions + +### Debug Mode + +Enable more verbose logging by checking the console output. The logger will show: +- Update check requests +- Version comparisons +- Download progress +- Any errors + +## Testing with Real GitHub Releases + +For the most realistic test: + +1. **Create a test release on GitHub**: + - Build the app with version `2.0.4` + - Create a GitHub release with tag `v2.0.4` + - Upload the built files + +2. **Lower your local version**: + - Set `package.json` to `2.0.3` + +3. **Run the app**: + - It will check GitHub and find `2.0.4` + - Download and install the update + +## Notes + +- **Dev mode only works when app is NOT packaged** (`!app.isPackaged`) +- **Production builds** ignore `dev-app-update.yml` and use the built-in `app-update.yml` +- **macOS**: Code signing is required for updates to work in production +- **Windows**: NSIS installer is required for auto-updates + +## Next Steps + +Once testing is complete: +1. Remove or comment out `forceDevUpdateConfig` for production +2. Ensure proper code signing for macOS +3. Set up CI/CD to automatically publish releases diff --git a/backend/appUpdater.js b/backend/appUpdater.js new file mode 100644 index 0000000..001b711 --- /dev/null +++ b/backend/appUpdater.js @@ -0,0 +1,120 @@ +const { autoUpdater } = require('electron-updater'); +const { app } = require('electron'); +const logger = require('./logger'); + +class AppUpdater { + constructor(mainWindow) { + this.mainWindow = mainWindow; + this.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 + // Create a compatible logger interface + autoUpdater.logger = { + info: (...args) => logger.info(...args), + warn: (...args) => logger.warn(...args), + error: (...args) => logger.error(...args), + debug: (...args) => logger.log(...args) + }; + + // Auto download updates + autoUpdater.autoDownload = true; + // Auto install on quit (after download) + autoUpdater.autoInstallOnAppQuit = true; + + // Event handlers + autoUpdater.on('checking-for-update', () => { + console.log('Checking for updates...'); + if (this.mainWindow && !this.mainWindow.isDestroyed()) { + this.mainWindow.webContents.send('update-checking'); + } + }); + + autoUpdater.on('update-available', (info) => { + console.log('Update available:', info.version); + if (this.mainWindow && !this.mainWindow.isDestroyed()) { + this.mainWindow.webContents.send('update-available', { + version: info.version, + releaseName: info.releaseName, + releaseNotes: info.releaseNotes + }); + } + }); + + autoUpdater.on('update-not-available', (info) => { + console.log('Update not available. Current version is latest.'); + if (this.mainWindow && !this.mainWindow.isDestroyed()) { + this.mainWindow.webContents.send('update-not-available', { + version: info.version + }); + } + }); + + autoUpdater.on('error', (err) => { + console.error('Error in auto-updater:', err); + if (this.mainWindow && !this.mainWindow.isDestroyed()) { + this.mainWindow.webContents.send('update-error', { + message: err.message + }); + } + }); + + autoUpdater.on('download-progress', (progressObj) => { + const message = `Download speed: ${progressObj.bytesPerSecond} - Downloaded ${progressObj.percent}% (${progressObj.transferred}/${progressObj.total})`; + console.log(message); + if (this.mainWindow && !this.mainWindow.isDestroyed()) { + this.mainWindow.webContents.send('update-download-progress', { + percent: progressObj.percent, + bytesPerSecond: progressObj.bytesPerSecond, + transferred: progressObj.transferred, + total: progressObj.total + }); + } + }); + + autoUpdater.on('update-downloaded', (info) => { + console.log('Update downloaded:', info.version); + if (this.mainWindow && !this.mainWindow.isDestroyed()) { + this.mainWindow.webContents.send('update-downloaded', { + version: info.version, + releaseName: info.releaseName, + releaseNotes: info.releaseNotes + }); + } + }); + } + + checkForUpdatesAndNotify() { + // Check for updates and notify if available + autoUpdater.checkForUpdatesAndNotify().catch(err => { + console.error('Failed to check for updates:', err); + }); + } + + checkForUpdates() { + // Manual check for updates (returns promise) + return autoUpdater.checkForUpdates(); + } + + quitAndInstall() { + // Quit and install the update + autoUpdater.quitAndInstall(false, true); + } + + getUpdateInfo() { + return { + currentVersion: app.getVersion(), + updateAvailable: false + }; + } +} + +module.exports = AppUpdater; diff --git a/dev-app-update.yml b/dev-app-update.yml new file mode 100644 index 0000000..e171683 --- /dev/null +++ b/dev-app-update.yml @@ -0,0 +1,3 @@ +provider: github +owner: amiayweb +repo: Hytale-F2P diff --git a/main.js b/main.js index b7e639a..d6eb302 100644 --- a/main.js +++ b/main.js @@ -2,14 +2,14 @@ const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron'); const path = require('path'); const fs = require('fs'); const { launchGame, launchGameWithVersionCheck, installGame, saveUsername, loadUsername, saveChatUsername, loadChatUsername, saveChatColor, loadChatColor, saveJavaPath, loadJavaPath, saveInstallPath, loadInstallPath, saveDiscordRPC, loadDiscordRPC, saveLanguage, loadLanguage, isGameInstalled, uninstallGame, repairGame, getHytaleNews, handleFirstLaunchCheck, proposeGameUpdate, markAsLaunched } = require('./backend/launcher'); -const UpdateManager = require('./backend/updateManager'); +const AppUpdater = require('./backend/appUpdater'); const logger = require('./backend/logger'); const profileManager = require('./backend/managers/profileManager'); logger.interceptConsole(); let mainWindow; -let updateManager; +let appUpdater; let discordRPC = null; // Discord Rich Presence setup @@ -113,11 +113,13 @@ function createWindow() { // Initialize Discord Rich Presence initDiscordRPC(); - updateManager = new UpdateManager(); - setTimeout(async () => { - const updateInfo = await updateManager.checkForUpdates(); - if (updateInfo.updateAvailable) { - mainWindow.webContents.send('show-update-popup', updateInfo); + // Initialize App Updater + appUpdater = new AppUpdater(mainWindow); + + // Check for updates after a short delay (3 seconds) + setTimeout(() => { + if (appUpdater) { + appUpdater.checkForUpdatesAndNotify(); } }, 3000); @@ -724,7 +726,15 @@ ipcMain.handle('copy-mod-file', async (event, sourcePath, modsPath) => { ipcMain.handle('check-for-updates', async () => { try { - return await updateManager.checkForUpdates(); + if (appUpdater) { + const result = await appUpdater.checkForUpdates(); + return { + updateAvailable: result?.updateInfo ? true : false, + version: result?.updateInfo?.version, + currentVersion: app.getVersion() + }; + } + return { updateAvailable: false, error: 'AppUpdater not initialized' }; } catch (error) { console.error('Error checking for updates:', error); return { updateAvailable: false, error: error.message }; @@ -733,7 +743,8 @@ ipcMain.handle('check-for-updates', async () => { ipcMain.handle('open-download-page', async () => { try { - await shell.openExternal(updateManager.getDownloadUrl()); + // Open GitHub releases page + await shell.openExternal('https://github.com/amiayweb/Hytale-F2P/releases'); setTimeout(() => { if (mainWindow && !mainWindow.isDestroyed()) { @@ -748,8 +759,24 @@ ipcMain.handle('open-download-page', async () => { } }); +ipcMain.handle('quit-and-install-update', async () => { + try { + if (appUpdater) { + appUpdater.quitAndInstall(); + return { success: true }; + } + return { success: false, error: 'AppUpdater not initialized' }; + } catch (error) { + console.error('Error installing update:', error); + return { success: false, error: error.message }; + } +}); + ipcMain.handle('get-update-info', async () => { - return updateManager.getUpdateInfo(); + if (appUpdater) { + return appUpdater.getUpdateInfo(); + } + return { currentVersion: app.getVersion(), updateAvailable: false }; }); ipcMain.handle('get-gpu-info', () => { diff --git a/package-lock.json b/package-lock.json index 90d6855..6efcf38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,18 @@ { - "name": "hytale-f2p-launcherv2", + "name": "hytale-f2p-launcher", "version": "2.0.2b", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "hytale-f2p-launcherv2", + "name": "hytale-f2p-launcher", "version": "2.0.2b", "license": "MIT", "dependencies": { "adm-zip": "^0.5.10", "axios": "^1.6.0", "discord-rpc": "^4.0.1", + "electron-updater": "^6.7.3", "tar": "^6.2.1", "uuid": "^9.0.1" }, @@ -1073,7 +1074,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, "license": "Python-2.0" }, "node_modules/assert-plus": { @@ -1283,7 +1283,6 @@ "version": "9.5.1", "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.5.1.tgz", "integrity": "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==", - "dev": true, "license": "MIT", "dependencies": { "debug": "^4.3.4", @@ -1711,7 +1710,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2178,6 +2176,69 @@ "node": ">= 10.0.0" } }, + "node_modules/electron-updater": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.7.3.tgz", + "integrity": "sha512-EgkT8Z9noqXKbwc3u5FkJA+r48jwZ5DTUiOkJMOTEEH//n5Am6wfQGz7nvSFEA2oIAMv9jRzn5JKTyWeSKOPgg==", + "license": "MIT", + "dependencies": { + "builder-util-runtime": "9.5.1", + "fs-extra": "^10.1.0", + "js-yaml": "^4.1.0", + "lazy-val": "^1.0.5", + "lodash.escaperegexp": "^4.1.2", + "lodash.isequal": "^4.5.0", + "semver": "~7.7.3", + "tiny-typed-emitter": "^2.1.0" + } + }, + "node_modules/electron-updater/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-updater/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-updater/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-updater/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/electron-winstaller": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.4.0.tgz", @@ -2759,7 +2820,6 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, "license": "ISC" }, "node_modules/has-flag": { @@ -3082,7 +3142,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -3150,7 +3209,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", - "dev": true, "license": "MIT" }, "node_modules/lodash": { @@ -3160,6 +3218,19 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -3476,7 +3547,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/negotiator": { @@ -4131,7 +4201,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", - "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=11.0.0" @@ -4602,6 +4671,12 @@ "semver": "bin/semver" } }, + "node_modules/tiny-typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", + "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", diff --git a/package.json b/package.json index 51dd605..9ce03ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hytale-f2p-launcher", - "version": "2.0.2b", + "version": "2.0.3", "description": "A modern, cross-platform launcher for Hytale with automatic updates and multi-client support", "homepage": "https://github.com/amiayweb/Hytale-F2P", "main": "main.js", @@ -24,7 +24,7 @@ "mod-manager", "chat" ], - "maintainers": [ + "maintainers": [ { "name": "Terromur", "url": "https://github.com/Terromur" @@ -33,7 +33,7 @@ "name": "Fari Gading", "email": "fazrigading@gmail.com", "url": "https://github.com/fazrigading" - } + } ], "author": { "name": "AMIAY", @@ -48,6 +48,7 @@ "adm-zip": "^0.5.10", "axios": "^1.6.0", "discord-rpc": "^4.0.1", + "electron-updater": "^6.7.3", "tar": "^6.2.1", "uuid": "^9.0.1" }, @@ -70,25 +71,70 @@ ], "win": { "target": [ - { "target": "nsis", "arch": ["x64", "arm64"] }, - { "target": "portable", "arch": ["x64"] } + { + "target": "nsis", + "arch": [ + "x64", + "arm64" + ] + }, + { + "target": "portable", + "arch": [ + "x64" + ] + } ], "icon": "icon.ico" }, "linux": { "target": [ - { "target": "AppImage", "arch": ["x64", "arm64"] }, - { "target": "deb", "arch": ["x64", "arm64"] }, - { "target": "rpm", "arch": ["x64", "arm64"] }, - { "target": "pacman", "arch": ["x64", "arm64"] } + { + "target": "AppImage", + "arch": [ + "x64", + "arm64" + ] + }, + { + "target": "deb", + "arch": [ + "x64", + "arm64" + ] + }, + { + "target": "rpm", + "arch": [ + "x64", + "arm64" + ] + }, + { + "target": "pacman", + "arch": [ + "x64", + "arm64" + ] + } ], "icon": "build/icon.png", "category": "Game" }, "mac": { "target": [ - { "target": "dmg", "arch": ["universal"] }, - { "target": "zip", "arch": ["universal"] } + { + "target": "dmg", + "arch": [ + "universal" + ] + }, + { + "target": "zip", + "arch": [ + "universal" + ] + } ], "icon": "build/icon.icns", "category": "public.app-category.games" @@ -98,6 +144,11 @@ "allowToChangeInstallationDirectory": true, "createDesktopShortcut": true, "createStartMenuShortcut": true + }, + "publish": { + "provider": "github", + "owner": "amiayweb", + "repo": "Hytale-F2P" } } -} \ No newline at end of file +}