mirror of
https://github.com/LCE-Hub/LCE-Emerald-Launcher.git
synced 2026-08-20 04:27:29 +00:00
revert
This commit is contained in:
parent
535735fcb2
commit
340f636b8e
195
.github/workflows/nightly.yml
vendored
195
.github/workflows/nightly.yml
vendored
|
|
@ -52,39 +52,12 @@ jobs:
|
|||
|
||||
- name: install frontend dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build and create DMG for macOS
|
||||
- name: build and fix macOS
|
||||
if: matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
pnpm build
|
||||
cd src-tauri
|
||||
cargo build --release --target ${{ matrix.args }}
|
||||
cd ..
|
||||
|
||||
TARGET_ARCH=${{ matrix.args == '--target aarch64-apple-darwin' && 'aarch64-apple-darwin' || 'x86_64-apple-darwin' }}
|
||||
|
||||
mkdir -p "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/MacOS"
|
||||
mkdir -p "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/Resources"
|
||||
|
||||
cp "src-tauri/target/$TARGET_ARCH/release/emerald-legacy-launcher" "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/MacOS/"
|
||||
|
||||
printf '<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>\n <key>CFBundleExecutable</key>\n <string>emerald-legacy-launcher</string>\n <key>CFBundleIdentifier</key>\n <string>com.emerald.legacy</string>\n <key>CFBundleName</key>\n <string>Emerald Legacy Launcher</string>\n <key>CFBundleVersion</key>\n <string>1.0.0</string>\n <key>CFBundleShortVersionString</key>\n <string>1.0.0</string>\n <key>CFBundlePackageType</key>\n <string>APPL</string>\n <key>NSHighResolutionCapable</key>\n <true/>\n <key>LSApplicationCategoryType</key>\n <string>public.app-category.games</string>\n</dict>\n</plist>\n' > "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/Info.plist"
|
||||
|
||||
if [ -f "src-tauri/icons/icon.icns" ]; then
|
||||
cp src-tauri/icons/icon.icns "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/Resources/"
|
||||
fi
|
||||
|
||||
chmod +x "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/MacOS/emerald-legacy-launcher"
|
||||
|
||||
cd "src-tauri/target/$TARGET_ARCH/release/bundle/macos"
|
||||
hdiutil create -volname "Emerald Legacy Launcher" -srcfolder "Emerald Legacy Launcher.app" -ov -format UDZO "Emerald Legacy Launcher.dmg"
|
||||
|
||||
mkdir -p "$GITHUB_WORKSPACE/src-tauri/target/release/bundle/dmg/"
|
||||
mv "Emerald Legacy Launcher.dmg" "$GITHUB_WORKSPACE/src-tauri/target/release/bundle/dmg/"
|
||||
|
||||
- name: Build with tauri-action for Windows and Linux
|
||||
if: matrix.platform != 'macos-latest'
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
pnpm tauri build ${{ matrix.args }}
|
||||
pnpm run post-build:macos
|
||||
- uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
|
@ -92,166 +65,48 @@ jobs:
|
|||
releaseName: 'Emerald Nightly'
|
||||
releaseBody: |
|
||||
# Emerald Legacy Launcher (Nightly)
|
||||
|
||||
## 📥 What to download?
|
||||
|
||||
### 🐧 GNU/Linux
|
||||
- **RHEL/Fedora**: `Emerald.Legacy.Launcher-*.rpm`
|
||||
- **Debian/Ubuntu**: `Emerald.Legacy.Launcher-*.deb`
|
||||
- **Universal**: `Emerald.Legacy.Launcher-*.AppImage`
|
||||
- **Flatpak**: `io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak`
|
||||
|
||||
### 🍎 macOS
|
||||
- **Intel Mac**: `Emerald.Legacy.Launcher_*.x64.dmg`
|
||||
- **M-series Mac**: `Emerald.Legacy.Launcher_*.aarch64.dmg`
|
||||
|
||||
### 🪟 Windows
|
||||
- **Setup Installer**: `Emerald.Legacy.Launcher-*.exe`
|
||||
- **MSI Installer**: `Emerald.Legacy.Launcher-*.msi`
|
||||
|
||||
# What to download?
|
||||
- `Emerald.Legacy.Launcher-*.rpm` for GNU/Linux (RHEL)
|
||||
- `Emerald.Legacy.Launcher-*.deb` for GNU/Linux (Debian+Ubuntu)
|
||||
- `Emerald.Legacy.Launcher-*.AppImage` for GNU/Linux (Universal)
|
||||
- `Emerald.Legacy.Launcher-*_x64.dmg` for macOS (Intel)
|
||||
- `Emerald.Legacy.Launcher-*_aarch64.dmg` for macOS (M-series)
|
||||
- `Emerald.Legacy.Launcher-*.exe` for Windows (Setup)
|
||||
- `Emerald.Legacy.Launcher-*.msi` for Windows (Setup)
|
||||
---
|
||||
|
||||
## ⚠️ Windows SmartScreen
|
||||
# Windows SmartScreen
|
||||
This software is completely safe. Because the launcher is unsigned, you will see a "Windows protected your PC" window. To proceed:
|
||||
|
||||
1. Click the **"More info"** link under the main text.
|
||||
2. Click the **"Run anyway"** button that appears.
|
||||
|
||||
## 🍎 macOS Installation
|
||||
Download the DMG file, open it, and drag the app to Applications folder.
|
||||
If you see "app damaged" error, right-click the app → Open → confirm Open.
|
||||
Or run: `xattr -cr "/Applications/Emerald Legacy Launcher.app"`
|
||||
---
|
||||
# macOS "Damaged" Error Fix
|
||||
The macOS builds now include automatic fixes for Gatekeeper quarantine issues. The app should launch without "application is damaged" errors.
|
||||
|
||||
releaseDraft: false
|
||||
prerelease: true
|
||||
args: ${{ matrix.args }}
|
||||
|
||||
- name: Upload all artifacts to release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
src-tauri/target/release/bundle/deb/*.deb
|
||||
src-tauri/target/release/bundle/appimage/*.AppImage
|
||||
src-tauri/target/release/bundle/rpm/*.rpm
|
||||
src-tauri/target/release/bundle/msi/*.msi
|
||||
src-tauri/target/release/bundle/nsis/*.exe
|
||||
tag_name: nightly
|
||||
name: 'Emerald Nightly'
|
||||
body: |
|
||||
# Emerald Legacy Launcher (Nightly)
|
||||
# What to download?
|
||||
- `Emerald.Legacy.Launcher-*.rpm` for GNU/Linux (RHEL)
|
||||
- `Emerald.Legacy.Launcher-*.deb` for GNU/Linux (Debian+Ubuntu)
|
||||
- `Emerald.Legacy.Launcher-*.AppImage` for GNU/Linux (Universal)
|
||||
- `Emerald Legacy Launcher*.dmg` for macOS (Intel + M-series)
|
||||
- `Emerald.Legacy.Launcher-*.exe` for Windows (Setup)
|
||||
- `Emerald.Legacy.Launcher-*.msi` for Windows (Setup)
|
||||
- `io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak` for GNU/Linux (Flatpak)
|
||||
---
|
||||
# Windows SmartScreen
|
||||
This software is completely safe. Because the launcher is unsigned, you will see a "Windows protected your PC" window. To proceed:
|
||||
|
||||
1. Click the **"More info"** link under the main text.
|
||||
2. Click the **"Run anyway"** button that appears.
|
||||
---
|
||||
# macOS Installation
|
||||
Download the DMG file, open it, and drag the app to Applications folder.
|
||||
If you see "app damaged" error, right-click the app → Open → confirm Open.
|
||||
Or run: `xattr -cr "/Applications/Emerald Legacy Launcher.app"`
|
||||
draft: false
|
||||
prerelease: true
|
||||
|
||||
- name: Upload macOS DMGs to release
|
||||
if: matrix.platform == 'macos-latest'
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: src-tauri/target/release/bundle/dmg/*.dmg
|
||||
tag_name: nightly
|
||||
name: 'Emerald Nightly'
|
||||
body: |
|
||||
# Emerald Legacy Launcher (Nightly)
|
||||
# What to download?
|
||||
- `Emerald.Legacy.Launcher-*.rpm` for GNU/Linux (RHEL)
|
||||
- `Emerald.Legacy.Launcher-*.deb` for GNU/Linux (Debian+Ubuntu)
|
||||
- `Emerald.Legacy.Launcher-*.AppImage` for GNU/Linux (Universal)
|
||||
- `Emerald Legacy Launcher*.dmg` for macOS (Intel + M-series)
|
||||
- `Emerald.Legacy.Launcher-*.exe` for Windows (Setup)
|
||||
- `Emerald.Legacy.Launcher-*.msi` for Windows (Setup)
|
||||
- `io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak` for GNU/Linux (Flatpak)
|
||||
---
|
||||
# Windows SmartScreen
|
||||
This software is completely safe. Because the launcher is unsigned, you will see a "Windows protected your PC" window. To proceed:
|
||||
|
||||
1. Click the **"More info"** link under the main text.
|
||||
2. Click the **"Run anyway"** button that appears.
|
||||
---
|
||||
# macOS Installation
|
||||
Download the DMG file, open it, and drag the app to Applications folder.
|
||||
If you see "app damaged" error, right-click the app → Open → confirm Open.
|
||||
Or run: `xattr -cr "/Applications/Emerald Legacy Launcher.app"`
|
||||
draft: false
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
nightly-flatpak:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
needs: nightly-tauri
|
||||
needs: nightly-tauri # Wait for Tauri release to be created
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:freedesktop-23.08
|
||||
options: --privileged
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y flatpak flatpak-builder
|
||||
|
||||
- name: setup flathub
|
||||
run: |
|
||||
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
sudo flatpak install -y flathub org.gnome.Sdk//48 org.gnome.Platform//48 org.freedesktop.Sdk.Extension.node20//24.08 org.freedesktop.Sdk.Extension.rust-stable//24.08
|
||||
sudo flatpak update
|
||||
|
||||
- name: setup flatpak
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
submodules: true
|
||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
bundle: io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak
|
||||
manifest-path: flatpak/io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.yml
|
||||
cache-key: flatpak-builder-${{ github.sha }}
|
||||
build-bundle: true
|
||||
repository-url: https://flathub.org/repo/flathub.flatpakrepo
|
||||
repository-name: flathub
|
||||
|
||||
- name: Upload flatpak to release
|
||||
uses: softprops/action-gh-release@v2
|
||||
- uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: "*.flatpak"
|
||||
files: io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak
|
||||
tag_name: nightly
|
||||
name: 'Emerald Nightly'
|
||||
body: |
|
||||
# Emerald Legacy Launcher (Nightly)
|
||||
# What to download?
|
||||
- `Emerald.Legacy.Launcher-*.rpm` for GNU/Linux (RHEL)
|
||||
- `Emerald.Legacy.Launcher-*.deb` for GNU/Linux (Debian+Ubuntu)
|
||||
- `Emerald.Legacy.Launcher-*.AppImage` for GNU/Linux (Universal)
|
||||
- `Emerald Legacy Launcher*.dmg` for macOS (Intel + M-series)
|
||||
- `Emerald.Legacy.Launcher-*.exe` for Windows (Setup)
|
||||
- `Emerald.Legacy.Launcher-*.msi` for Windows (Setup)
|
||||
- `io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak` for GNU/Linux (Flatpak)
|
||||
---
|
||||
# Windows SmartScreen
|
||||
This software is completely safe. Because the launcher is unsigned, you will see a "Windows protected your PC" window. To proceed:
|
||||
|
||||
1. Click the **"More info"** link under the main text.
|
||||
2. Click the **"Run anyway"** button that appears.
|
||||
---
|
||||
# macOS Installation
|
||||
Download the DMG file, open it, and drag the app to Applications folder.
|
||||
If you see "app damaged" error, right-click the app → Open → confirm Open.
|
||||
Or run: `xattr -cr "/Applications/Emerald Legacy Launcher.app"`
|
||||
draft: false
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
231
.github/workflows/publish.yml
vendored
231
.github/workflows/publish.yml
vendored
|
|
@ -15,28 +15,20 @@ jobs:
|
|||
args: '--target aarch64-apple-darwin'
|
||||
- platform: 'macos-latest'
|
||||
args: '--target x86_64-apple-darwin'
|
||||
- platform: 'ubuntu-22.04'
|
||||
args: ''
|
||||
- platform: 'windows-latest'
|
||||
args: ''
|
||||
# - platform: 'ubuntu-22.04'
|
||||
# args: ''
|
||||
# - platform: 'windows-latest'
|
||||
# args: ''
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Extract version
|
||||
id: get_version
|
||||
shell: bash
|
||||
run: |
|
||||
VERSION=$(node -p "require('./package.json').version")
|
||||
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "APP_VERSION=$VERSION" >> $GITHUB_ENV
|
||||
|
||||
- name: install dependencies (ubuntu only)
|
||||
if: matrix.platform == 'ubuntu-22.04'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libudev-dev
|
||||
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
|
@ -60,220 +52,61 @@ jobs:
|
|||
|
||||
- name: install frontend dependencies
|
||||
run: pnpm install
|
||||
- name: Build and create artifacts for macOS
|
||||
- name: Create PKG with post-install script
|
||||
if: matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
# Build the app once
|
||||
pnpm build
|
||||
cd src-tauri
|
||||
cargo build --release --target ${{ matrix.args }}
|
||||
cd ..
|
||||
|
||||
# Setup target architecture name
|
||||
TARGET_ARCH=${{ matrix.args == '--target aarch64-apple-darwin' && 'aarch64-apple-darwin' || 'x86_64-apple-darwin' }}
|
||||
|
||||
# Prepare paths for .app bundle
|
||||
mkdir -p "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/MacOS"
|
||||
mkdir -p "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/Resources"
|
||||
|
||||
cp "src-tauri/target/$TARGET_ARCH/release/emerald-legacy-launcher" "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/MacOS/"
|
||||
|
||||
printf '<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>\n <key>CFBundleExecutable</key>\n <string>emerald-legacy-launcher</string>\n <key>CFBundleIdentifier</key>\n <string>com.emerald.legacy</string>\n <key>CFBundleName</key>\n <string>Emerald Legacy Launcher</string>\n <key>CFBundleVersion</key>\n <string>${{ steps.get_version.outputs.VERSION }}</string>\n <key>CFBundleShortVersionString</key>\n <string>${{ steps.get_version.outputs.VERSION }}</string>\n <key>CFBundlePackageType</key>\n <string>APPL</string>\n <key>NSHighResolutionCapable</key>\n <true/>\n <key>LSApplicationCategoryType</key>\n <string>public.app-category.games</string>\n</dict>\n</plist>\n' > "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/Info.plist"
|
||||
|
||||
if [ -f "src-tauri/icons/icon.icns" ]; then
|
||||
cp src-tauri/icons/icon.icns "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/Resources/"
|
||||
fi
|
||||
|
||||
chmod +x "src-tauri/target/$TARGET_ARCH/release/bundle/macos/Emerald Legacy Launcher.app/Contents/MacOS/emerald-legacy-launcher"
|
||||
|
||||
# Create PKG (optional, using the built .app)
|
||||
# Create temporary directory for PKG creation
|
||||
mkdir -p pkg_temp/scripts
|
||||
cp scripts/postinstall.sh pkg_temp/scripts/
|
||||
|
||||
pkgbuild --root "src-tauri/target/$TARGET_ARCH/release/bundle/macos" \
|
||||
# Build the app first
|
||||
pnpm tauri build -- ${{ matrix.args }}
|
||||
|
||||
# Find the built app
|
||||
APP_PATH=$(find src-tauri/target/release/bundle/macos/ -name "*.app" | head -1)
|
||||
APP_NAME=$(basename "$APP_PATH")
|
||||
|
||||
# Create PKG with post-install script
|
||||
pkgbuild --root "$APP_PATH/.." \
|
||||
--install-location /Applications \
|
||||
--scripts pkg_temp/scripts \
|
||||
--identifier "com.emerald.legacy" \
|
||||
--version "${{ steps.get_version.outputs.VERSION }}" \
|
||||
--version "1.0.0" \
|
||||
--install-location "/Applications" \
|
||||
--root "$APP_PATH" \
|
||||
"Emerald-Legacy-Launcher.pkg"
|
||||
|
||||
# Create DMG
|
||||
cd "src-tauri/target/$TARGET_ARCH/release/bundle/macos"
|
||||
hdiutil create -volname "Emerald Legacy Launcher" -srcfolder "Emerald Legacy Launcher.app" -ov -format UDZO "Emerald Legacy Launcher.dmg"
|
||||
|
||||
# Move artifacts to final locations
|
||||
mkdir -p "$GITHUB_WORKSPACE/src-tauri/target/release/bundle/dmg/"
|
||||
mv "Emerald Legacy Launcher.dmg" "$GITHUB_WORKSPACE/src-tauri/target/release/bundle/dmg/"
|
||||
|
||||
mkdir -p "$GITHUB_WORKSPACE/src-tauri/target/release/bundle/macos/"
|
||||
mv "$GITHUB_WORKSPACE/Emerald-Legacy-Launcher.pkg" "$GITHUB_WORKSPACE/src-tauri/target/release/bundle/macos/"
|
||||
|
||||
- name: Build with tauri-action for Windows and Linux
|
||||
if: matrix.platform != 'macos-latest'
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
# Move PKG to bundle directory
|
||||
mkdir -p src-tauri/target/release/bundle/macos/
|
||||
mv "Emerald-Legacy-Launcher.pkg" src-tauri/target/release/bundle/macos/
|
||||
- uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tagName: v${{ steps.get_version.outputs.VERSION }}
|
||||
releaseName: 'Emerald v${{ steps.get_version.outputs.VERSION }}'
|
||||
releaseBody: |
|
||||
# Emerald Legacy Launcher v${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
## 📥 What to download?
|
||||
|
||||
### 🐧 GNU/Linux
|
||||
- **RHEL/Fedora**: `Emerald.Legacy.Launcher-*.rpm`
|
||||
- **Debian/Ubuntu**: `Emerald.Legacy.Launcher-*.deb`
|
||||
- **Universal**: `Emerald.Legacy.Launcher-*.AppImage`
|
||||
- **Flatpak**: `io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak`
|
||||
|
||||
### 🍎 macOS
|
||||
- **Intel Mac**: `Emerald.Legacy.Launcher_*.x64.dmg`
|
||||
- **M-series Mac**: `Emerald.Legacy.Launcher_*.aarch64.dmg`
|
||||
|
||||
### 🪟 Windows
|
||||
- **Setup Installer**: `Emerald.Legacy.Launcher-*.exe`
|
||||
- **MSI Installer**: `Emerald.Legacy.Launcher-*.msi`
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Windows SmartScreen
|
||||
This software is completely safe. Because the launcher is unsigned, you will see a "Windows protected your PC" window. To proceed:
|
||||
|
||||
1. Click the **"More info"** link under the main text.
|
||||
2. Click the **"Run anyway"** button that appears.
|
||||
|
||||
## 🍎 macOS Installation
|
||||
Download the DMG file, open it, and drag the app to Applications folder.
|
||||
If you see "app damaged" error, right-click the app → Open → confirm Open.
|
||||
Or run: `xattr -cr "/Applications/Emerald Legacy Launcher.app"`
|
||||
tagName: v__VERSION__
|
||||
releaseName: 'Emerald v__VERSION__'
|
||||
releaseBody: '*pls edit me*'
|
||||
releaseDraft: true
|
||||
prerelease: false
|
||||
args: ${{ matrix.args }}
|
||||
|
||||
- name: Upload all artifacts to release
|
||||
if: matrix.platform != 'macos-latest'
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
src-tauri/target/release/bundle/deb/*.deb
|
||||
src-tauri/target/release/bundle/appimage/*.AppImage
|
||||
src-tauri/target/release/bundle/rpm/*.rpm
|
||||
src-tauri/target/release/bundle/msi/*.msi
|
||||
src-tauri/target/release/bundle/nsis/*.exe
|
||||
tag_name: v${{ steps.get_version.outputs.VERSION }}
|
||||
name: 'Emerald v${{ steps.get_version.outputs.VERSION }}'
|
||||
body: |
|
||||
# Emerald Legacy Launcher v${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
## 📥 What to download?
|
||||
|
||||
### 🐧 GNU/Linux
|
||||
- **RHEL/Fedora**: `Emerald.Legacy.Launcher-*.rpm`
|
||||
- **Debian/Ubuntu**: `Emerald.Legacy.Launcher-*.deb`
|
||||
- **Universal**: `Emerald.Legacy.Launcher-*.AppImage`
|
||||
- **Flatpak**: `io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak`
|
||||
|
||||
### 🍎 macOS
|
||||
- **Intel Mac**: `Emerald.Legacy.Launcher_*.x64.dmg`
|
||||
- **M-series Mac**: `Emerald.Legacy.Launcher_*.aarch64.dmg`
|
||||
|
||||
### 🪟 Windows
|
||||
- **Setup Installer**: `Emerald.Legacy.Launcher-*.exe`
|
||||
- **MSI Installer**: `Emerald.Legacy.Launcher-*.msi`
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Windows SmartScreen
|
||||
This software is completely safe. Because the launcher is unsigned, you will see a "Windows protected your PC" window. To proceed:
|
||||
|
||||
1. Click the **"More info"** link under the main text.
|
||||
2. Click the **"Run anyway"** button that appears.
|
||||
|
||||
## 🍎 macOS Installation
|
||||
Download the DMG file, open it, and drag the app to Applications folder.
|
||||
If you see "app damaged" error, right-click the app → Open → confirm Open.
|
||||
Or run: `xattr -cr "/Applications/Emerald Legacy Launcher.app"`
|
||||
draft: true
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload macOS DMGs to release
|
||||
if: matrix.platform == 'macos-latest'
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
src-tauri/target/release/bundle/dmg/*.dmg
|
||||
src-tauri/target/release/bundle/macos/*.pkg
|
||||
tag_name: v${{ steps.get_version.outputs.VERSION }}
|
||||
name: 'Emerald v${{ steps.get_version.outputs.VERSION }}'
|
||||
body: |
|
||||
# Emerald Legacy Launcher v${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
## 📥 What to download?
|
||||
|
||||
### 🐧 GNU/Linux
|
||||
- **RHEL/Fedora**: `Emerald.Legacy.Launcher-*.rpm`
|
||||
- **Debian/Ubuntu**: `Emerald.Legacy.Launcher-*.deb`
|
||||
- **Universal**: `Emerald.Legacy.Launcher-*.AppImage`
|
||||
- **Flatpak**: `io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak`
|
||||
|
||||
### 🍎 macOS
|
||||
- **Intel Mac**: `Emerald.Legacy.Launcher_*.x64.dmg`
|
||||
- **M-series Mac**: `Emerald.Legacy.Launcher_*.aarch64.dmg`
|
||||
|
||||
### 🪟 Windows
|
||||
- **Setup Installer**: `Emerald.Legacy.Launcher-*.exe`
|
||||
- **MSI Installer**: `Emerald.Legacy.Launcher-*.msi`
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Windows SmartScreen
|
||||
This software is completely safe. Because the launcher is unsigned, you will see a "Windows protected your PC" window. To proceed:
|
||||
|
||||
1. Click the **"More info"** link under the main text.
|
||||
2. Click the **"Run anyway"** button that appears.
|
||||
|
||||
## 🍎 macOS Installation
|
||||
Download the DMG file, open it, and drag the app to Applications folder.
|
||||
If you see "app damaged" error, right-click the app → Open → confirm Open.
|
||||
Or run: `xattr -cr "/Applications/Emerald Legacy Launcher.app"`
|
||||
draft: true
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
publish-flatpak:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
needs: publish-tauri
|
||||
needs: publish-tauri # Wait for Tauri release to be created
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:freedesktop-23.08
|
||||
options: --privileged
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y flatpak flatpak-builder
|
||||
|
||||
- name: setup flathub
|
||||
run: |
|
||||
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
sudo flatpak install -y flathub org.gnome.Sdk//48 org.gnome.Platform//48 org.freedesktop.Sdk.Extension.node20//24.08 org.freedesktop.Sdk.Extension.rust-stable//24.08
|
||||
sudo flatpak update
|
||||
|
||||
- name: setup flatpak
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
submodules: true
|
||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
bundle: io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak
|
||||
manifest-path: flatpak/io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.yml
|
||||
cache-key: flatpak-builder-${{ github.sha }}
|
||||
build-bundle: true
|
||||
repository-url: https://flathub.org/repo/flathub.flatpakrepo
|
||||
repository-name: flathub
|
||||
- uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: io.github.Emerald_Legacy_Launcher.Emerald_Legacy_Launcher.flatpak
|
||||
|
|
|
|||
333
README.md
333
README.md
|
|
@ -1,13 +1,7 @@
|
|||
<div align="center">
|
||||
<img height="150" src="https://raw.githubusercontent.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/refs/heads/main/public/images/icon.png" alt="Emerald Legacy Launcher Logo">
|
||||
<img height="150" src="https://raw.githubusercontent.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/refs/heads/main/public/images/logo.png">
|
||||
<h1>Emerald Legacy Launcher</h1>
|
||||
<p><strong>FOSS cross-platform launcher for Minecraft Legacy Console Edition</strong></p>
|
||||
|
||||
<p>
|
||||
<img src="https://img.shields.io/badge/version-1.0.0-blue?style=flat-square" alt="Version">
|
||||
<img src="https://img.shields.io/badge/license-GPL--3.0-green?style=flat-square" alt="License">
|
||||
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey?style=flat-square" alt="Platforms">
|
||||
</p>
|
||||
<p>FOSS cross-platform launcher for Minecraft Legacy Console Edition</p>
|
||||
</div>
|
||||
|
||||
<p align="center">
|
||||
|
|
@ -27,300 +21,57 @@
|
|||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
<img width="1680" height="960" alt="Screenshot" src="https://github.com/user-attachments/assets/a5dd6aa1-2200-4f08-84e5-e75a8052ba79" />
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Features](#features)
|
||||
- [Screenshots](#screenshots)
|
||||
- [Installation](#installation)
|
||||
- [Windows](#windows)
|
||||
- [macOS](#macos)
|
||||
- [Linux](#linux)
|
||||
- [Game Versions & Partnerships](#game-versions--partnerships)
|
||||
- [Building from Source](#building-from-source)
|
||||
- [Development](#development)
|
||||
- [Project Structure](#project-structure)
|
||||
- [Tech Stack](#tech-stack)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Roadmap](#roadmap)
|
||||
- [Acknowledgments](#acknowledgments)
|
||||
- [License](#license)
|
||||
|
||||
|
||||
### PROJECT OVERVIEW
|
||||
Emerald Legacy Launcher started as a solo project to create a better way to play Legacy Console Edition. Over time, other developers joined the effort, bringing expertise from various preservation projects into one place.
|
||||
|
||||
**Our Philosophy:** For too long, the LCE scene has been fragmented across different, often resource-heavy launchers. Emerald was built to stop this fragmentation and centralize everything into a single, definitive hub. By avoiding bloated frameworks and utilizing a modern Rust/Tauri stack, we deliver a high-performance, cross-platform experience that uses only ~15MB of RAM, leaving all your PC's resources dedicated to the game itself.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
### CORE FEATURES
|
||||
|
||||
Emerald Legacy Launcher is a **high-performance, open-source launcher** for Minecraft Legacy Console Edition (LCE). Built to centralize the fragmented LCE scene, it provides a lightweight, unified hub for playing your favorite console versions of Minecraft on PC.
|
||||
|
||||
**Why Emerald?** Traditional launchers often rely on bloated frameworks, consuming excessive resources. Emerald utilizes a modern **Rust/Tauri** architecture, using only **~15MB of RAM** — leaving your PC's resources dedicated to the game itself.
|
||||
|
||||
The project started as a solo effort and has grown into a collaborative community project, bringing together expertise from various LCE preservation initiatives.
|
||||
<table width="100%" style="border-collapse: collapse;">
|
||||
<tr>
|
||||
<td style="padding: 20px; border: 1px solid #333;">
|
||||
<b>EASY SETUP</b><br>
|
||||
An automated installation process for TU19, Legacy Evolved and 360Revived, with more versions coming in future updates.
|
||||
</td>
|
||||
<td style="padding: 20px; border: 1px solid #333;">
|
||||
<b>RUST BACKEND</b><br>
|
||||
A memory-safe backend that handles all file operations and game execution with minimal overhead.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 20px; border: 1px solid #333;">
|
||||
<b>EASY CONFIGURATION</b><br>
|
||||
An integrated settings menu to change your username and manage game parameters directly through the launcher.
|
||||
</td>
|
||||
<td style="padding: 20px; border: 1px solid #333;">
|
||||
<b>TAURI FRONTEND</b><br>
|
||||
A lightweight frontend that handles the user interface and configuration management via webview.
|
||||
</td>*Proudly developed by a passionate team from the LCE community.*
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
### Core Features
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Automated Setup** | One-click installation for TU19, Legacy Evolved, Revelations, and 360Revived versions |
|
||||
| **Cross-Platform** | Native support for Windows, macOS (Intel & Apple Silicon), and Linux |
|
||||
| **Lightweight** | Very light RAM usage thanks to Rust backend and Tauri framework |
|
||||
| **Easy Configuration** | Built-in settings for username, game parameters, and profiles |
|
||||
|
||||
### Advanced Features
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **3D Skin Viewer** | Interactive skin preview using Three.js with layer support |
|
||||
| **Custom Skins** | Import and manage your own skins with local storage |
|
||||
| **Controller Support** | Full gamepad navigation support (keyboard fallback included) |
|
||||
| **Discord Rich Presence** | Show your current activity and game status on Discord |
|
||||
| **Workshop and modloader** | *(Coming Soon)* Community content and mod browser |
|
||||
### [DEVELOPMENT ROADMAP](https://github.com/orgs/Emerald-Legacy-Launcher/projects/2)
|
||||
Click the heading above to track progress, view active tasks, and see upcoming launcher features.
|
||||
|
||||
---
|
||||
|
||||
## Game Versions & Partnerships
|
||||
|
||||
Emerald Legacy Launcher integrates multiple community-driven builds of Minecraft Legacy Console Edition. Each build brings unique features and improvements to the classic LCE experience.
|
||||
|
||||
### Available Builds
|
||||
|
||||
| Build | Developer | Platform | Description |
|
||||
|-------|-----------|----------|-------------|
|
||||
| **[Revelations](https://github.com/itsRevela/MinecraftConsoles)** | [@itsRevela](https://github.com/itsRevela) | GitHub | Enhanced LCE with uncapped FPS, graphics fixes, hardcore hearts, and dedicated server security. Features LAN multiplayer, split-screen, and keyboard & mouse support. |
|
||||
| **[360 Revived](https://github.com/BluTac10/360Revived)** | [@BluTac10](https://github.com/BluTac10) | GitHub | PC port of Xbox 360 Edition TU19 with desktop optimizations. Features keyboard & mouse, fullscreen, LAN multiplayer, dedicated server, and split-screen support. |
|
||||
| **[Legacy Evolved](https://codeberg.org/piebot/LegacyEvolved)** | [@piebot](https://codeberg.org/piebot) | Codeberg | Backports newer title updates to LCE TU19 base. Currently porting TU25 (~98% complete) and TU31 (~76% complete). |
|
||||
| **[Title Update 19](https://github.com/smartcmd/MinecraftConsoles)** | [@smartcmd](https://github.com/smartcmd) | GitHub | Minecraft LCE v1.6.0560.0 with compilation fixes. Base version for modding with keyboard & mouse, fullscreen, LAN multiplayer, and dedicated server support. |
|
||||
|
||||
### Coming Soon: Legacy Minecraft Restoration Project (LMRP)
|
||||
|
||||
**LMRP** will be our **first major collaboration** to bring fully functional **online mini-games** back to Legacy Console Edition. This groundbreaking project aims to:
|
||||
|
||||
- Restore classic LCE mini-games (Battle, Tumble, Glide)
|
||||
- Preserve the authentic mini-game mechanics and maps
|
||||
|
||||
Stay tuned for updates on this exciting partnership! :)
|
||||
> ### ACKNOWLEDGMENTS
|
||||
> * <sub style="color: grey;">**The Emerald Team:** Technical development and maintenance.</sub>
|
||||
> * <sub style="color: grey;">**4J Studios & Mojang:** Original creators of Legacy Console Edition.</sub>
|
||||
> * <sub style="color: grey;">**smartcmd & The LCE Community:** Research and foundations for Legacy Console Edition on PC.</sub>
|
||||
> * <sub style="color: grey;">**LegacyEvolved:** Backporting TUs into smartcmd</sub>
|
||||
> * <sub style="color: grey;">**Tauri & Rust:** Core technologies.</sub>
|
||||
|
||||
---
|
||||
|
||||
## Screenshots
|
||||
|
||||
<img width="1680" alt="Emerald Legacy Launcher Screenshot" src="https://github.com/user-attachments/assets/a5dd6aa1-2200-4f08-84e5-e75a8052ba79" />
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### Windows
|
||||
|
||||
Download the latest release from [GitHub Releases](https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/releases):
|
||||
|
||||
| Format | Best For |
|
||||
|--------|----------|
|
||||
| `.exe` (NSIS) | Standard installation with uninstaller |
|
||||
| `.msi` | Enterprise/IT deployment |
|
||||
|
||||
**⚠️ Windows SmartScreen Warning:**
|
||||
> Since the launcher is unsigned, Windows may show a "Windows protected your PC" warning. To proceed:
|
||||
> 1. Click **"More info"**
|
||||
> 2. Click **"Run anyway"**
|
||||
|
||||
### macOS
|
||||
|
||||
| Format | Architecture |
|
||||
|--------|-------------|
|
||||
| `.dmg` (x64) | Intel Macs |
|
||||
| `.dmg` (aarch64) | Apple Silicon (M1/M2/M3) |
|
||||
|
||||
**Installation Steps:**
|
||||
1. Download the appropriate DMG for your Mac
|
||||
2. Open the DMG and drag the app to Applications
|
||||
3. If you see "app is damaged" error:
|
||||
- Right-click the app → **Open** → confirm **Open**
|
||||
- Or run: `xattr -cr "/Applications/Emerald Legacy Launcher.app"`
|
||||
|
||||
### Linux
|
||||
|
||||
Multiple distribution formats available:
|
||||
|
||||
| Format | Distribution |
|
||||
|--------|------------|
|
||||
| `.deb` | Debian, Ubuntu, Linux Mint |
|
||||
| `.rpm` | RHEL, Fedora, openSUSE |
|
||||
| `.AppImage` | Universal (no installation required) |
|
||||
| `Flatpak` | Universal with sandboxing |
|
||||
|
||||
**Flatpak Installation:**
|
||||
```bash
|
||||
flatpak install emerald.flatpak
|
||||
```
|
||||
|
||||
**Dependencies (if building from source):**
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt install libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libudev-dev
|
||||
|
||||
# Fedora
|
||||
sudo dnf install webkit2gtk4.1-devel libappindicator-gtk3-devel librsvg2-devel patchelf systemd-devel
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Building from Source
|
||||
|
||||
### Requirements
|
||||
|
||||
- **Node.js** (LTS recommended)
|
||||
- **Rust** (latest stable)
|
||||
- **PNPM** (recommended) or NPM
|
||||
- Platform-specific dependencies:
|
||||
- Linux: `WebKit2GTK-4.1`
|
||||
- macOS: WebKit (pre-installed)
|
||||
- Windows: Edge WebView2 Runtime (usually pre-installed)
|
||||
|
||||
### Build Steps
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher.git
|
||||
cd Emerald-Legacy-Launcher
|
||||
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
||||
# Development mode
|
||||
pnpm tauri dev
|
||||
|
||||
# Production build
|
||||
pnpm tauri build
|
||||
```
|
||||
|
||||
**Flatpak Build:**
|
||||
```bash
|
||||
pnpm flatpak
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
Emerald-Legacy-Launcher/
|
||||
├── src/ # React frontend
|
||||
│ ├── components/ # UI components
|
||||
│ ├── context/ # React context providers
|
||||
│ ├── hooks/ # Custom React hooks
|
||||
│ ├── pages/ # Page components
|
||||
│ ├── services/ # API/services layer
|
||||
│ └── css/ # Global styles
|
||||
├── src-tauri/ # Rust backend
|
||||
│ ├── src/ # Rust source code
|
||||
│ ├── Cargo.toml # Rust dependencies
|
||||
│ └── tauri.conf.json # Tauri configuration
|
||||
├── public/ # Static assets
|
||||
├── flatpak/ # Flatpak build config
|
||||
└── scripts/ # Build scripts
|
||||
```
|
||||
|
||||
### Tech Stack
|
||||
|
||||
| Layer | Technology | Version |
|
||||
|-------|-----------|---------|
|
||||
| **Backend** | Rust | 2021 Edition |
|
||||
| **Framework** | Tauri | v2 |
|
||||
| **Frontend** | React | ^19.1.0 |
|
||||
| **Language** | TypeScript | ~5.8.3 |
|
||||
| **Styling** | TailwindCSS | v4 |
|
||||
| **Animations** | Framer Motion | ^12.36.0 |
|
||||
| **3D Rendering** | Three.js | ^0.183.2 |
|
||||
| **Build Tool** | Vite | ^7.0.4 |
|
||||
|
||||
### Key Dependencies
|
||||
|
||||
**Rust Crates:**
|
||||
- `tauri` — Cross-platform app framework
|
||||
- `serde` — Serialization
|
||||
- `reqwest` — HTTP client
|
||||
- `tokio` — Async runtime
|
||||
- `rfd` — Native file dialogs
|
||||
|
||||
**Frontend Packages:**
|
||||
- `@tauri-apps/api` — Tauri JS API
|
||||
- `tauri-plugin-drpc` — Discord Rich Presence
|
||||
- `tauri-plugin-gamepad-api` — Controller support
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### macOS "App is Damaged" Error
|
||||
|
||||
```bash
|
||||
# Remove quarantine attributes
|
||||
xattr -cr /path/to/Emerald\ Legacy\ Launcher.app
|
||||
```
|
||||
|
||||
### Linux WebView Issues
|
||||
|
||||
Ensure WebKit2GTK-4.1 is installed:
|
||||
```bash
|
||||
# Check installation
|
||||
pkg-config --modversion webkit2gtk-4.1
|
||||
|
||||
# Reinstall if needed
|
||||
sudo apt install --reinstall libwebkit2gtk-4.1-0
|
||||
```
|
||||
|
||||
### Game Not Launching
|
||||
|
||||
1. Verify game files are properly installed via the launcher
|
||||
2. Check that Wine/Proton is installed (Linux only)
|
||||
3. Check that Wine/GPTK3 are installed (macOS only)
|
||||
4. Ensure your GPU drivers are up to date
|
||||
|
||||
### Controller Not Detected
|
||||
|
||||
- Connect controller before launching the launcher
|
||||
- Xbox and PlayStation controllers are best supported
|
||||
|
||||
---
|
||||
|
||||
## Roadmap
|
||||
|
||||
Track our progress and upcoming features on the [Development Roadmap](https://github.com/orgs/Emerald-Legacy-Launcher/projects/2).
|
||||
|
||||
**Planned Features:**
|
||||
- [ ] Workshop content browser
|
||||
- [ ] Additional TU versions support
|
||||
- [ ] Enhanced mod support
|
||||
- [ ] Cloud sync for settings/skins
|
||||
- [ ] Auto-updater integration
|
||||
|
||||
---
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
*Proudly developed by a passionate team from the LCE community.*
|
||||
|
||||
- **The Emerald Team** — Technical development and maintenance
|
||||
- **4J Studios & Mojang** — Original creators of Legacy Console Edition
|
||||
- **smartcmd & The LCE Community** — Research and foundations for LCE on PC
|
||||
- **Tauri & Rust Communities** — Core technologies and ecosystem
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the **[GNU GPL v3 License](LICENSE)**.
|
||||
|
||||
You are free to:
|
||||
- **Use** — Use the launcher for any purpose
|
||||
- **Study** — Access and study the source code
|
||||
- **Share** — Redistribute copies
|
||||
- **Improve** — Submit improvements and modifications
|
||||
|
||||
See `LICENSE` file for full terms.
|
||||
***This project is licensed under the [GNU GPL v3 License](LICENSE)***
|
||||
|
||||
|
|
|
|||
7350
changes.patch
Normal file
7350
changes.patch
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
Before Width: | Height: | Size: 269 KiB |
|
|
@ -1,98 +0,0 @@
|
|||
import { motion } from "framer-motion";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
export default function SpecialThanksModal({
|
||||
isOpen,
|
||||
onClose,
|
||||
playSfx,
|
||||
}: any) {
|
||||
const [focusIndex, setFocusIndex] = useState(0);
|
||||
|
||||
const contributors = [
|
||||
{ name: "smartcmd & LCE Community", desc: "Research & Foundations" },
|
||||
{ name: "Andi_pog & AFanFromWalmart", desc: "Project Testers" }
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) {
|
||||
setFocusIndex(0);
|
||||
return;
|
||||
}
|
||||
const handleKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") {
|
||||
playSfx("close_click.wav");
|
||||
onClose();
|
||||
} else if (e.key === "ArrowDown" || e.key === "Tab") {
|
||||
e.preventDefault();
|
||||
setFocusIndex((prev) => (prev + 1) % (contributors.length + 1));
|
||||
} else if (e.key === "ArrowUp") {
|
||||
e.preventDefault();
|
||||
setFocusIndex((prev) => (prev - 1 + (contributors.length + 1)) % (contributors.length + 1));
|
||||
} else if (e.key === "Enter") {
|
||||
if (focusIndex === contributors.length) {
|
||||
playSfx("close_click.wav");
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
};
|
||||
window.addEventListener("keydown", handleKey);
|
||||
return () => window.removeEventListener("keydown", handleKey);
|
||||
}, [isOpen, focusIndex]);
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="absolute inset-0 z-[110] flex items-center justify-center bg-black/80 backdrop-blur-sm outline-none border-none"
|
||||
>
|
||||
<div
|
||||
className="relative w-[400px] p-6 flex flex-col items-center shadow-2xl"
|
||||
style={{
|
||||
backgroundImage: "url('/images/frame_background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<h2 className="text-[#FFFF55] text-2xl mc-text-shadow mb-4 border-b-2 border-[#373737] pb-2 w-full text-center uppercase">
|
||||
Special Thanks
|
||||
</h2>
|
||||
<div className="flex flex-col gap-2 w-full items-center max-h-[320px] overflow-y-auto overflow-x-hidden scrollbar-hide py-2">
|
||||
{contributors.map((item, idx) => (
|
||||
<div
|
||||
key={item.name}
|
||||
onMouseEnter={() => setFocusIndex(idx)}
|
||||
className={`w-[90%] p-2 flex flex-col items-center justify-center mc-text-shadow transition-transform outline-none border-none bg-transparent ${focusIndex === idx ? "scale-105 text-[#FFFF55]" : "opacity-80 text-white"}`}
|
||||
>
|
||||
<span className="text-xl">
|
||||
{item.name}
|
||||
</span>
|
||||
<span className="text-[10px] text-[#A0A0A0] uppercase tracking-widest mt-1">
|
||||
{item.desc}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
onMouseEnter={() => setFocusIndex(contributors.length)}
|
||||
onClick={() => {
|
||||
playSfx("close_click.wav");
|
||||
onClose();
|
||||
}}
|
||||
className={`mt-6 w-56 h-12 flex items-center justify-center transition-colors text-2xl mc-text-shadow outline-none border-none ${focusIndex === contributors.length ? "text-[#FFFF55]" : "text-white"}`}
|
||||
style={{
|
||||
backgroundImage: focusIndex === contributors.length
|
||||
? "url('/images/button_highlighted.png')"
|
||||
: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import { motion } from "framer-motion";
|
|||
import { useUI, useConfig, useAudio, useGame } from "../../context/LauncherContext";
|
||||
|
||||
const HomeView = memo(function HomeView() {
|
||||
const { setActiveView, setShowCredits, setShowSpecialThanks, focusSection, onNavigateToSkin } = useUI();
|
||||
const { setActiveView, setShowCredits, focusSection, onNavigateToSkin } = useUI();
|
||||
const { profile, legacyMode } = useConfig();
|
||||
const { playClickSound, playSfx } = useAudio();
|
||||
const { handleLaunch, isGameRunning, editions, installs, toggleInstall, downloadProgress, downloadingId } = useGame();
|
||||
|
|
@ -155,17 +155,6 @@ const HomeView = memo(function HomeView() {
|
|||
>
|
||||
EMERALD TEAM
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (isFocusedSection) {
|
||||
playSfx("orb.ogg");
|
||||
setShowSpecialThanks(true);
|
||||
}
|
||||
}}
|
||||
className={`text-white/60 hover:text-[#FFFF55] text-xs mc-text-shadow tracking-[0.2em] transition-colors bg-transparent border-none outline-none ${!isFocusedSection ? "cursor-default pointer-events-none" : ""}`}
|
||||
>
|
||||
SPECIAL THANKS
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</motion.div>
|
||||
|
|
|
|||
|
|
@ -207,13 +207,13 @@ const SettingsView = memo(function SettingsView() {
|
|||
if (currentSubMenu === "main") {
|
||||
items.push({
|
||||
id: "audio_menu",
|
||||
label: "Audio",
|
||||
label: "Audio Settings",
|
||||
type: "button",
|
||||
onClick: () => { playClickSound(); setCurrentSubMenu("audio"); setFocusIndex(0); },
|
||||
});
|
||||
items.push({
|
||||
id: "video_menu",
|
||||
label: "User Interface",
|
||||
label: "Video Settings",
|
||||
type: "button",
|
||||
onClick: () => { playClickSound(); setCurrentSubMenu("video"); setFocusIndex(0); },
|
||||
});
|
||||
|
|
@ -225,23 +225,23 @@ const SettingsView = memo(function SettingsView() {
|
|||
});
|
||||
items.push({
|
||||
id: "launcher_menu",
|
||||
label: "Options",
|
||||
label: "Launcher Settings",
|
||||
type: "button",
|
||||
onClick: () => { playClickSound(); setCurrentSubMenu("launcher"); setFocusIndex(0); },
|
||||
});
|
||||
} else if (currentSubMenu === "audio") {
|
||||
items.push({
|
||||
id: "music",
|
||||
label: `Music: ${musicVolume ?? 50}%`,
|
||||
label: `Music: ${musicVolume}%`,
|
||||
type: "slider",
|
||||
value: musicVolume ?? 50,
|
||||
value: musicVolume,
|
||||
onChange: setMusicVolume,
|
||||
});
|
||||
items.push({
|
||||
id: "sfx",
|
||||
label: `SFX: ${sfxVolume ?? 100}%`,
|
||||
label: `SFX: ${sfxVolume}%`,
|
||||
type: "slider",
|
||||
value: sfxVolume ?? 100,
|
||||
value: sfxVolume,
|
||||
onChange: setSfxVolume,
|
||||
});
|
||||
items.push({
|
||||
|
|
@ -480,7 +480,7 @@ const SettingsView = memo(function SettingsView() {
|
|||
className="flex flex-col items-center w-full max-w-2xl outline-none"
|
||||
>
|
||||
<h2 className="text-2xl text-white mc-text-shadow mt-2 mb-4 border-b-2 border-[#373737] pb-2 w-[40%] max-w-[200px] text-center tracking-widest uppercase opacity-80 font-bold whitespace-nowrap px-4">
|
||||
{currentSubMenu === "main" ? "Settings" : currentSubMenu === "audio" ? "Audio" : currentSubMenu === "video" ? "User Interface" : currentSubMenu === "controls" ? "Controls" : "Options"}
|
||||
{currentSubMenu === "main" ? "Settings" : currentSubMenu === "audio" ? "Audio Settings" : currentSubMenu === "video" ? "Video Settings" : currentSubMenu === "controls" ? "Controls" : "Launcher"}
|
||||
</h2>
|
||||
|
||||
<div className="w-full max-w-[540px] space-y-2 mb-4 p-6 flex flex-col items-center overflow-y-auto max-h-[55vh]">
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const VersionsView = memo(function VersionsView() {
|
|||
const { setActiveView } = useUI();
|
||||
const { profile: selectedProfile, setProfile: setSelectedProfile } = useConfig();
|
||||
const { playClickSound, playBackSound, playSfx } = useAudio();
|
||||
const { editions, installs: installedVersions, toggleInstall, handleUninstall: onUninstall, deleteCustomEdition: onDeleteEdition, addCustomEdition: onAddEdition, updateCustomEdition: onUpdateEdition, downloadingId } = useGame();
|
||||
const { editions, installs: installedVersions, toggleInstall, handleUninstall: onUninstall, deleteCustomEdition: onDeleteEdition, addCustomEdition: onAddEdition, updateCustomEdition: onUpdateEdition, downloadingId, downloadProgress } = useGame();
|
||||
|
||||
const [focusRow, setFocusRow] = useState<number>(0);
|
||||
const [focusCol, setFocusCol] = useState<number>(0);
|
||||
|
|
@ -35,49 +35,34 @@ const VersionsView = memo(function VersionsView() {
|
|||
setFocusCol(0);
|
||||
} else if (e.key === "ArrowRight") {
|
||||
if (focusRow < editions.length) {
|
||||
const edition = editions[focusRow];
|
||||
const isInstalled = installedVersions.includes(edition.id);
|
||||
const isCustom = edition.id.startsWith("custom_");
|
||||
const hasCredits = !isCustom && edition.credits;
|
||||
|
||||
const id = editions[focusRow].id;
|
||||
const isInstalled = installedVersions.includes(id);
|
||||
const isCustom = id.startsWith("custom_");
|
||||
let maxCol = 1;
|
||||
if (isInstalled) maxCol = 3;
|
||||
if (isCustom) maxCol = isInstalled ? 5 : 3;
|
||||
if (hasCredits) maxCol = Math.max(maxCol, 0); // credits button is at col -1
|
||||
|
||||
setFocusCol((prev) => (prev < maxCol ? prev + 1 : prev));
|
||||
}
|
||||
} else if (e.key === "ArrowLeft") {
|
||||
if (focusRow < editions.length) {
|
||||
const edition = editions[focusRow];
|
||||
const isCustom = edition.id.startsWith("custom_");
|
||||
const hasCredits = !isCustom && edition.credits;
|
||||
|
||||
if (hasCredits && focusCol > -1) {
|
||||
setFocusCol(-1);
|
||||
} else if (focusCol > 0) {
|
||||
setFocusCol((prev) => prev - 1);
|
||||
}
|
||||
} else {
|
||||
setFocusCol((prev) => (prev > 0 ? prev - 1 : prev));
|
||||
}
|
||||
setFocusCol((prev) => (prev > 0 ? prev - 1 : prev));
|
||||
} else if (e.key === "Enter") {
|
||||
if (focusRow < editions.length) {
|
||||
const edition = editions[focusRow];
|
||||
const isInstalled = installedVersions.includes(edition.id);
|
||||
const isCustom = edition.id.startsWith("custom_");
|
||||
|
||||
if (focusCol === -1) {
|
||||
// Credits button
|
||||
if (edition.credits) {
|
||||
if (focusCol === 0) {
|
||||
if (isInstalled) {
|
||||
playClickSound();
|
||||
window.open(edition.credits.url, '_blank');
|
||||
}
|
||||
} else if (focusCol === 1) {
|
||||
if (!downloadingId) {
|
||||
setSelectedProfile(edition.id);
|
||||
} else if (!downloadingId) {
|
||||
playClickSound();
|
||||
toggleInstall(edition.id);
|
||||
}
|
||||
} else if (focusCol === 1 && !downloadingId) {
|
||||
playClickSound();
|
||||
toggleInstall(edition.id);
|
||||
} else if (focusCol === 2) {
|
||||
if (isInstalled) {
|
||||
playClickSound();
|
||||
|
|
@ -116,10 +101,22 @@ const VersionsView = memo(function VersionsView() {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [editions, focusRow, focusCol, downloadingId, installedVersions, onUninstall, onDeleteEdition, ITEM_COUNT]);
|
||||
}, [
|
||||
focusRow,
|
||||
focusCol,
|
||||
editions,
|
||||
installedVersions,
|
||||
playClickSound,
|
||||
playBackSound,
|
||||
setSelectedProfile,
|
||||
setActiveView,
|
||||
toggleInstall,
|
||||
onUninstall,
|
||||
onDeleteEdition,
|
||||
ITEM_COUNT,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const el = containerRef.current?.querySelector(
|
||||
|
|
@ -142,381 +139,304 @@ const VersionsView = memo(function VersionsView() {
|
|||
</h2>
|
||||
|
||||
<div className="w-full max-w-[740px] h-[380px] overflow-y-auto mb-6 p-6 relative">
|
||||
<div
|
||||
className="w-full p-6"
|
||||
style={{
|
||||
backgroundImage: "url('/images/frame_background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
backgroundRepeat: "no-repeat",
|
||||
imageRendering: "pixelated",
|
||||
minHeight: "340px",
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col gap-3">
|
||||
{editions.map((edition: any, i: number) => {
|
||||
const isInstalled = installedVersions.includes(edition.id);
|
||||
const isSelected = selectedProfile === edition.id;
|
||||
const isRowFocused = focusRow === i;
|
||||
const isCustom = edition.id.startsWith("custom_");
|
||||
const isPlaceholder = edition.id === "lmrp_placeholder";
|
||||
<div className="flex flex-col gap-3">
|
||||
{editions.map((edition: any, i: number) => {
|
||||
const isInstalled = installedVersions.includes(edition.id);
|
||||
const isSelected = selectedProfile === edition.id;
|
||||
const isRowFocused = focusRow === i;
|
||||
const isCustom = edition.id.startsWith("custom_");
|
||||
|
||||
return (
|
||||
return (
|
||||
<div
|
||||
key={edition.id}
|
||||
className={`w-full flex items-center transition-all border-none outline-none overflow-hidden`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
isSelected || (isRowFocused && focusCol === 0)
|
||||
? "url('/images/button_highlighted.png')"
|
||||
: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
key={edition.id}
|
||||
className={`w-full p-4 flex items-center transition-all border-none outline-none overflow-hidden relative ${isPlaceholder ? 'bg-gray-800/50 border-2 border-gray-600 opacity-50' : isSelected ? 'bg-[#50C878]/20 border-2 border-[#50C878]' :
|
||||
isRowFocused ? 'bg-white/5 border-2 border-white/50' :
|
||||
'bg-black/30 border-2 border-transparent hover:bg-white/5'
|
||||
}`}
|
||||
data-row={i}
|
||||
data-col={0}
|
||||
tabIndex={0}
|
||||
onMouseEnter={() => {
|
||||
if (!isPlaceholder) {
|
||||
setFocusRow(i);
|
||||
setFocusCol(0);
|
||||
}
|
||||
setFocusRow(i);
|
||||
setFocusCol(0);
|
||||
}}
|
||||
onClick={() => {
|
||||
if (!isPlaceholder && isInstalled) {
|
||||
if (isInstalled) {
|
||||
playClickSound();
|
||||
setSelectedProfile(edition.id);
|
||||
} else {
|
||||
toggleInstall(edition.id);
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
backdropFilter: 'blur(4px)',
|
||||
cursor: isPlaceholder ? 'not-allowed' : isInstalled ? 'pointer' : 'default',
|
||||
imageRendering: 'pixelated',
|
||||
borderRadius: '0'
|
||||
}}
|
||||
className="flex-1 p-4 flex items-center cursor-pointer outline-none pl-6 text-left relative"
|
||||
>
|
||||
<div className="flex flex-col flex-1">
|
||||
<div className="flex items-center gap-3 mb-1">
|
||||
<div className="flex flex-col">
|
||||
<div className="flex items-center gap-3">
|
||||
<span
|
||||
className={`text-xl mc-text-shadow ${isSelected ? "text-[#50C878]" : "text-white"}`}
|
||||
style={{ imageRendering: 'pixelated' }}
|
||||
className={`text-2xl mc-text-shadow ${isSelected || (isRowFocused && focusCol === 0) ? "text-[#FFFF55]" : "text-white"}`}
|
||||
>
|
||||
{edition.name}
|
||||
</span>
|
||||
{isCustom && (
|
||||
<span
|
||||
className="text-[10px] bg-[#50C878] text-black px-1 font-bold uppercase mc-text-shadow-none"
|
||||
style={{ imageRendering: 'pixelated' }}
|
||||
>
|
||||
<span className="text-[10px] bg-[#FFFF55] text-black px-1 font-bold uppercase mc-text-shadow-none">
|
||||
Custom
|
||||
</span>
|
||||
)}
|
||||
{edition.id === "revelations_edition" && (
|
||||
<>
|
||||
<span
|
||||
className="text-[10px] bg-[#50C878] text-white px-1 font-bold uppercase mc-text-shadow-none"
|
||||
style={{ imageRendering: 'pixelated' }}
|
||||
>
|
||||
New
|
||||
</span>
|
||||
<span
|
||||
className="text-[10px] bg-[#FFD700] text-black px-1 font-bold uppercase mc-text-shadow-none"
|
||||
style={{ imageRendering: 'pixelated' }}
|
||||
>
|
||||
Recommended
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
{edition.id === "360revived" && (
|
||||
<span
|
||||
className="text-[10px] bg-[#50C878] text-white px-1 font-bold uppercase mc-text-shadow-none"
|
||||
style={{ imageRendering: 'pixelated' }}
|
||||
>
|
||||
New
|
||||
</span>
|
||||
)}
|
||||
{edition.id === "lmrp_placeholder" && (
|
||||
<span
|
||||
className="text-[10px] bg-gray-500 text-white px-1 font-bold uppercase mc-text-shadow-none"
|
||||
style={{ imageRendering: 'pixelated' }}
|
||||
>
|
||||
Coming Soon
|
||||
</span>
|
||||
)}
|
||||
{!isCustom && edition.credits && (
|
||||
<span
|
||||
className="text-xs text-[#B0B0B0] mc-text-shadow"
|
||||
style={{ imageRendering: 'pixelated' }}
|
||||
>
|
||||
by {edition.credits.developer}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className="text-sm text-[#E0E0E0] mc-text-shadow"
|
||||
style={{ imageRendering: 'pixelated' }}
|
||||
>
|
||||
<span className="text-base text-[#E0E0E0] mc-text-shadow truncate w-full">
|
||||
{edition.desc}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!isPlaceholder && (
|
||||
<div className="flex items-center gap-2">
|
||||
{!isCustom && edition.credits && (
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={-1}
|
||||
onMouseEnter={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusRow(i);
|
||||
setFocusCol(-1);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playClickSound();
|
||||
window.open(edition.credits.url, '_blank');
|
||||
}}
|
||||
className={`mc-sq-btn w-8 h-8 flex items-center justify-center outline-none border-none transition-all`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === -1
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
title={`Credits: ${edition.credits.developer} (${edition.credits.platform})`}
|
||||
>
|
||||
{edition.credits?.platform === "codeberg" ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
className="text-white drop-shadow-md"
|
||||
>
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z" />
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="text-white drop-shadow-md"
|
||||
>
|
||||
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!isInstalled ? (
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={1}
|
||||
onMouseEnter={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusRow(i);
|
||||
setFocusCol(1);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (!downloadingId) {
|
||||
playClickSound();
|
||||
toggleInstall(edition.id);
|
||||
}
|
||||
}}
|
||||
className={`mc-sq-btn w-8 h-8 flex items-center justify-center outline-none border-none transition-all ${downloadingId === edition.id ? "opacity-100" : downloadingId ? "opacity-50" : ""}`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === 1
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
{downloadingId === edition.id ? (
|
||||
<img
|
||||
src="/images/loading.gif"
|
||||
alt="Loading"
|
||||
className="w-6 h-6 object-contain pointer-events-none drop-shadow-md"
|
||||
style={{ imageRendering: "pixelated" }}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
src="/images/Download_Icon.png"
|
||||
alt="Download"
|
||||
className="w-6 h-6 object-contain pointer-events-none drop-shadow-md"
|
||||
style={{ imageRendering: "pixelated" }}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
<div className="flex items-center gap-3 p-3 pr-6">
|
||||
{!isInstalled ? (
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={1}
|
||||
onMouseEnter={() => {
|
||||
setFocusRow(i);
|
||||
setFocusCol(1);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (!downloadingId) {
|
||||
playClickSound();
|
||||
toggleInstall(edition.id);
|
||||
}
|
||||
}}
|
||||
className={`mc-sq-btn w-10 h-10 flex items-center justify-center outline-none border-none transition-all ${downloadingId === edition.id ? "opacity-100" : downloadingId ? "opacity-50" : ""}`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === 1
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
{downloadingId === edition.id ? (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<span className="text-[10px] text-white font-bold leading-none">
|
||||
{Math.floor(downloadProgress || 0)}%
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={2}
|
||||
onMouseEnter={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusRow(i);
|
||||
setFocusCol(2);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playClickSound();
|
||||
TauriService.openInstanceFolder(edition.id);
|
||||
}}
|
||||
className="mc-sq-btn w-8 h-8 flex items-center justify-center outline-none border-none transition-all"
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === 2
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src="/images/Folder_Icon.png"
|
||||
alt="Folder"
|
||||
className="w-6 h-6 object-contain pointer-events-none drop-shadow-md"
|
||||
style={{ imageRendering: "pixelated" }}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={3}
|
||||
onMouseEnter={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusRow(i);
|
||||
setFocusCol(3);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playBackSound();
|
||||
onUninstall(edition.id);
|
||||
}}
|
||||
className="mc-sq-btn w-8 h-8 flex items-center justify-center outline-none border-none transition-all"
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === 3
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="square"
|
||||
className="text-white drop-shadow-md"
|
||||
>
|
||||
<polyline points="3 6 5 6 21 6"></polyline>
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
|
||||
<line x1="10" y1="11" x2="10" y2="17"></line>
|
||||
<line x1="14" y1="11" x2="14" y2="17"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</>
|
||||
<img
|
||||
src="/images/Download_Icon.png"
|
||||
alt="Download"
|
||||
className="w-8 h-8 object-contain pointer-events-none drop-shadow-md"
|
||||
style={{ imageRendering: "pixelated" }}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
)}
|
||||
{isCustom && (
|
||||
<>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={isInstalled ? 4 : 2}
|
||||
onMouseEnter={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusRow(i);
|
||||
setFocusCol(isInstalled ? 4 : 2);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playClickSound();
|
||||
setEditingEdition(edition);
|
||||
setIsImportModalOpen(true);
|
||||
}}
|
||||
className="mc-sq-btn w-8 h-8 flex items-center justify-center outline-none border-none transition-all"
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === (isInstalled ? 4 : 2)
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="square"
|
||||
className="text-white drop-shadow-md"
|
||||
>
|
||||
<path d="M12 20h9"></path>
|
||||
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={isInstalled ? 5 : 3}
|
||||
onMouseEnter={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusRow(i);
|
||||
setFocusCol(isInstalled ? 5 : 3);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playBackSound();
|
||||
onDeleteEdition(edition.id);
|
||||
}}
|
||||
className="mc-sq-btn w-8 h-8 flex items-center justify-center outline-none border-none transition-all"
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === (isInstalled ? 5 : 3)
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
strokeLinecap="square"
|
||||
className="text-red-500 drop-shadow-md"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={1}
|
||||
onMouseEnter={() => {
|
||||
setFocusRow(i);
|
||||
setFocusCol(1);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (!downloadingId) {
|
||||
playClickSound();
|
||||
toggleInstall(edition.id);
|
||||
}
|
||||
}}
|
||||
className={`mc-sq-btn w-10 h-10 flex items-center justify-center outline-none border-none transition-all ${downloadingId === edition.id ? "opacity-100" : downloadingId ? "opacity-50" : ""}`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === 1
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
{downloadingId === edition.id ? (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<span className="text-[10px] text-white font-bold leading-none">
|
||||
{Math.floor(downloadProgress || 0)}%
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<img
|
||||
src="/images/Update_Icon.png"
|
||||
alt="Update"
|
||||
className="w-8 h-8 object-contain pointer-events-none drop-shadow-md"
|
||||
style={{ imageRendering: "pixelated" }}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={2}
|
||||
onMouseEnter={() => {
|
||||
setFocusRow(i);
|
||||
setFocusCol(2);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playClickSound();
|
||||
TauriService.openInstanceFolder(edition.id);
|
||||
}}
|
||||
className="mc-sq-btn w-10 h-10 flex items-center justify-center outline-none border-none transition-all"
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === 2
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src="/images/Folder_Icon.png"
|
||||
alt="Folder"
|
||||
className="w-8 h-8 object-contain pointer-events-none drop-shadow-md"
|
||||
style={{ imageRendering: "pixelated" }}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={3}
|
||||
onMouseEnter={() => {
|
||||
setFocusRow(i);
|
||||
setFocusCol(3);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playBackSound();
|
||||
onUninstall(edition.id);
|
||||
}}
|
||||
className="mc-sq-btn w-10 h-10 flex items-center justify-center outline-none border-none transition-all"
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === 3
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="square"
|
||||
className="text-white drop-shadow-md"
|
||||
>
|
||||
<polyline points="3 6 5 6 21 6"></polyline>
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
|
||||
<line x1="10" y1="11" x2="10" y2="17"></line>
|
||||
<line x1="14" y1="11" x2="14" y2="17"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
{isCustom && (
|
||||
<>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={isInstalled ? 4 : 2}
|
||||
onMouseEnter={() => {
|
||||
setFocusRow(i);
|
||||
setFocusCol(isInstalled ? 4 : 2);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playClickSound();
|
||||
setEditingEdition(edition);
|
||||
setIsImportModalOpen(true);
|
||||
}}
|
||||
className="mc-sq-btn w-10 h-10 flex items-center justify-center outline-none border-none transition-all"
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === (isInstalled ? 4 : 2)
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="square"
|
||||
className="text-white drop-shadow-md"
|
||||
>
|
||||
<path d="M12 20h9"></path>
|
||||
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
data-row={i}
|
||||
data-col={isInstalled ? 5 : 3}
|
||||
onMouseEnter={() => {
|
||||
setFocusRow(i);
|
||||
setFocusCol(isInstalled ? 5 : 3);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
playBackSound();
|
||||
onDeleteEdition(edition.id);
|
||||
}}
|
||||
className="mc-sq-btn w-10 h-10 flex items-center justify-center outline-none border-none transition-all"
|
||||
style={{
|
||||
backgroundImage:
|
||||
isRowFocused && focusCol === (isInstalled ? 5 : 3)
|
||||
? "url('/images/Button_Square_Highlighted.png')"
|
||||
: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
strokeLinecap="square"
|
||||
className="text-red-500 drop-shadow-md"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -532,7 +452,7 @@ const VersionsView = memo(function VersionsView() {
|
|||
playClickSound();
|
||||
setIsImportModalOpen(true);
|
||||
}}
|
||||
className={`w-72 h-14 flex items-center justify-center transition-colors text-2xl mc-text-shadow outline-none border-none ${focusRow === editions.length ? "text-[#50C878]" : "text-white"}`}
|
||||
className={`w-72 h-14 flex items-center justify-center transition-colors text-2xl mc-text-shadow outline-none border-none ${focusRow === editions.length ? "text-[#FFFF55]" : "text-white"}`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
focusRow === editions.length
|
||||
|
|
@ -556,7 +476,7 @@ const VersionsView = memo(function VersionsView() {
|
|||
playBackSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
className={`w-72 h-14 flex items-center justify-center transition-colors text-2xl mc-text-shadow outline-none border-none ${focusRow === editions.length + 1 ? "text-[#50C878]" : "text-white"}`}
|
||||
className={`w-72 h-14 flex items-center justify-center transition-colors text-2xl mc-text-shadow outline-none border-none ${focusRow === editions.length + 1 ? "text-[#FFFF55]" : "text-white"}`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
focusRow === editions.length + 1
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ interface UIContextType {
|
|||
isWindowVisible: boolean;
|
||||
showCredits: boolean;
|
||||
setShowCredits: (show: boolean) => void;
|
||||
showSpecialThanks: boolean;
|
||||
setShowSpecialThanks: (show: boolean) => void;
|
||||
focusSection: "menu" | "skin";
|
||||
setFocusSection: (section: "menu" | "skin") => void;
|
||||
onNavigateToSkin: () => void;
|
||||
|
|
@ -44,7 +42,6 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) {
|
|||
const [isUiHidden, setIsUiHidden] = useState(false);
|
||||
const [isWindowVisible, setIsWindowVisible] = useState(true);
|
||||
const [showCredits, setShowCredits] = useState(false);
|
||||
const [showSpecialThanks, setShowSpecialThanks] = useState(false);
|
||||
const [focusSection, setFocusSection] = useState<"menu" | "skin">("menu");
|
||||
|
||||
const { updateMessage, clearUpdateMessage } = useUpdateCheck();
|
||||
|
|
@ -71,19 +68,13 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) {
|
|||
configRaw.rpcEnabled, configRaw.musicVol, configRaw.sfxVol, configRaw.isDayTime,
|
||||
configRaw.profile, configRaw.linuxRunner, configRaw.perfBoost, configRaw.customEditions,
|
||||
configRaw.legacyMode, configRaw.keepLauncherOpen, configRaw.enableTrayIcon,
|
||||
configRaw.animationsEnabled, configRaw.saveConfig, configRaw.setUsername, configRaw.setTheme,
|
||||
configRaw.setLayout, configRaw.setVfxEnabled, configRaw.setAnimationsEnabled,
|
||||
configRaw.setRpcEnabled, configRaw.setMusicVol, configRaw.setSfxVol, configRaw.setIsDayTime,
|
||||
configRaw.setProfile, configRaw.setLinuxRunner, configRaw.setPerfBoost, configRaw.setCustomEditions,
|
||||
configRaw.isLoaded, configRaw.hasCompletedSetup, configRaw.setHasCompletedSetup
|
||||
configRaw.animationsEnabled
|
||||
]);
|
||||
|
||||
const game = useMemo(() => gameRaw, [
|
||||
gameRaw.installs, gameRaw.isGameRunning, gameRaw.downloadProgress,
|
||||
gameRaw.downloadingId, gameRaw.editions, gameRaw.isRunnerDownloading,
|
||||
gameRaw.runnerDownloadProgress, gameRaw.error, gameRaw.updateCustomEdition, configRaw.profile,
|
||||
gameRaw.handleLaunch, gameRaw.stopGame, gameRaw.toggleInstall, gameRaw.handleUninstall,
|
||||
gameRaw.addCustomEdition, gameRaw.deleteCustomEdition, gameRaw.downloadRunner, gameRaw.checkInstalls
|
||||
gameRaw.runnerDownloadProgress, gameRaw.error, gameRaw.updateCustomEdition, configRaw.profile
|
||||
]);
|
||||
|
||||
const audio = useMemo(() => audioRaw, [
|
||||
|
|
@ -174,10 +165,10 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) {
|
|||
activeView, setActiveView, showIntro, setShowIntro,
|
||||
logoAnimDone, setLogoAnimDone, isUiHidden, setIsUiHidden,
|
||||
isWindowVisible,
|
||||
showCredits, setShowCredits, showSpecialThanks, setShowSpecialThanks, focusSection, setFocusSection,
|
||||
showCredits, setShowCredits, focusSection, setFocusSection,
|
||||
onNavigateToSkin, onNavigateToMenu, connected,
|
||||
updateMessage, clearUpdateMessage
|
||||
}), [activeView, showIntro, logoAnimDone, isUiHidden, isWindowVisible, showCredits, showSpecialThanks, focusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, clearUpdateMessage]);
|
||||
}), [activeView, showIntro, logoAnimDone, isUiHidden, isWindowVisible, showCredits, focusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, clearUpdateMessage]);
|
||||
|
||||
return (
|
||||
<UIContext.Provider value={uiValue}>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
border: 4px solid transparent;
|
||||
border-image: url('/images/Button_Background.png') 4 stretch;
|
||||
image-rendering: pixelated;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
background: rgba(0,0,0,0.6);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
|
|
@ -102,13 +102,4 @@ body {
|
|||
.no-animations * {
|
||||
transition: none !important;
|
||||
animation: none !important;
|
||||
}
|
||||
|
||||
.scrollbar-hide::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scrollbar-hide {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
|
@ -37,8 +37,8 @@ export function useAppConfig() {
|
|||
if (config.vfxEnabled !== undefined) setVfxEnabled(config.vfxEnabled);
|
||||
if (config.animationsEnabled !== undefined) setAnimationsEnabled(config.animationsEnabled);
|
||||
if (config.rpcEnabled !== undefined) setRpcEnabled(config.rpcEnabled);
|
||||
if (config.musicVol !== undefined && config.musicVol !== null) setMusicVol(config.musicVol);
|
||||
if (config.sfxVol !== undefined && config.sfxVol !== null) setSfxVol(config.sfxVol);
|
||||
if (config.musicVol !== undefined) setMusicVol(config.musicVol);
|
||||
if (config.sfxVol !== undefined) setSfxVol(config.sfxVol);
|
||||
if (config.legacyMode !== undefined) setLegacyMode(config.legacyMode);
|
||||
setIsLoaded(true);
|
||||
});
|
||||
|
|
@ -83,9 +83,9 @@ export function useAppConfig() {
|
|||
setAnimationsEnabled,
|
||||
rpcEnabled,
|
||||
setRpcEnabled,
|
||||
musicVol: musicVol ?? 50,
|
||||
musicVol,
|
||||
setMusicVol,
|
||||
sfxVol: sfxVol ?? 100,
|
||||
sfxVol,
|
||||
setSfxVol,
|
||||
isDayTime,
|
||||
setIsDayTime,
|
||||
|
|
|
|||
|
|
@ -5,65 +5,26 @@ import { TauriService } from "../services/TauriService";
|
|||
const appWindow = getCurrentWindow();
|
||||
|
||||
const BASE_EDITIONS = [
|
||||
{
|
||||
id: "revelations_edition",
|
||||
name: "Revelations",
|
||||
desc: "Enhanced LCE with uncapped FPS, graphics fixes, hardcore hearts, and dedicated server security. Features LAN multiplayer, split-screen, and keyboard & mouse support.",
|
||||
url: "https://github.com/itsRevela/MinecraftConsoles/releases/download/Nightly/LCREWindows64.zip",
|
||||
titleImage: "/images/minecraft_title_revelations.png",
|
||||
credits: {
|
||||
developer: "itsRevela",
|
||||
platform: "github",
|
||||
url: "https://github.com/itsRevela"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "360revived",
|
||||
name: "360 Revived",
|
||||
desc: "PC port of Xbox 360 Edition TU19 with desktop optimizations. Features keyboard & mouse, fullscreen, LAN multiplayer, dedicated server, and split-screen support.",
|
||||
url: "https://github.com/BluTac10/360Revived/releases/download/nightly/LCEWindows64.zip",
|
||||
titleImage: "/images/minecraft_title_360revived.png",
|
||||
credits: {
|
||||
developer: "BluTac10",
|
||||
platform: "github",
|
||||
url: "https://github.com/BluTac10"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "legacy_evolved",
|
||||
name: "Legacy Evolved",
|
||||
desc: "Backports newer title updates to LCE TU19 base. Currently porting TU25 (98% complete) and TU31 (76% complete).",
|
||||
desc: "Backporting the newer title updates back to the LCE",
|
||||
url: "https://codeberg.org/piebot/LegacyEvolved/releases/download/nightly/LCEWindows64.zip",
|
||||
titleImage: "/images/minecraft_title_LegacyEvolved.png",
|
||||
credits: {
|
||||
developer: "piebot",
|
||||
platform: "codeberg",
|
||||
url: "https://codeberg.org/piebot"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "vanilla_tu19",
|
||||
name: "Title Update 19",
|
||||
desc: "Minecraft LCE v1.6.0560.0 with compilation fixes. Base version for modding with keyboard & mouse, fullscreen, LAN multiplayer, and dedicated server support.",
|
||||
desc: "Leaked 4J Studios build. (smartcmd)",
|
||||
url: "https://github.com/smartcmd/MinecraftConsoles/releases/download/nightly/LCEWindows64.zip",
|
||||
titleImage: "/images/minecraft_title_tu19.png",
|
||||
credits: {
|
||||
developer: "smartcmd",
|
||||
platform: "github",
|
||||
url: "https://github.com/smartcmd"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "lmrp_placeholder",
|
||||
name: "LMRP (Coming Soon)",
|
||||
desc: "Legacy Minecraft Restoration Project - Classic mini-games and nostalgic gameplay. Stay tuned for updates!",
|
||||
url: "",
|
||||
titleImage: "/images/minecraft_title_lmrp.png",
|
||||
credits: {
|
||||
developer: "LMRP Team",
|
||||
platform: "github",
|
||||
url: "https://github.com/LMRP-Project"
|
||||
}
|
||||
id: "360revived",
|
||||
name: "360 Revived",
|
||||
desc: "PC port of Xbox 360 Edition TU19",
|
||||
url: "https://github.com/BluTac10/360Revived/releases/download/nightly/LCEWindows64.zip",
|
||||
titleImage: "/images/minecraft_title_360revived.png",
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -175,7 +136,7 @@ export function useGameManager({ profile, setProfile, customEditions, setCustomE
|
|||
await appWindow.unminimize();
|
||||
await appWindow.setFocus();
|
||||
}
|
||||
}, [isGameRunning, profile, keepLauncherOpen]);
|
||||
}, [isGameRunning, profile]);
|
||||
|
||||
const stopGame = useCallback(async () => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import WorkshopView from "../components/views/WorkshopView";
|
|||
import SetupView from "../components/views/SetupView";
|
||||
import SkinViewer from "../components/common/SkinViewer";
|
||||
import TeamModal from "../components/modals/TeamModal";
|
||||
import SpecialThanksModal from "../components/modals/SpecialThanksModal";
|
||||
import PanoramaBackground from "../components/common/PanoramaBackground";
|
||||
import { ClickParticles } from "../components/common/ClickParticles";
|
||||
import { AppHeader } from "../components/layout/AppHeader";
|
||||
|
|
@ -25,7 +24,7 @@ export default function App() {
|
|||
const {
|
||||
showIntro, setShowIntro, logoAnimDone, setLogoAnimDone,
|
||||
activeView, setActiveView, isUiHidden, setIsUiHidden,
|
||||
showCredits, setShowCredits, showSpecialThanks, setShowSpecialThanks, focusSection,
|
||||
showCredits, setShowCredits, focusSection,
|
||||
onNavigateToMenu, updateMessage, clearUpdateMessage
|
||||
} = useUI();
|
||||
|
||||
|
|
@ -126,14 +125,6 @@ export default function App() {
|
|||
playSfx={audio.playSfx}
|
||||
/>
|
||||
)}
|
||||
{showSpecialThanks && (
|
||||
<SpecialThanksModal
|
||||
isOpen={showSpecialThanks}
|
||||
onClose={() => setShowSpecialThanks(false)}
|
||||
playClickSound={audio.playClickSound}
|
||||
playSfx={audio.playSfx}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<AnimatePresence>
|
||||
|
|
|
|||
Loading…
Reference in a new issue