Fix overrides not being downloaded
This commit is contained in:
parent
b5d6beada0
commit
e745c75cc8
6 changed files with 122 additions and 46 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use onelauncher_core::api::cluster::dao::ClusterId;
|
||||
use onelauncher_core::api::packages::modpack::data::ModpackArchive;
|
||||
|
|
@ -21,6 +22,12 @@ pub trait OneClientApi {
|
|||
#[taurpc(alias = "getVersions")]
|
||||
async fn get_versions() -> LauncherResult<OnlineClusterManifest>;
|
||||
|
||||
#[taurpc(alias = "extractBundleOverrides")]
|
||||
async fn extract_bundle_overrides(
|
||||
bundle_path: PathBuf,
|
||||
cluster_id: ClusterId,
|
||||
) -> LauncherResult<()>;
|
||||
|
||||
#[taurpc(alias = "checkForUpdate")]
|
||||
async fn check_for_update<R: Runtime>(
|
||||
app_handle: AppHandle<R>,
|
||||
|
|
@ -82,6 +89,30 @@ impl OneClientApi for OneClientApiImpl {
|
|||
get_data_storage_versions().await
|
||||
}
|
||||
|
||||
async fn extract_bundle_overrides(
|
||||
self,
|
||||
bundle_path: PathBuf,
|
||||
cluster_id: ClusterId,
|
||||
) -> LauncherResult<()> {
|
||||
let cluster = onelauncher_core::api::cluster::dao::get_cluster_by_id(cluster_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
onelauncher_core::error::LauncherError::from(anyhow::anyhow!(
|
||||
"cluster with id {} not found",
|
||||
cluster_id
|
||||
))
|
||||
})?;
|
||||
|
||||
onelauncher_core::api::packages::modpack::mrpack::copy_overrides_folder(
|
||||
&cluster,
|
||||
&bundle_path,
|
||||
&None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn check_for_update<R: Runtime>(
|
||||
self,
|
||||
app_handle: AppHandle<R>,
|
||||
|
|
|
|||
|
|
@ -303,25 +303,12 @@ export type VersionType =
|
|||
*/
|
||||
"old_beta"
|
||||
|
||||
const ARGS_MAP = { 'events':'{"message":["event"],"process":["event"],"ingress":["event"]}', 'oneclient':'{"getBundlesFor":["cluster_id"],"checkForUpdate":[],"installUpdate":[],"getVersions":[],"getClustersGroupedByMajor":[]}', 'debug':'{"getLocale":[],"getType":[],"getArch":[],"getFamily":[],"getOsVersion":[],"getPackageVersion":[],"getPlatform":[],"getBuildTimestamp":[],"isInDev":[],"getGitCommitHash":[],"openDevTools":[]}', 'core':'{"getWorlds":["id"],"setClusterStage":["id","stage"],"getDefaultUser":["fallback"],"setDefaultUser":["uuid"],"getClusterById":["id"],"getLogByName":["id","name"],"removePackage":["cluster_id","package_hash"],"getRunningProcessesByClusterId":["cluster_id"],"getPackage":["provider","slug"],"downloadExternalPackage":["package","cluster_id","force","skip_compatibility"],"isClusterRunning":["cluster_id"],"getUser":["uuid"],"setDiscordRPCMessage":["message"],"getRunningProcesses":[],"killProcess":["pid"],"getLoadersForVersion":["mc_version"],"searchPackages":["provider","query"],"updateClusterById":["id","request"],"getClusters":[],"getGameVersions":[],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"launchCluster":["id","uuid","search_for_java"],"installModpack":["modpack","cluster_id"],"changeSkin":["access_token","skin_url","skin_variant"],"readSettings":[],"refreshAccount":["uuid"],"getMultiplePackages":["provider","slugs"],"openMsaLogin":[],"updateClusterProfile":["name","profile"],"open":["input"],"getUsers":[],"getScreenshots":["id"],"getProfileOrDefault":["name"],"removeUser":["uuid"],"getGlobalProfile":[],"createCluster":["options"],"getUsersFromAuthor":["provider","author"],"fetchMinecraftProfile":["uuid"],"removeCape":["access_token"],"convertUsernameUUID":["username_uuid"],"createSettingsProfile":["name"],"getLogs":["id"],"getPackageBody":["provider","body"],"refreshAccounts":[],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getLinkedPackages":["cluster_id"],"changeCape":["access_token","cape_uuid"],"writeSettings":["setting"],"uploadSkinBytes":["access_token","skin_data","image_format","skin_variant"],"fetchLoggedInProfile":["access_token"],"removeCluster":["id"]}', 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}' }
|
||||
export type Router = { 'debug': { openDevTools: () => Promise<void>,
|
||||
isInDev: () => Promise<boolean>,
|
||||
getArch: () => Promise<string>,
|
||||
getFamily: () => Promise<string>,
|
||||
getLocale: () => Promise<string | null>,
|
||||
getType: () => Promise<string>,
|
||||
getPlatform: () => Promise<string>,
|
||||
getOsVersion: () => Promise<string>,
|
||||
getGitCommitHash: () => Promise<string>,
|
||||
getBuildTimestamp: () => Promise<string>,
|
||||
getPackageVersion: () => Promise<string> },
|
||||
const ARGS_MAP = { 'core':'{"removeUser":["uuid"],"downloadExternalPackage":["package","cluster_id","force","skip_compatibility"],"changeCape":["access_token","cape_uuid"],"getScreenshots":["id"],"setClusterStage":["id","stage"],"getRunningProcesses":[],"convertUsernameUUID":["username_uuid"],"getClusterById":["id"],"getRunningProcessesByClusterId":["cluster_id"],"getLoadersForVersion":["mc_version"],"getPackageBody":["provider","body"],"open":["input"],"getMultiplePackages":["provider","slugs"],"isClusterRunning":["cluster_id"],"removeCape":["access_token"],"getGlobalProfile":[],"setDiscordRPCMessage":["message"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"fetchLoggedInProfile":["access_token"],"readSettings":[],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"killProcess":["pid"],"refreshAccounts":[],"uploadSkinBytes":["access_token","skin_data","image_format","skin_variant"],"getLogs":["id"],"updateClusterProfile":["name","profile"],"searchPackages":["provider","query"],"updateClusterById":["id","request"],"getWorlds":["id"],"getProfileOrDefault":["name"],"refreshAccount":["uuid"],"getUsers":[],"getLogByName":["id","name"],"removeCluster":["id"],"launchCluster":["id","uuid","search_for_java"],"openMsaLogin":[],"getPackage":["provider","slug"],"writeSettings":["setting"],"getClusters":[],"getUsersFromAuthor":["provider","author"],"getGameVersions":[],"getUser":["uuid"],"getLinkedPackages":["cluster_id"],"removePackage":["cluster_id","package_hash"],"createCluster":["options"],"getDefaultUser":["fallback"],"setDefaultUser":["uuid"],"installModpack":["modpack","cluster_id"],"fetchMinecraftProfile":["uuid"],"createSettingsProfile":["name"],"changeSkin":["access_token","skin_url","skin_variant"]}', 'events':'{"process":["event"],"ingress":["event"],"message":["event"]}', 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}', 'debug':'{"getLocale":[],"getPlatform":[],"isInDev":[],"getGitCommitHash":[],"getOsVersion":[],"getFamily":[],"getBuildTimestamp":[],"getPackageVersion":[],"openDevTools":[],"getType":[],"getArch":[]}', 'oneclient':'{"getVersions":[],"installUpdate":[],"getClustersGroupedByMajor":[],"extractBundleOverrides":["bundle_path","cluster_id"],"checkForUpdate":[],"getBundlesFor":["cluster_id"]}' }
|
||||
export type Router = { 'events': { ingress: (event: IngressPayload) => Promise<void>,
|
||||
message: (event: MessagePayload) => Promise<void>,
|
||||
process: (event: ProcessPayload) => Promise<void> },
|
||||
'folders': { fromCluster: (folderName: string) => Promise<string>,
|
||||
openCluster: (folderName: string) => Promise<null> },
|
||||
'oneclient': { getClustersGroupedByMajor: () => Promise<Partial<{ [key in number]: ClusterModel[] }>>,
|
||||
getBundlesFor: (clusterId: number) => Promise<ModpackArchive[]>,
|
||||
getVersions: () => Promise<OnlineClusterManifest>,
|
||||
checkForUpdate: () => Promise<Update | null>,
|
||||
installUpdate: () => Promise<null> },
|
||||
'core': { getClusters: () => Promise<ClusterModel[]>,
|
||||
getClusterById: (id: number) => Promise<ClusterModel | null>,
|
||||
removeCluster: (id: number) => Promise<null>,
|
||||
|
|
@ -373,9 +360,23 @@ removeCape: (accessToken: string) => Promise<MojangFullPlayerProfile>,
|
|||
convertUsernameUUID: (usernameUuid: string) => Promise<MowojangProfile>,
|
||||
setDiscordRPCMessage: (message: string) => Promise<null>,
|
||||
open: (input: string) => Promise<null> },
|
||||
'events': { ingress: (event: IngressPayload) => Promise<void>,
|
||||
message: (event: MessagePayload) => Promise<void>,
|
||||
process: (event: ProcessPayload) => Promise<void> } };
|
||||
'oneclient': { getClustersGroupedByMajor: () => Promise<Partial<{ [key in number]: ClusterModel[] }>>,
|
||||
getBundlesFor: (clusterId: number) => Promise<ModpackArchive[]>,
|
||||
getVersions: () => Promise<OnlineClusterManifest>,
|
||||
extractBundleOverrides: (bundlePath: string, clusterId: number) => Promise<null>,
|
||||
checkForUpdate: () => Promise<Update | null>,
|
||||
installUpdate: () => Promise<null> },
|
||||
'debug': { openDevTools: () => Promise<void>,
|
||||
isInDev: () => Promise<boolean>,
|
||||
getArch: () => Promise<string>,
|
||||
getFamily: () => Promise<string>,
|
||||
getLocale: () => Promise<string | null>,
|
||||
getType: () => Promise<string>,
|
||||
getPlatform: () => Promise<string>,
|
||||
getOsVersion: () => Promise<string>,
|
||||
getGitCommitHash: () => Promise<string>,
|
||||
getBuildTimestamp: () => Promise<string>,
|
||||
getPackageVersion: () => Promise<string> } };
|
||||
|
||||
|
||||
export type { InferCommandOutput }
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import type { ExternalPackage, ManagedVersionDependency, ModpackFile, Provider } from '@/bindings.gen';
|
||||
import type { ExternalPackage, ManagedVersionDependency, ModpackArchive, ModpackFile, Provider } from '@/bindings.gen';
|
||||
import { getModMetaDataName, Overlay } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandMut } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { useNavigate } from '@tanstack/react-router';
|
||||
import { useEffect, useImperativeHandle, useState } from 'react';
|
||||
import { useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import { DialogTrigger } from 'react-aria-components';
|
||||
|
||||
export interface DownloadModsRef {
|
||||
|
|
@ -36,7 +36,7 @@ export function isManagedMod(mod: ModData): mod is ManagedModData {
|
|||
return mod.managed === true;
|
||||
}
|
||||
|
||||
export function DownloadMods({ modsPerCluster, ref }: { modsPerCluster: Record<string, Array<ModpackFile>>; ref: React.Ref<DownloadModsRef> }) {
|
||||
export function DownloadMods({ modsPerCluster, bundlesPerCluster, ref }: { modsPerCluster: Record<string, Array<ModpackFile>>; bundlesPerCluster?: Record<string, Array<ModpackArchive>>; ref: React.Ref<DownloadModsRef> }) {
|
||||
const navigate = useNavigate();
|
||||
const [isOpen, setOpen] = useState<boolean>(false);
|
||||
const [mods, setMods] = useState<ModDataArray>([]);
|
||||
|
|
@ -89,7 +89,7 @@ export function DownloadMods({ modsPerCluster, ref }: { modsPerCluster: Record<s
|
|||
<Button className="mb-4" isDisabled={mods.length === 0} onPress={() => setOpen(prev => !prev)}>Download Mods</Button>
|
||||
|
||||
<Overlay isDismissable={false} isOpen={isOpen}>
|
||||
<DownloadingMods mods={mods} nextPath={nextPath} setOpen={setOpen} />
|
||||
<DownloadingMods bundlesPerCluster={bundlesPerCluster} mods={mods} nextPath={nextPath} setOpen={setOpen} />
|
||||
</Overlay>
|
||||
</DialogTrigger>
|
||||
);
|
||||
|
|
@ -106,10 +106,12 @@ function downloadModsParallel(items: ModDataArray, limit: number, fn: (mod: ModD
|
|||
return Promise.all(workers);
|
||||
}
|
||||
|
||||
function DownloadingMods({ mods, setOpen, nextPath }: { mods: ModDataArray; setOpen: React.Dispatch<React.SetStateAction<boolean>>; nextPath: string }) {
|
||||
function DownloadingMods({ mods, setOpen, nextPath, bundlesPerCluster }: { mods: ModDataArray; setOpen: React.Dispatch<React.SetStateAction<boolean>>; nextPath: string; bundlesPerCluster?: Record<string, Array<ModpackArchive>> }) {
|
||||
const navigate = useNavigate();
|
||||
const [downloadedMods, setDownloadedMods] = useState(0);
|
||||
const [modName, setModName] = useState<string | null>(null);
|
||||
const [allDone, setAllDone] = useState(false);
|
||||
const hasStarted = useRef(false);
|
||||
const download = useCommandMut(async (mod: ModData) => {
|
||||
if (isManagedMod(mod)) {
|
||||
if (mod.dependencies.length > 0)
|
||||
|
|
@ -133,37 +135,72 @@ function DownloadingMods({ mods, setOpen, nextPath }: { mods: ModDataArray; setO
|
|||
let useParallelModDownloading = setting('parallel_mod_downloading');
|
||||
|
||||
useEffect(() => {
|
||||
if (hasStarted.current)
|
||||
return;
|
||||
hasStarted.current = true;
|
||||
|
||||
const downloadAll = async () => {
|
||||
if (useParallelModDownloading)
|
||||
await downloadModsParallel(mods, 10, async (mod) => {
|
||||
setModName(mod.name);
|
||||
try {
|
||||
await download.mutateAsync(mod);
|
||||
try {
|
||||
if (useParallelModDownloading)
|
||||
await downloadModsParallel(mods, 10, async (mod) => {
|
||||
setModName(mod.name);
|
||||
try {
|
||||
await download.mutateAsync(mod);
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(`Failed to download mod ${mod.name}:`, e);
|
||||
}
|
||||
finally {
|
||||
setDownloadedMods(prev => prev + 1);
|
||||
}
|
||||
}); else
|
||||
for (const mod of mods) {
|
||||
setModName(mod.name);
|
||||
try {
|
||||
await download.mutateAsync(mod);
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(`Failed to download mod ${mod.name}:`, e);
|
||||
}
|
||||
finally {
|
||||
setDownloadedMods(prev => prev + 1);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
setDownloadedMods(prev => prev + 1);
|
||||
}
|
||||
}); else
|
||||
for (const mod of mods) {
|
||||
setModName(mod.name);
|
||||
try {
|
||||
await download.mutateAsync(mod);
|
||||
}
|
||||
finally {
|
||||
setDownloadedMods(prev => prev + 1);
|
||||
|
||||
// Extract overrides from enabled bundles after all mods are downloaded
|
||||
if (bundlesPerCluster) {
|
||||
setModName('Extracting overrides...');
|
||||
for (const [clusterId, bundles] of Object.entries(bundlesPerCluster)) {
|
||||
for (const bundle of bundles) {
|
||||
if (bundle.manifest.enabled) {
|
||||
try {
|
||||
await bindings.oneclient.extractBundleOverrides(bundle.path, Number(clusterId));
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`Failed to extract overrides for bundle ${bundle.manifest.name}:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error('Error during mod download:', e);
|
||||
}
|
||||
finally {
|
||||
setAllDone(true);
|
||||
}
|
||||
};
|
||||
|
||||
downloadAll();
|
||||
}, [mods]);
|
||||
|
||||
useEffect(() => {
|
||||
if (downloadedMods >= mods.length) {
|
||||
if (allDone) {
|
||||
setOpen(false);
|
||||
navigate({ to: nextPath });
|
||||
}
|
||||
}, [downloadedMods, mods, navigate, nextPath, setOpen]);
|
||||
}, [allDone, navigate, nextPath, setOpen]);
|
||||
|
||||
return (
|
||||
<Overlay.Dialog isDismissable={false}>
|
||||
|
|
|
|||
|
|
@ -61,6 +61,13 @@ function RouteComponent() {
|
|||
}, {} as Record<string, Array<ModpackFile>>),
|
||||
);
|
||||
|
||||
const bundlesPerCluster = useMemo(() => {
|
||||
return clusters.reduce((acc, cluster, i) => {
|
||||
acc[cluster.id] = bundleQueries[i];
|
||||
return acc;
|
||||
}, {} as Record<string, Array<ModpackArchive>>);
|
||||
}, [clusters, bundleQueries]);
|
||||
|
||||
const downloadModsRef = useRef<DownloadModsRef>(null);
|
||||
|
||||
return (
|
||||
|
|
@ -82,7 +89,7 @@ function RouteComponent() {
|
|||
</div>
|
||||
|
||||
<div className="hidden">
|
||||
<DownloadMods modsPerCluster={modsPerCluster} ref={downloadModsRef} />
|
||||
<DownloadMods bundlesPerCluster={bundlesPerCluster} modsPerCluster={modsPerCluster} ref={downloadModsRef} />
|
||||
</div>
|
||||
</div>
|
||||
</OverlayScrollbarsComponent>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use crate::error::LauncherResult;
|
|||
use crate::store::ingress::SubIngress;
|
||||
|
||||
pub mod data;
|
||||
mod mrpack;
|
||||
pub mod mrpack;
|
||||
mod polymrpack;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ pub(super) async fn download_and_link_packages(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn copy_overrides_folder(
|
||||
pub async fn copy_overrides_folder(
|
||||
cluster: &clusters::Model,
|
||||
archive_path: &PathBuf,
|
||||
_ingress: &Option<SubIngress<'_>>,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue