Compare commits

..

2 Commits

Author SHA1 Message Date
Fazri Gading
39c12c0591 Release v2.2.0 - Fixed Arch failed build for Linux (#250)
* fix: resolve cross-platform EPERM permissions errors

modManager.js:
- Switch from hardcoded 'junction' to dynamic symlink type based on OS (fixing Linux EPERM).
- Add retry logic for directory removal to handle file locking race conditions.
- Improve broken symlink detection during profile sync.

gameManager.js:
- Implement retry loop (3 attempts) for game directory removal in updateGameFiles to prevent EBUSY/EPERM errors on Windows.

paths.js:
- Prevent fs.mkdirSync failure in getModsPath by pre-checking for broken symbolic links.

* fix: missing pacman builds

* prepare release for 2.1.1

minor fix for EPERM error permission

* prepare release 2.1.1

minor fix EPERM permission error

* prepare release 2.1.1

* Update README.md Windows Prequisites for ARM64 builds

* fix: remove broken symlink after detected

* fix: add pathexists for paths.js to check symlink

* fix: isbrokenlink should be true to remove the symlink

* add arch package .pkg.tar.zst for release

* fix: release workflow for build-arch and build-linux

* build-arch job now only build arch .pkg.tar.zst package instead of the whole generic linux.
* build-linux job now exclude .pacman package since its deprecated and should not be used.

* fix: removes pacman build as it replaced by tar.zst and adds build:arch shortcut for pkgbuild

* aur: add proper VCS (-git) PKGBUILD

created clean VCS-based PKGBUILD following arch packaging conventions.

this explicitly marked as a rolling (-git) build and derives its version dynamically from git tags and commit history via pkgver(). previous hybrid approach has been changed.

key changes:
- use -git suffix to clearly indicate rolling source builds
- set pkgver=0 and compute the actual version via pkgver()
- build only a directory layout using electron-builder (--dir)
- avoid generating AppImage, deb, rpm, or pacman installers
- align build and package steps with Arch packaging guidelines

note: this PKGBUILD is intended for development and AUR use only and is not suitable for binary redistribution or release artifacts.

* ci: add fixed-version PKGBUILD for Arch Linux releases

this PKGBUILD intended for CI and GitHub release artifacts. targets tagged releases only and uses a fixed pkgver that matches the corresponding git tag. all of the VCS logic has been removed to PKGBUILD-git to ensure reproducible builds and stable versioning suitable for binary distribution.

the build process relies on electron-builder directory output (--dir) and packages only the unpacked application into a standard Arch Linux package (.pkg.tar.zst). other distro format are excluded from this path and handled separately.

this change establishes a clear separation between:
- rolling AUR development builds (-git)
- CI-generated, versioned Arch Linux release packages

the result is predictable artifact naming, correct version alignment, and Arch-compliant packaging for downstream users.

* Update README.md

adds information for Arch build

* Update README.md

BUILD.md location was changed and now this link is poiting to nothing

* Update PKGBUILD

* Update PKGBUILD-git

* chore: fix ubuntu/debian part in README.md

* Polish language support (#195)

* Update support_request.yml

Added hardware specification

* Update bug_report.yml

Add logs textfield to bug report

* chore: add changelog in README.md

* fix screenshot input in feature_request.yml

* add hardware spec input in bug_report.yml

* fix: PKGBUILD pkgname variable fix

* userdata migration [need review from other OS]

* french translate

* Add German and Swedish translations

Added de.json and sv.json locale files for German and Swedish language support. Updated i18n.js to register 'de' and 'sv' as available languages in the launcher.

* Update README.md

* chore: add offline-mode warning to the README.md

* chore: add downloads counter in README.md

* fix: Steam Deck/Ubuntu crash - use system libzstd.so

The bundled libzstd.so is incompatible with glibc 2.41's stricter heap
validation, causing "free(): invalid pointer" crashes.

Solution: Automatically replace bundled libzstd.so with system version
on Linux. The launcher detects and symlinks to /usr/lib/libzstd.so.1.

- Auto-detect system libzstd at common paths (Arch, Debian, Fedora)
- Backup bundled version as libzstd.so.bundled
- Create symlink to system version
- Add HYTALE_NO_LIBZSTD_FIX=1 to disable if needed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: remove Windows and Linux ARM64 information on the README.md

* Update support_request.yml

* fix: improve update system UX and macOS compatibility

Update System Improvements:
- Fix duplicate update popups by disabling legacy updater.js
- Add skip button to update popup (shows after 30s, on error, or after download)
- Add macOS-specific handling with manual download as primary option
- Add missing open-download-page IPC handler
- Add missing unblockInterface() method to properly clean up after popup close
- Add quitAndInstallUpdate alias in preload for compatibility
- Remove pulse animation when download completes
- Fix manual download button to show correct status and close popup
- Sync player name to settings input after first install

Client Patcher Cleanup:
- Remove server patching code (server uses pre-patched JAR from CDN)
- Simplify to client-only patching
- Remove unused imports (crypto, AdmZip, execSync, spawn, javaManager)
- Remove unused methods (stringToUtf8, findAndReplaceDomainUtf8)
- Move localhost dev code to backup file for reference

Code Quality Fixes:
- Fix duplicate DOMContentLoaded handlers in install.js
- Fix duplicate checkForUpdates definition in preload.js
- Fix redundant if/else in onProgressUpdate callback
- Fix typo "Harwadre" -> "Hardware" in preload.js

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add Russian language support

Added Russian (ru) to the list of available languages.

* chore: drafting documentation on SERVER.md

* Some updates in Russian language localization file

* fix

* Update ru.json

* Fixed Java runtime name and fixed typo

* fixed untranslated place

* Update ru.json

* Update ru.json

* Update ru.json

* Update ru.json

* Update ru.json

* fix: timeout getLatestClient 

fixes #138

* fix: change default version to 7.pwr in main.js

* fix: change default release version to 7.pwr

* fix: change version release to 7.pwr

* docs: Add comprehensive troubleshooting guide (#209)

Add TROUBLESHOOTING.md with solutions for common issues including:

- Windows: Firewall configuration, duplicate mods, SmartScreen
- Linux: GPU detection (NVIDIA/AMD), SDL3_image/libpng dependencies,
  Wayland/X11 issues, Steam Deck support
- macOS: Rosetta 2 for Apple Silicon, code signing, quarantine
- Connection: Server boot failures, regional restrictions
- Authentication: Token errors, config reset procedures
- Avatar/Cosmetics: F2P limitations documentation
- Backup locations for all platforms
- Log locations for bug reports

Solutions compiled from closed GitHub issues (#205, #155, #90, #60,
#144, #192) and community feedback.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* Standardize language codes, improve formatting, and update all locale files. (#224)

* Update German (Germany) localization

* Update Español (España) localization

* Update French (France) localization

* Update Polish (Poland) localization

* Update Portuguese (Brazil) localization

* Update Russian (Russia) localization

* Update Swedish (Sweden) localization

* Update Turkish (Turkey) localization

* Update language codes, names and alphabetical in i18n system

* Changed Spanish language name to the Formal name "Spanish (Spain)"

* Fix PKGBUILD-git

* Fix PKGBUILD

* delete cache after installation

* Enforce 16-char player name limit and update mod sync

Added a maxlength attribute to the player name input and enforced a 16-character limit in both install and settings scripts, providing user feedback if exceeded. Refactored modManager.js to replace symlink-based mod management with a copy-based system, copying enabled mods to HytaleSaves\Mods and removing legacy symlink logic to improve compatibility and avoid permission issues.

* Update installation subtitle

* chore: update quickstart link in README.md

* chore: delete warning of Ubuntu-Debian at Linux Prequisites section

* added featured server list from api

* Add Featured Servers page to GUI

* Update Discord invite URL in client patcher

* Add differential update system

* Remove launcher chat and add Discord popup

* fix: removed 'check disk space' alert on permission file error

* fix: upgrade tar to ^7.5.6 version

* fix: re-add universal arch for mac

* fix: upgrade electron/rebuild to 4.0.3

* fix: removed override tar version

* fix: pkgbuild version to 2.1.2

* fix: src.tar.zst and srcinfo missing files

* feat: add Indonesian language translation

* fix: GPU preference hint to Laptop-only

* feat: create two columns for settings page

* Add Discord invite link to rpc

* docs: add recordings form, fix OS list

* Release v2.2.0

* Release v2.2.0

* Release v2.2.0

* chore: delete icon.ico, moved to build folder

* chore: delete icon.png, moved to build folder

* fix: build and release for tag push-only in release.yml

* fix: gamescope steam deck issue fixes #186 hopefully

* Support branch selection for server patching

* chose: add auto-patch system for pre-release JAR

* fix: preserves arch x64 on linux target for #242

* fix: removed arm64 flags

* fix: redo package.json arch

* update package-lock.json

* Update release.yml

* chore: sync package-lock with package.json

---------

Co-authored-by: TalesAmaral <57869141+TalesAmaral@users.noreply.github.com>
Co-authored-by: walti0 <95646872+walti0@users.noreply.github.com>
Co-authored-by: AMIAY <letudiantenrap.collab@gmail.com>
Co-authored-by: sanasol <mail@sanasol.ws>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Terromur <79866197+Terromur@users.noreply.github.com>
Co-authored-by: Zakhar Smokotov <zaharb840@gmail.com>
Co-authored-by: xSamiVS <samtaiebc@gmail.com>
2026-01-31 23:08:40 +08:00
Fazri Gading
094bb938fc Release v2.2.0 - Fix AppImage Build (#247) 2026-01-31 15:26:44 +01:00
5 changed files with 270 additions and 761 deletions

View File

@@ -27,10 +27,8 @@ jobs:
dist/*.exe.blockmap dist/*.exe.blockmap
dist/latest.yml dist/latest.yml
# macOS ARM64 build (Apple Silicon) build-macos:
build-macos-arm64: runs-on: macos-latest
runs-on: macos-latest # ARM64 runner for native Apple Silicon builds
timeout-minutes: 120
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
@@ -39,75 +37,15 @@ jobs:
cache: 'npm' cache: 'npm'
- run: npm ci - run: npm ci
- name: Build macOS ARM64 Package - name: Build macOS Packages
env: run: npx electron-builder --mac --publish never
# Code signing
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
# Notarization
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: npx electron-builder --mac --arm64 --publish never
- name: Rename ARM64 artifacts for clarity
run: |
cd dist
for f in *.dmg; do
[ -f "$f" ] && mv "$f" "${f%.dmg}-arm64.dmg" 2>/dev/null || true
done
for f in *.zip; do
[ -f "$f" ] && mv "$f" "${f%.zip}-arm64.zip" 2>/dev/null || true
done
ls -la
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: macos-arm64-builds name: macos-builds
path: |
dist/*.dmg
dist/*.zip
# macOS x64 build (Intel)
build-macos-x64:
runs-on: macos-15-large # Intel runner for native x64 builds
timeout-minutes: 120
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- name: Build macOS x64 Package
env:
# Code signing
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
# Notarization
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: npx electron-builder --mac --x64 --publish never
- name: Rename x64 artifacts for clarity
run: |
cd dist
for f in *.dmg; do
[ -f "$f" ] && mv "$f" "${f%.dmg}-x64.dmg" 2>/dev/null || true
done
for f in *.zip; do
[ -f "$f" ] && mv "$f" "${f%.zip}-x64.zip" 2>/dev/null || true
done
ls -la
- uses: actions/upload-artifact@v4
with:
name: macos-x64-builds
path: | path: |
dist/*.dmg dist/*.dmg
dist/*.zip dist/*.zip
dist/latest-mac.yml
build-linux: build-linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -188,9 +126,8 @@ jobs:
.SRCINFO .SRCINFO
include-hidden-files: true include-hidden-files: true
# Create release with Windows, Linux, Arch (fast builds)
release: release:
needs: [build-windows, build-linux, build-arch] needs: [build-windows, build-macos, build-linux, build-arch]
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: | if: |
startsWith(github.ref, 'refs/tags/v') || startsWith(github.ref, 'refs/tags/v') ||
@@ -204,23 +141,10 @@ jobs:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Download Windows artifacts - name: Download all artifacts
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: windows-builds path: artifacts
path: artifacts/windows-builds
- name: Download Linux artifacts
uses: actions/download-artifact@v4
with:
name: linux-builds
path: artifacts/linux-builds
- name: Download Arch artifacts
uses: actions/download-artifact@v4
with:
name: arch-package
path: artifacts/arch-package
- name: Display structure of downloaded files - name: Display structure of downloaded files
run: ls -R artifacts run: ls -R artifacts
@@ -237,70 +161,10 @@ jobs:
artifacts/arch-package/*.pkg.tar.zst artifacts/arch-package/*.pkg.tar.zst
artifacts/arch-package/*.src.tar.zst artifacts/arch-package/*.src.tar.zst
artifacts/arch-package/.SRCINFO artifacts/arch-package/.SRCINFO
artifacts/linux-builds/* artifacts/linux-builds/**/*
artifacts/windows-builds/* artifacts/windows-builds/**/*
artifacts/macos-builds/**/*
generate_release_notes: true generate_release_notes: true
draft: true draft: true
prerelease: false prerelease: false
# Upload macOS ARM64 builds separately
release-macos-arm64:
needs: [build-macos-arm64, release]
runs-on: ubuntu-latest
if: |
startsWith(github.ref, 'refs/tags/v') ||
github.ref == 'refs/heads/main' ||
github.event_name == 'workflow_dispatch'
permissions:
contents: write
steps:
- name: Download macOS ARM64 artifacts
uses: actions/download-artifact@v4
with:
name: macos-arm64-builds
path: artifacts/macos-arm64-builds
- name: Display macOS ARM64 files
run: ls -R artifacts
- name: Upload macOS ARM64 to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
files: |
artifacts/macos-arm64-builds/*
draft: true
prerelease: false
# Upload macOS x64 builds separately
release-macos-x64:
needs: [build-macos-x64, release]
runs-on: ubuntu-latest
if: |
startsWith(github.ref, 'refs/tags/v') ||
github.ref == 'refs/heads/main' ||
github.event_name == 'workflow_dispatch'
permissions:
contents: write
steps:
- name: Download macOS x64 artifacts
uses: actions/download-artifact@v4
with:
name: macos-x64-builds
path: artifacts/macos-x64-builds
- name: Display macOS x64 files
run: ls -R artifacts
- name: Upload macOS x64 to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
files: |
artifacts/macos-x64-builds/*
draft: true
prerelease: false

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>

682
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "hytale-f2p-launcher", "name": "hytale-f2p-launcher",
"version": "2.1.2", "version": "2.2.0",
"description": "A modern, cross-platform launcher for Hytale with automatic updates and multi-client support", "description": "A modern, cross-platform launcher for Hytale with automatic updates and multi-client support",
"homepage": "https://github.com/amiayweb/Hytale-F2P", "homepage": "https://github.com/amiayweb/Hytale-F2P",
"main": "main.js", "main": "main.js",
@@ -25,8 +25,7 @@
"cross-platform", "cross-platform",
"electron", "electron",
"auto-update", "auto-update",
"mod-manager", "mod-manager"
"chat"
], ],
"maintainers": [ "maintainers": [
{ {
@@ -34,7 +33,7 @@
"url": "https://github.com/Terromur" "url": "https://github.com/Terromur"
}, },
{ {
"name": "Fari Gading", "name": "Fazri Gading",
"email": "fazrigading@gmail.com", "email": "fazrigading@gmail.com",
"url": "https://github.com/fazrigading" "url": "https://github.com/fazrigading"
} }
@@ -45,7 +44,6 @@
}, },
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@electron/notarize": "^2.5.0",
"electron": "^40.0.0", "electron": "^40.0.0",
"electron-builder": "^26.4.0" "electron-builder": "^26.4.0"
}, },
@@ -56,16 +54,13 @@
"dotenv": "^17.2.3", "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": "^7.5.7",
"uuid": "^9.0.1" "uuid": "^9.0.1"
}, },
"overrides": {
"tar": "$tar"
},
"build": { "build": {
"appId": "com.hytalef2p.launcher", "appId": "com.hytalef2p.launcher",
"productName": "Hytale F2P Launcher", "productName": "Hytale F2P Launcher",
"artifactName": "${name}_${version}_${arch}.${ext}", "artifactName": "${name}_${version}.${ext}",
"directories": { "directories": {
"output": "dist" "output": "dist"
}, },
@@ -78,40 +73,14 @@
".env" ".env"
], ],
"win": { "win": {
"target": [ "target": "nsis",
{
"target": "nsis",
"arch": [
"x64",
"arm64"
]
}
],
"icon": "build/icon.ico" "icon": "build/icon.ico"
}, },
"linux": { "linux": {
"target": [ "target": [
{ "AppImage",
"target": "AppImage", "deb",
"arch": [ "rpm"
"x64",
"arm64"
]
},
{
"target": "deb",
"arch": [
"x64",
"arm64"
]
},
{
"target": "rpm",
"arch": [
"x64",
"arm64"
]
}
], ],
"icon": "build/icon.png", "icon": "build/icon.png",
"category": "Game" "category": "Game"
@@ -121,30 +90,20 @@
{ {
"target": "dmg", "target": "dmg",
"arch": [ "arch": [
"arm64", "universal"
"x64"
] ]
}, },
{ {
"target": "zip", "target": "zip",
"arch": [ "arch": [
"arm64", "universal"
"x64"
] ]
} }
], ],
"icon": "build/icon.icns", "icon": "build/icon.icns",
"category": "public.app-category.games", "artifactName": "${name}_${version}_${arch}.${ext}",
"hardenedRuntime": true, "category": "public.app-category.games"
"gatekeeperAssess": false,
"entitlements": "build/entitlements.mac.plist",
"entitlementsInherit": "build/entitlements.mac.plist",
"forceCodeSigning": true,
"strictVerify": true,
"type": "distribution",
"notarize": false
}, },
"afterSign": "scripts/notarize.js",
"nsis": { "nsis": {
"oneClick": false, "oneClick": false,
"allowToChangeInstallationDirectory": true, "allowToChangeInstallationDirectory": true,

View File

@@ -1,92 +0,0 @@
console.log('[Notarize] Script loaded');
let notarize;
try {
notarize = require('@electron/notarize').notarize;
console.log('[Notarize] @electron/notarize loaded successfully');
} catch (err) {
console.error('[Notarize] Failed to load @electron/notarize:', err.message);
throw err;
}
const path = require('path');
// Timeout for notarization (30 minutes max)
const NOTARIZE_TIMEOUT_MS = 30 * 60 * 1000;
function withTimeout(promise, ms, message) {
return Promise.race([
promise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error(message)), ms)
)
]);
}
exports.default = async function notarizing(context) {
console.log('[Notarize] afterSign hook called');
console.log('[Notarize] Context:', JSON.stringify({
platform: context.electronPlatformName,
appOutDir: context.appOutDir,
outDir: context.outDir
}, null, 2));
const { electronPlatformName, appOutDir } = context;
// Only notarize macOS builds
if (electronPlatformName !== 'darwin') {
console.log('[Notarize] Skipping: not macOS');
return;
}
// Check if notarization is disabled via env var
if (process.env.SKIP_NOTARIZE === 'true') {
console.log('[Notarize] Skipping: SKIP_NOTARIZE=true');
return;
}
// Check credentials
const hasAppleId = !!process.env.APPLE_ID;
const hasPassword = !!process.env.APPLE_APP_SPECIFIC_PASSWORD;
const hasTeamId = !!process.env.APPLE_TEAM_ID;
console.log('[Notarize] Credentials check:', { hasAppleId, hasPassword, hasTeamId });
if (!hasAppleId || !hasPassword || !hasTeamId) {
console.log('[Notarize] Skipping: missing credentials');
return;
}
const appName = context.packager.appInfo.productFilename;
const appPath = path.join(appOutDir, `${appName}.app`);
console.log('[Notarize] Starting notarization...');
console.log('[Notarize] App path:', appPath);
console.log('[Notarize] Team ID:', process.env.APPLE_TEAM_ID);
console.log('[Notarize] Timeout:', NOTARIZE_TIMEOUT_MS / 1000, 'seconds');
try {
await withTimeout(
notarize({
appPath,
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_APP_SPECIFIC_PASSWORD,
teamId: process.env.APPLE_TEAM_ID,
}),
NOTARIZE_TIMEOUT_MS,
`Notarization timed out after ${NOTARIZE_TIMEOUT_MS / 1000} seconds`
);
console.log('[Notarize] Notarization complete!');
} catch (error) {
console.error('[Notarize] Notarization failed:', error.message);
// Don't fail the build if notarization times out or fails
// The app will still be code-signed, just not notarized
if (process.env.NOTARIZE_FAIL_ON_ERROR !== 'true') {
console.warn('[Notarize] Continuing build without notarization (set NOTARIZE_FAIL_ON_ERROR=true to fail)');
return;
}
throw error;
}
};