This commit is contained in:
2025-11-03 11:20:07 -07:00
parent 2d764448af
commit a3aa1915d4
14 changed files with 111 additions and 269 deletions

View File

@@ -71,9 +71,9 @@
"@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
"@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="], "@emnapi/core": ["@emnapi/core@1.7.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw=="],
"@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="], "@emnapi/runtime": ["@emnapi/runtime@1.7.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q=="],
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
@@ -927,9 +927,9 @@
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],

View File

@@ -1,7 +1,7 @@
{ {
"name": "lncvrt-games-launcher", "name": "lncvrt-games-launcher",
"private": true, "private": true,
"version": "1.1.1", "version": "1.1.2",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "lncvrt-games-launcher" name = "lncvrt-games-launcher"
version = "1.1.1" version = "1.1.2"
authors = ["Lncvrt"] authors = ["Lncvrt"]
edition = "2024" edition = "2024"
@@ -27,6 +27,7 @@ libc = "0.2.177"
tauri-plugin-dialog = "2.4.2" tauri-plugin-dialog = "2.4.2"
tauri-plugin-notification = "2.3.3" tauri-plugin-notification = "2.3.3"
sysinfo = "0.37.2" sysinfo = "0.37.2"
sha2 = "0.10.9"
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
shlex = "1.3.0" shlex = "1.3.0"

View File

@@ -1,4 +1,5 @@
use futures_util::stream::StreamExt; use futures_util::stream::StreamExt;
use sha2::{Digest, Sha512};
use std::{ use std::{
fs::{File, create_dir_all}, fs::{File, create_dir_all},
io::{BufReader, copy}, io::{BufReader, copy},
@@ -62,7 +63,13 @@ async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> String {
#[allow(unused_variables)] #[allow(unused_variables)]
#[tauri::command] #[tauri::command]
async fn download(app: AppHandle, url: String, name: String, executable: String) -> String { async fn download(
app: AppHandle,
url: String,
name: String,
executable: String,
hash: String,
) -> String {
let client = reqwest::Client::new(); let client = reqwest::Client::new();
let resp = match client.get(&url).send().await { let resp = match client.get(&url).send().await {
Ok(r) => r, Ok(r) => r,
@@ -90,7 +97,9 @@ async fn download(app: AppHandle, url: String, name: String, executable: String)
let _ = tokio::fs::remove_dir_all(&game_path.join(name.clone())).await; let _ = tokio::fs::remove_dir_all(&game_path.join(name.clone())).await;
} }
let _ = tokio::fs::create_dir_all(&game_path.join(&name)).await; let _ = tokio::fs::create_dir_all(&game_path.join(&name)).await;
let mut file = tokio::fs::File::create(download_part_path).await.unwrap(); let mut file = tokio::fs::File::create(download_part_path.clone())
.await
.unwrap();
while let Ok(Some(chunk_result)) = timeout(Duration::from_secs(5), stream.next()).await { while let Ok(Some(chunk_result)) = timeout(Duration::from_secs(5), stream.next()).await {
let chunk = match chunk_result { let chunk = match chunk_result {
@@ -120,10 +129,21 @@ async fn download(app: AppHandle, url: String, name: String, executable: String)
return "-1".to_string(); return "-1".to_string();
} }
tokio::fs::rename( app.emit("download-hash-checking", format!("{}", &name))
downloads_path.join(format!("{}.part", name)), .unwrap();
download_zip_path.clone(), let mut hasher = Sha512::new();
) hasher.update(&tokio::fs::read(download_part_path.clone()).await.unwrap());
let download_hash = format!("{:x}", hasher.finalize());
if hash != download_hash {
tokio::fs::remove_file(download_part_path.clone())
.await
.unwrap();
return "-1".to_string();
}
app.emit("download-finishing", format!("{}", &name))
.unwrap();
tokio::fs::rename(download_part_path.clone(), download_zip_path.clone())
.await .await
.unwrap(); .unwrap();
let unzip_res = unzip_to_dir(download_zip_path.clone(), game_path.join(&name)).await; let unzip_res = unzip_to_dir(download_zip_path.clone(), game_path.join(&name)).await;
@@ -167,7 +187,7 @@ async fn download(app: AppHandle, url: String, name: String, executable: String)
#[allow(unused_variables)] #[allow(unused_variables)]
#[tauri::command] #[tauri::command]
fn launch_game(app: AppHandle, name: String, executable: String, wine: bool, wine_command: String) { fn launch_game(app: AppHandle, name: String, executable: String) {
let game_folder = app let game_folder = app
.path() .path()
.app_local_data_dir() .app_local_data_dir()
@@ -183,27 +203,6 @@ fn launch_game(app: AppHandle, name: String, executable: String, wine: bool, win
.show(|_| {}); .show(|_| {});
return; return;
} }
let result = if wine && platform() == "linux" {
#[cfg(target_os = "linux")]
{
let wine_cmd_to_use =
wine_command.replace("%path%", &format!("\"{}\"", game_path.to_string_lossy()));
let parts = shlex::split(&wine_cmd_to_use).expect("failed to split command");
let exe = &parts[0];
let args = &parts[1..];
Command::new(exe)
.args(args)
.current_dir(&game_folder)
.spawn()
}
#[cfg(not(target_os = "linux"))]
{
Err(std::io::Error::new(std::io::ErrorKind::Other, "not linux"))
}
} else {
if is_running_by_path(&game_path) { if is_running_by_path(&game_path) {
app.dialog() app.dialog()
.message(format!("The version {} is already running.", name)) .message(format!("The version {} is already running.", name))
@@ -212,25 +211,18 @@ fn launch_game(app: AppHandle, name: String, executable: String, wine: bool, win
.show(|_| {}); .show(|_| {});
return; return;
} }
if platform() == "macos" { if platform() == "macos" {
Command::new("open") Command::new("open")
.arg(&game_path) .arg(&game_path)
.current_dir(&game_folder) .current_dir(&game_folder)
.spawn() .spawn()
.unwrap();
} else { } else {
Command::new(&game_path).current_dir(&game_folder).spawn() Command::new(&game_path)
} .current_dir(&game_folder)
}; .spawn()
.unwrap();
match result {
Ok(_) => println!("Game launched successfully."),
Err(e) => {
app.dialog()
.message(format!("Failed to load game:\n{}\n\nTry reinstalling the game or make a support request in the Community link on the sidebar.", e))
.kind(MessageDialogKind::Error)
.title("Failed to launch game")
.show(|_| {});
}
} }
} }

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Lncvrt Games Launcher", "productName": "Lncvrt Games Launcher",
"version": "1.1.1", "version": "1.1.2",
"identifier": "xyz.lncvrt.games-launcher", "identifier": "xyz.lncvrt.games-launcher",
"build": { "build": {
"beforeDevCommand": "next dev", "beforeDevCommand": "next dev",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Lncvrt Games Launcher", "productName": "Lncvrt Games Launcher",
"version": "1.1.1", "version": "1.1.2",
"identifier": "xyz.lncvrt.games-launcher", "identifier": "xyz.lncvrt.games-launcher",
"build": { "build": {
"beforeDevCommand": "next dev", "beforeDevCommand": "next dev",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Lncvrt Games Launcher", "productName": "Lncvrt Games Launcher",
"version": "1.1.1", "version": "1.1.2",
"identifier": "xyz.lncvrt.games-launcher", "identifier": "xyz.lncvrt.games-launcher",
"build": { "build": {
"beforeDevCommand": "next dev", "beforeDevCommand": "next dev",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Lncvrt Games Launcher", "productName": "Lncvrt Games Launcher",
"version": "1.1.1", "version": "1.1.2",
"identifier": "xyz.lncvrt.games-launcher", "identifier": "xyz.lncvrt.games-launcher",
"build": { "build": {
"beforeDevCommand": "next dev", "beforeDevCommand": "next dev",

View File

@@ -1,11 +1,9 @@
'use client' 'use client'
import { useEffect } from 'react' import { useEffect } from 'react'
import { platform } from '@tauri-apps/plugin-os'
import '../Installs.css' import '../Installs.css'
import { format } from 'date-fns' import { format } from 'date-fns'
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import { message } from '@tauri-apps/plugin-dialog'
import { useGlobal } from '../GlobalProvider' import { useGlobal } from '../GlobalProvider'
import { useSearchParams } from 'next/navigation' import { useSearchParams } from 'next/navigation'
@@ -100,43 +98,9 @@ export default function Installs () {
onClick={async () => { onClick={async () => {
const verInfo = getVersionInfo(entry) const verInfo = getVersionInfo(entry)
if (verInfo == undefined) return if (verInfo == undefined) return
let plat = platform()
let willUseWine = false
let cfg = null
while (normalConfig != null) {
cfg = normalConfig
break
}
if (plat === 'macos' || plat === 'linux') {
if (
!verInfo.platforms.includes(plat) &&
verInfo.platforms.includes('windows')
) {
if (
cfg != null &&
!cfg.settings.useWineOnUnixWhenNeeded
) {
await message(
'Wine support is disabled in settings and this version requires wine',
{
title: 'Wine is needed to load this version',
kind: 'error'
}
)
return
}
plat = 'windows'
willUseWine = true
}
}
invoke('launch_game', { invoke('launch_game', {
name: verInfo.id, name: verInfo.id,
executable: executable: verInfo.executable
verInfo.executables[
verInfo.platforms.indexOf(plat)
],
wine: willUseWine,
wineCommand: cfg?.settings.wineOnUnixCommand
}) })
}} }}
> >

View File

@@ -4,7 +4,6 @@ import { useCallback, useEffect, useState } from 'react'
import Sidebar from './componets/Sidebar' import Sidebar from './componets/Sidebar'
import './Globals.css' import './Globals.css'
import { DownloadProgress } from './types/DownloadProgress' import { DownloadProgress } from './types/DownloadProgress'
import { arch, platform } from '@tauri-apps/plugin-os'
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { import {
@@ -40,6 +39,7 @@ import { GameVersion } from './types/GameVersion'
import { Game } from './types/Game' import { Game } from './types/Game'
import { listen } from '@tauri-apps/api/event' import { listen } from '@tauri-apps/api/event'
import { usePathname } from 'next/navigation' import { usePathname } from 'next/navigation'
import { arch, platform } from '@tauri-apps/plugin-os'
const roboto = Roboto({ const roboto = Roboto({
subsets: ['latin'] subsets: ['latin']
@@ -114,6 +114,28 @@ export default function RootLayout ({
}) })
}).then(f => (unlistenProgress = f)) }).then(f => (unlistenProgress = f))
listen<string>('download-hash-checking', event => {
const versionName = event.payload
setDownloadProgress(prev => {
const i = prev.findIndex(d => d.version === versionName)
if (i === -1) return prev
const copy = [...prev]
copy[i] = { ...copy[i], hash_checking: true }
return copy
})
}).then(f => (unlistenProgress = f))
listen<string>('download-finishing', event => {
const versionName = event.payload
setDownloadProgress(prev => {
const i = prev.findIndex(d => d.version === versionName)
if (i === -1) return prev
const copy = [...prev]
copy[i] = { ...copy[i], hash_checking: false, finishing: true }
return copy
})
}).then(f => (unlistenProgress = f))
listen<string>('version-uninstalled', event => { listen<string>('version-uninstalled', event => {
const versionName = event.payload const versionName = event.payload
setDownloadedVersionsConfig(prev => { setDownloadedVersionsConfig(prev => {
@@ -162,7 +184,7 @@ export default function RootLayout ({
setLoadingText('Downloading version list...') setLoadingText('Downloading version list...')
try { try {
const res = await axios.get( const res = await axios.get(
'https://games.lncvrt.xyz/api/launcher/versions' `http://localhost:3342/launcher/versions?platform=${platform()}&arch=${arch()}`
) )
setServerVersionList(res.data) setServerVersionList(res.data)
} catch { } catch {
@@ -193,92 +215,18 @@ export default function RootLayout ({
function getSpecialVersionsList (game?: number): GameVersion[] { function getSpecialVersionsList (game?: number): GameVersion[] {
if (!normalConfig || !serverVersionList) return [] if (!normalConfig || !serverVersionList) return []
const useWine = normalConfig.settings.useWineOnUnixWhenNeeded
const p = platform()
const a = arch()
return serverVersionList.versions return serverVersionList.versions
.filter(v => !downloadedVersionsConfig?.list.includes(v.id)) .filter(v => !downloadedVersionsConfig?.list.includes(v.id))
.filter(v => { .filter(v => {
if (game && v.game != game) return false if (game && v.game != game) return false
if (p === 'macos' || p === 'linux') { return true
if (useWine) {
return (
v.platforms.includes('windows-x86') ||
v.platforms.includes('windows-x64') ||
v.platforms.includes(p)
)
}
return v.platforms.includes(p)
}
if (p === 'windows') {
if (a === 'x86_64')
return (
v.platforms.includes('windows-x86') ||
v.platforms.includes('windows-x64')
)
if (a === 'aarch64') return v.platforms.includes('windows-arm64')
}
return false
}) })
.sort((a, b) => { .sort((a, b) => {
if (b.game !== a.game) return a.game - b.game if (b.game !== a.game) return a.game - b.game
return b.place - a.place return 0
}) })
} }
function getDownloadLink (version: GameVersion): string | undefined {
const p = platform()
const a = arch()
const findUrl = (plat: string) => {
const i = version.platforms.indexOf(plat)
return i >= 0 ? version.downloadUrls[i] : undefined
}
if (p === 'windows') {
if (a === 'x86_64')
return findUrl('windows-x64') || findUrl('windows-x86')
if (a === 'aarch64') return findUrl('windows-arm64')
}
if (p === 'macos' || p === 'linux') {
if (normalConfig?.settings.useWineOnUnixWhenNeeded) {
return findUrl('windows-x86') || findUrl('windows-x64') || findUrl(p)
}
return findUrl(p)
}
return undefined
}
function getExecutableName (version: GameVersion): string | undefined {
const p = platform()
const a = arch()
const findUrl = (plat: string) => {
const i = version.platforms.indexOf(plat)
return i >= 0 ? version.executables[i] : undefined
}
if (p === 'windows') {
if (a === 'x86_64')
return findUrl('windows-x64') || findUrl('windows-x86')
if (a === 'aarch64') return findUrl('windows-arm64')
}
if (p === 'macos' || p === 'linux') {
if (normalConfig?.settings.useWineOnUnixWhenNeeded) {
return findUrl('windows-x86') || findUrl('windows-x64') || findUrl(p)
}
return findUrl(p)
}
return undefined
}
function getVersionInfo (id: string | undefined): GameVersion | undefined { function getVersionInfo (id: string | undefined): GameVersion | undefined {
if (!id) return undefined if (!id) return undefined
return serverVersionList?.versions.find(v => v.id === id) return serverVersionList?.versions.find(v => v.id === id)
@@ -310,7 +258,7 @@ export default function RootLayout ({
setSelectedVersionList([]) setSelectedVersionList([])
const newDownloads = list.map( const newDownloads = list.map(
version => new DownloadProgress(version, 0, false, true) version => new DownloadProgress(version, 0, false, true, false, false)
) )
setDownloadProgress(newDownloads) setDownloadProgress(newDownloads)
@@ -330,29 +278,16 @@ export default function RootLayout ({
) )
return return
} }
const downloadLink = getDownloadLink(info)
if (!downloadLink) {
setDownloadProgress(prev =>
prev.filter(d => d.version !== download.version)
)
return
}
const executableName = getExecutableName(info)
if (!executableName) {
setDownloadProgress(prev =>
prev.filter(d => d.version !== download.version)
)
return
}
setDownloadProgress(prev => setDownloadProgress(prev =>
prev.map(d => prev.map(d =>
d.version === download.version ? { ...d, queued: false } : d d.version === download.version ? { ...d, queued: false } : d
) )
) )
const res = await invoke<string>('download', { const res = await invoke<string>('download', {
url: downloadLink, url: info.downloadUrl,
name: info.id, name: info.id,
executable: executableName executable: info.executable,
hash: info.sha512sum
}) })
if (res == '1') { if (res == '1') {
setDownloadProgress(prev => setDownloadProgress(prev =>
@@ -394,38 +329,13 @@ export default function RootLayout ({
} | null { } | null {
if (!downloadedVersionsConfig || !serverVersionList) return null if (!downloadedVersionsConfig || !serverVersionList) return null
const p = platform()
const a = arch()
const installed = downloadedVersionsConfig.list.filter( const installed = downloadedVersionsConfig.list.filter(
v => getVersionGame(getVersionInfo(v)?.game)?.id === gameId v => getVersionGame(getVersionInfo(v)?.game)?.id === gameId
).length ).length
const total = serverVersionList.versions const total = serverVersionList.versions.filter(
.filter(v => { v => getVersionGame(v?.game)?.id === gameId
if (p === 'macos' || p === 'linux') { ).length
if (normalConfig?.settings.useWineOnUnixWhenNeeded) {
return (
v.platforms.includes('windows-x86') ||
v.platforms.includes('windows-x64') ||
v.platforms.includes(p)
)
}
return v.platforms.includes(p)
}
if (p === 'windows') {
if (a === 'x86_64')
return (
v.platforms.includes('windows-x86') ||
v.platforms.includes('windows-x64')
)
if (a === 'aarch64') return v.platforms.includes('windows-arm64')
}
return false
})
.filter(v => getVersionGame(v?.game)?.id === gameId).length
return { installed, total } return { installed, total }
} }
@@ -690,6 +600,18 @@ export default function RootLayout ({
<span className='text-yellow-500'> <span className='text-yellow-500'>
Queued Queued
</span> </span>
) : v.queued ? (
<span className='text-yellow-500'>
Queued
</span>
) : v.hash_checking ? (
<span className='text-blue-500'>
Checking hash...
</span>
) : v.finishing ? (
<span className='text-green-500'>
Finishing...
</span>
) : ( ) : (
<span> <span>
Downloading: {v.progress}% done Downloading: {v.progress}% done

View File

@@ -3,25 +3,18 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Setting } from '../componets/Setting' import { Setting } from '../componets/Setting'
import { writeNormalConfig } from '../util/BazookaManager' import { writeNormalConfig } from '../util/BazookaManager'
import { platform } from '@tauri-apps/plugin-os'
import { useGlobal } from '../GlobalProvider' import { useGlobal } from '../GlobalProvider'
export default function Settings () { export default function Settings () {
const [allowNotifications, setAllowNotifications] = useState(false) const [allowNotifications, setAllowNotifications] = useState(false)
const [alwaysShowGamesInSidebar, setAlwaysShowGamesInSidebar] = const [alwaysShowGamesInSidebar, setAlwaysShowGamesInSidebar] =
useState(false) useState(false)
const [useWineOnUnixWhenNeeded, setUseWineOnUnixWhenNeeded] = useState(false)
const [wineOnUnixCommand, setWineOnUnixCommand] = useState('wine %path%')
const [loaded, setLoaded] = useState(false) const [loaded, setLoaded] = useState(false)
const { normalConfig, setNormalConfig } = useGlobal() const { normalConfig, setNormalConfig } = useGlobal()
useEffect(() => { useEffect(() => {
;(async () => { ;(async () => {
while (normalConfig != null) { while (normalConfig != null) {
setUseWineOnUnixWhenNeeded(
normalConfig.settings.useWineOnUnixWhenNeeded
)
setWineOnUnixCommand(normalConfig.settings.wineOnUnixCommand)
setAllowNotifications(normalConfig.settings.allowNotifications) setAllowNotifications(normalConfig.settings.allowNotifications)
setAlwaysShowGamesInSidebar( setAlwaysShowGamesInSidebar(
normalConfig.settings.alwaysShowGamesInSidebar normalConfig.settings.alwaysShowGamesInSidebar
@@ -73,35 +66,6 @@ export default function Settings () {
} }
}} }}
/> />
<Setting
label='Use wine to launch Berry Dash when needed'
value={useWineOnUnixWhenNeeded}
onChange={async () => {
while (normalConfig != null) {
setUseWineOnUnixWhenNeeded(!useWineOnUnixWhenNeeded)
normalConfig.settings.useWineOnUnixWhenNeeded =
!useWineOnUnixWhenNeeded
await writeNormalConfig(normalConfig)
break
}
}}
className={platform() == 'linux' ? '' : 'hidden'}
/>
<input
type='text'
value={wineOnUnixCommand}
onChange={async e => {
while (normalConfig != null) {
setWineOnUnixCommand(e.target.value)
normalConfig.settings.wineOnUnixCommand = e.target.value
await writeNormalConfig(normalConfig)
break
}
}}
className={`input-field ${
platform() == 'linux' && useWineOnUnixWhenNeeded ? '' : 'hidden'
}`}
></input>
</div> </div>
)} )}
</> </>

View File

@@ -3,6 +3,8 @@ export class DownloadProgress {
public version: string, public version: string,
public progress: number, public progress: number,
public failed: boolean, public failed: boolean,
public queued: boolean public queued: boolean,
public hash_checking: boolean,
public finishing: boolean
) { } ) { }
} }

View File

@@ -2,9 +2,8 @@ export interface GameVersion {
id: string id: string
versionName: string versionName: string
releaseDate: number releaseDate: number
downloadUrls: string[]
platforms: string[]
executables: string[]
game: number game: number
place: number downloadUrl: string
executable: string
sha512sum: string
} }

View File

@@ -1,8 +1,6 @@
export class SettingsType { export class SettingsType {
constructor( constructor(
public allowNotifications: boolean = true, public allowNotifications: boolean = true,
public alwaysShowGamesInSidebar: boolean = true, public alwaysShowGamesInSidebar: boolean = true
public useWineOnUnixWhenNeeded: boolean = false,
public wineOnUnixCommand: string = 'wine %path%'
) { } ) { }
} }